1
0
Fork 0

Codechange: Remove global GetRegister(), instead return 100+ registers directly from GetXxxCallback().

pull/14224/head
frosch 2025-05-05 21:33:18 +02:00 committed by frosch
parent f59cf73b88
commit 6faa667644
28 changed files with 84 additions and 72 deletions

View File

@ -2804,11 +2804,12 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
bool callback_enabled = indspec->callback_mask.Test(monthly ? IndustryCallbackMask::MonthlyProdChange : IndustryCallbackMask::ProductionChange);
if (callback_enabled) {
uint16_t res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->location.tile);
std::array<int32_t, 1> regs100;
uint16_t res = GetIndustryCallback(monthly ? CBID_INDUSTRY_MONTHLYPROD_CHANGE : CBID_INDUSTRY_PRODUCTION_CHANGE, 0, Random(), i, i->type, i->location.tile, regs100);
if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
suppress_message = HasBit(res, 7);
/* Get the custom message if any */
if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grfid, GRFStringID(GB(GetRegister(0x100), 0, 16)));
if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grfid, GRFStringID(GB(regs100[0], 0, 16)));
res = GB(res, 0, 4);
switch (res) {
default: NOT_REACHED();
@ -2826,7 +2827,7 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
increment = res == 0x0D ? -1 : 1;
break;
case 0xF: // Set production to third byte of register 0x100
i->prod_level = Clamp(GB(GetRegister(0x100), 16, 8), PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
i->prod_level = Clamp(GB(regs100[0], 16, 8), PRODLEVEL_MINIMUM, PRODLEVEL_MAXIMUM);
recalculate_multipliers = true;
break;
}

View File

@ -264,10 +264,10 @@ SpriteID GetCustomAirportSprite(const AirportSpec *as, uint8_t layout)
return group->sprite;
}
uint16_t GetAirportCallback(CallbackID callback, uint32_t param1, uint32_t param2, Station *st, TileIndex tile)
uint16_t GetAirportCallback(CallbackID callback, uint32_t param1, uint32_t param2, Station *st, TileIndex tile, std::span<int32_t> regs100)
{
AirportResolverObject object(tile, st, AirportSpec::Get(st->airport.type), st->airport.layout, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**
@ -280,7 +280,7 @@ uint16_t GetAirportCallback(CallbackID callback, uint32_t param1, uint32_t param
StringID GetAirportTextCallback(const AirportSpec *as, uint8_t layout, uint16_t callback)
{
AirportResolverObject object(INVALID_TILE, nullptr, as, layout, (CallbackID)callback);
uint16_t cb_res = object.ResolveCallback();
uint16_t cb_res = object.ResolveCallback({});
if (cb_res == CALLBACK_FAILED || cb_res == 0x400) return STR_UNDEFINED;
if (cb_res > 0x400) {
ErrorUnknownCallbackResult(as->grf_prop.grfid, callback, cb_res);

View File

@ -235,10 +235,10 @@ uint32_t AirportTileResolverObject::GetDebugID() const
return this->tiles_scope.ats->grf_prop.local_id;
}
uint16_t GetAirportTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, const AirportTileSpec *ats, Station *st, TileIndex tile, [[maybe_unused]] int extra_data = 0)
static uint16_t GetAirportTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, const AirportTileSpec *ats, Station *st, TileIndex tile, std::span<int32_t> regs100 = {})
{
AirportTileResolverObject object(ats, tile, st, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
static void AirportDrawTileLayout(const TileInfo *ti, const DrawTileSpriteSpan &dts, Colours colour)
@ -282,8 +282,14 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, const AirportTileSpec *airts)
return true;
}
/* Simple wrapper for GetAirportTileCallback to keep the animation unified. */
static uint16_t GetSimpleAirportTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, const AirportTileSpec *ats, Station *st, TileIndex tile, int)
{
return GetAirportTileCallback(callback, param1, param2, ats, st, tile);
}
/** Helper class for animation control. */
struct AirportTileAnimationBase : public AnimationBase<AirportTileAnimationBase, AirportTileSpec, Station, int, GetAirportTileCallback, TileAnimationFrameAnimationHelper<Station> > {
struct AirportTileAnimationBase : public AnimationBase<AirportTileAnimationBase, AirportTileSpec, Station, int, GetSimpleAirportTileCallback, TileAnimationFrameAnimationHelper<Station>> {
static constexpr CallbackID cb_animation_speed = CBID_AIRPTILE_ANIMATION_SPEED;
static constexpr CallbackID cb_animation_next_frame = CBID_AIRPTILE_ANIMATION_NEXT_FRAME;

View File

@ -153,12 +153,13 @@ SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
* @param param2 Callback parameter 2.
* @param feature For which feature to run the callback.
* @param tile Tile index of canal.
* @param[out] regs100 Additional result values from registers 100+
* @return Callback result or #CALLBACK_FAILED if the callback failed.
*/
static uint16_t GetCanalCallback(CallbackID callback, uint32_t param1, uint32_t param2, CanalFeature feature, TileIndex tile)
static uint16_t GetCanalCallback(CallbackID callback, uint32_t param1, uint32_t param2, CanalFeature feature, TileIndex tile, std::span<int32_t> regs100 = {})
{
CanalResolverObject object(feature, tile, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**

View File

@ -62,10 +62,10 @@ SpriteID GetCustomCargoSprite(const CargoSpec *cs)
}
uint16_t GetCargoCallback(CallbackID callback, uint32_t param1, uint32_t param2, const CargoSpec *cs)
uint16_t GetCargoCallback(CallbackID callback, uint32_t param1, uint32_t param2, const CargoSpec *cs, std::span<int32_t> regs100)
{
CargoResolverObject object(cs, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**

View File

@ -19,7 +19,7 @@ struct CargoSpec;
struct GRFFile;
SpriteID GetCustomCargoSprite(const CargoSpec *cs);
uint16_t GetCargoCallback(CallbackID callback, uint32_t param1, uint32_t param2, const CargoSpec *cs);
uint16_t GetCargoCallback(CallbackID callback, uint32_t param1, uint32_t param2, const CargoSpec *cs, std::span<int32_t> regs100 = {});
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit = false);
std::span<const CargoLabel> GetClimateDependentCargoTranslationTable();

View File

@ -1183,12 +1183,13 @@ bool UsesWagonOverride(const Vehicle *v)
* @param param2 Second parameter of the callback
* @param engine Engine type of the vehicle to evaluate the callback for
* @param v The vehicle to evaluate the callback for, or nullptr if it doesn't exist yet
* @param[out] regs100 Additional result values from registers 100+
* @return The value the callback returned, or CALLBACK_FAILED if it failed
*/
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v)
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, std::span<int32_t> regs100)
{
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_UNCACHED, false, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**
@ -1199,13 +1200,14 @@ uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param
* @param engine Engine type of the vehicle to evaluate the callback for
* @param v The vehicle to evaluate the callback for, or nullptr if it doesn't exist yet
* @param parent The vehicle to use for parent scope
* @param[out] regs100 Additional result values from registers 100+
* @return The value the callback returned, or CALLBACK_FAILED if it failed
*/
uint16_t GetVehicleCallbackParent(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, const Vehicle *parent)
uint16_t GetVehicleCallbackParent(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, const Vehicle *parent, std::span<int32_t> regs100)
{
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_NONE, false, callback, param1, param2);
object.parent_scope.SetVehicle(parent);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}

View File

@ -92,8 +92,8 @@ struct GRFFile;
void SetEngineGRF(EngineID engine, const struct GRFFile *file);
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v);
uint16_t GetVehicleCallbackParent(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, const Vehicle *parent);
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, std::span<int32_t> regs100 = {});
uint16_t GetVehicleCallbackParent(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v, const Vehicle *parent, std::span<int32_t> regs100 = {});
bool UsesWagonOverride(const Vehicle *v);
/* Handler to Evaluate callback 36. If the callback fails (i.e. most of the

View File

@ -161,9 +161,10 @@ GenericResolverObject::GenericResolverObject(bool ai_callback, CallbackID callba
* @param object pre-populated resolver object
* @param param1_grfv7 callback_param1 for GRFs up to version 7.
* @param param1_grfv8 callback_param1 for GRFs from version 8 on.
* @param[out] regs100 Additional result values from registers 100+
* @return answering GRFFile and callback value if successful, or CALLBACK_FAILED
*/
static std::pair<const GRFFile *, uint16_t> GetGenericCallbackResult(uint8_t feature, ResolverObject &object, uint32_t param1_grfv7, uint32_t param1_grfv8)
static std::pair<const GRFFile *, uint16_t> GetGenericCallbackResult(uint8_t feature, ResolverObject &object, uint32_t param1_grfv7, uint32_t param1_grfv8, std::span<int32_t> regs100 = {})
{
assert(feature < lengthof(_gcl));
@ -173,7 +174,7 @@ static std::pair<const GRFFile *, uint16_t> GetGenericCallbackResult(uint8_t fea
object.root_spritegroup = it.group;
/* Set callback param based on GRF version. */
object.callback_param1 = it.file->grf_version >= 8 ? param1_grfv8 : param1_grfv7;
uint16_t result = object.ResolveCallback();
uint16_t result = object.ResolveCallback(regs100);
if (result == CALLBACK_FAILED) continue;
return {it.file, result};

View File

@ -453,12 +453,12 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex start_ti
return UINT_MAX;
}
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile,
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, std::span<int32_t> regs100,
bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view)
{
HouseResolverObject object(house_id, tile, town, callback, param1, param2,
not_yet_constructed, initial_random_bits, watched_cargo_triggers, view);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
static void DrawTileLayout(const TileInfo *ti, const DrawTileSpriteSpan &dts, uint8_t stage, HouseID house_id)
@ -533,7 +533,7 @@ void DrawNewHouseTileInGUI(int x, int y, const HouseSpec *spec, HouseID house_id
PaletteID palette = GetColourPalette(spec->random_colour[0]);
if (spec->callback_mask.Test(HouseCallbackMask::Colour)) {
uint16_t callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, nullptr, INVALID_TILE, true, view);
uint16_t callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, nullptr, INVALID_TILE, {}, true, view);
if (callback != CALLBACK_FAILED) {
/* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
palette = HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
@ -554,9 +554,9 @@ void DrawNewHouseTileInGUI(int x, int y, const HouseSpec *spec, HouseID house_id
}
/* Simple wrapper for GetHouseCallback to keep the animation unified. */
uint16_t GetSimpleHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, const HouseSpec *spec, Town *town, TileIndex tile, CargoTypes extra_data)
static uint16_t GetSimpleHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, const HouseSpec *spec, Town *town, TileIndex tile, CargoTypes extra_data)
{
return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, {}, false, 0, extra_data);
}
/** Helper class for animation control. */

View File

@ -104,7 +104,7 @@ void AnimateNewHouseTile(TileIndex tile);
void TriggerHouseAnimation_ConstructionStageChanged(TileIndex tile, bool first_call);
void TriggerHouseAnimation_WatchedCargoAccepted(TileIndex tile, CargoTypes trigger_cargoes);
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile,
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, std::span<int32_t> regs100 = {},
bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0, int view = 0);
bool CanDeleteHouse(TileIndex tile);

View File

@ -524,12 +524,13 @@ uint32_t IndustriesResolverObject::GetDebugID() const
* @param industry The industry to do the callback for.
* @param type The type of industry to do the callback for.
* @param tile The tile associated with the callback.
* @param[out] regs100 Additional result values from registers 100+
* @return The callback result.
*/
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile)
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile, std::span<int32_t> regs100)
{
IndustriesResolverObject object(tile, industry, type, 0, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**
@ -559,7 +560,7 @@ CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, siz
ind.psa = nullptr;
IndustriesResolverObject object(tile, &ind, type, seed, CBID_INDUSTRY_LOCATION, 0, creation_type);
uint16_t result = object.ResolveCallback();
uint16_t result = object.ResolveCallback({});
/* Unlike the "normal" cases, not having a valid result means we allow
* the building of the industry, as that's how it's done in TTDP. */

View File

@ -86,7 +86,7 @@ enum IndustryAvailabilityCallType : uint8_t {
};
/* in newgrf_industry.cpp */
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile);
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile, std::span<int32_t> regs100 = {});
uint32_t GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i, uint32_t cur_grfid);
void IndustryProductionCallback(Industry *ind, int reason);
CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32_t seed, uint16_t initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type);

View File

@ -179,13 +179,13 @@ static void IndustryDrawTileLayout(const TileInfo *ti, const DrawTileSpriteSpan
DrawNewGRFTileSeq(ti, &dts, TO_INDUSTRIES, stage, GetColourPalette(rnd_colour));
}
uint16_t GetIndustryTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile)
uint16_t GetIndustryTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile, std::span<int32_t> regs100)
{
assert(industry != nullptr && IsValidTile(tile));
assert(industry->index == IndustryID::Invalid() || IsTileType(tile, MP_INDUSTRY));
IndustryTileResolverObject object(gfx_id, tile, industry, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds)

View File

@ -58,7 +58,7 @@ struct IndustryTileResolverObject : public SpecializedResolverObject<IndustryRan
};
bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds);
uint16_t GetIndustryTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile);
uint16_t GetIndustryTileCallback(CallbackID callback, uint32_t param1, uint32_t param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile, std::span<int32_t> regs100 = {});
CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, size_t layout_index, uint16_t initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type);
void AnimateNewIndustryTile(TileIndex tile);

View File

@ -429,12 +429,13 @@ uint32_t ObjectResolverObject::GetDebugID() const
* @param o The object to call the callback for.
* @param tile The tile the callback is called for.
* @param view The view of the object (only used when o == nullptr).
* @param[out] regs100 Additional result values from registers 100+
* @return The result of the callback.
*/
uint16_t GetObjectCallback(CallbackID callback, uint32_t param1, uint32_t param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8_t view)
uint16_t GetObjectCallback(CallbackID callback, uint32_t param1, uint32_t param2, const ObjectSpec *spec, Object *o, TileIndex tile, std::span<int32_t> regs100, uint8_t view)
{
ObjectResolverObject object(spec, o, tile, view, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**

View File

@ -165,7 +165,7 @@ private:
/** Class containing information relating to object classes. */
using ObjectClass = NewGRFClass<ObjectSpec, ObjectClassID, OBJECT_CLASS_MAX>;
uint16_t GetObjectCallback(CallbackID callback, uint32_t param1, uint32_t param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8_t view = 0);
uint16_t GetObjectCallback(CallbackID callback, uint32_t param1, uint32_t param2, const ObjectSpec *spec, Object *o, TileIndex tile, std::span<int32_t> regs100 = {}, uint8_t view = 0);
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec);
void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8_t view);

View File

@ -269,10 +269,10 @@ TownScopeResolver *RoadStopResolverObject::GetTown()
return &*this->town_scope;
}
uint16_t GetRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view)
uint16_t GetRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view, std::span<int32_t> regs100)
{
RoadStopResolverObject object(roadstopspec, st, tile, roadtype, type, view, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**
@ -344,11 +344,14 @@ void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec,
DrawCommonTileSeqInGUI(x, y, &dts, 0, 0, palette, true);
}
std::optional<SpriteLayoutProcessor> GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view)
std::optional<SpriteLayoutProcessor> GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view, std::span<int32_t> regs100)
{
RoadStopResolverObject object(spec, st, ti->tile, INVALID_ROADTYPE, type, view);
auto group = object.Resolve<TileLayoutSpriteGroup>();
if (group == nullptr) return std::nullopt;
for (uint i = 0; i < regs100.size(); ++i) {
regs100[i] = object.GetRegister(0x100 + i);
}
return group->ProcessRegisters(object, nullptr);
}

View File

@ -163,10 +163,10 @@ struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
using RoadStopClass = NewGRFClass<RoadStopSpec, RoadStopClassID, ROADSTOP_CLASS_MAX>;
std::optional<SpriteLayoutProcessor> GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view);
std::optional<SpriteLayoutProcessor> GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view, std::span<int32_t> regs100 = {});
void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, StationType type, int view);
uint16_t GetRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view);
uint16_t GetRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view, std::span<int32_t> regs100 = {});
void AnimateRoadStopTile(TileIndex tile);
uint8_t GetRoadStopTileAnimationSpeed(TileIndex tile);

View File

@ -21,18 +21,6 @@
#include "newgrf_storage.h"
#include "newgrf_commons.h"
/**
* Gets the value of a so-called newgrf "register".
* @param i index of the register
* @pre i < 0x110
* @return the value of the register
*/
inline int32_t GetRegister(uint i)
{
extern TemporaryStorageArray<int32_t, 0x110> _temp_store;
return _temp_store.GetValue(i);
}
/* List of different sprite group types */
enum SpriteGroupType : uint8_t {
SGT_REAL,
@ -396,13 +384,18 @@ public:
/**
* Resolve callback.
* @param[out] regs100 Additional result values from registers 100+
* @return Callback result.
*/
inline CallbackResult ResolveCallback()
inline CallbackResult ResolveCallback(std::span<int32_t> regs100)
{
auto result = this->DoResolve();
const auto *value = std::get_if<CallbackResult>(&result);
return value != nullptr ? *value : CALLBACK_FAILED;
if (value == nullptr) return CALLBACK_FAILED;
for (uint i = 0; i < regs100.size(); ++i) {
regs100[i] = this->GetRegister(0x100 + i);
}
return *value;
}
virtual const SpriteGroup *ResolveReal(const RealSpriteGroup &group) const;

View File

@ -662,10 +662,10 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS
}
uint16_t GetStationCallback(CallbackID callback, uint32_t param1, uint32_t param2, const StationSpec *statspec, BaseStation *st, TileIndex tile)
uint16_t GetStationCallback(CallbackID callback, uint32_t param1, uint32_t param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, std::span<int32_t> regs100)
{
StationResolverObject object(statspec, st, tile, callback, param1, param2);
return object.ResolveCallback();
return object.ResolveCallback(regs100);
}
/**
@ -688,7 +688,7 @@ CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_til
(numtracks << 24) | (plat_len << 16) | (axis == AXIS_Y ? TileX(diff) << 8 | TileY(diff) : TileY(diff) << 8 | TileX(diff)));
object.station_scope.axis = axis;
uint16_t cb_res = object.ResolveCallback();
uint16_t cb_res = object.ResolveCallback({});
/* Failed callback means success. */
if (cb_res == CALLBACK_FAILED) return CommandCost();

View File

@ -210,7 +210,7 @@ uint32_t GetPlatformInfo(Axis axis, uint8_t tile, int platforms, int length, int
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32_t var10 = 0);
void GetCustomStationRelocation(SpriteLayoutProcessor &processor, const StationSpec *statspec, BaseStation *st, TileIndex tile);
SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint layout, uint edge_info);
uint16_t GetStationCallback(CallbackID callback, uint32_t param1, uint32_t param2, const StationSpec *statspec, BaseStation *st, TileIndex tile);
uint16_t GetStationCallback(CallbackID callback, uint32_t param1, uint32_t param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, std::span<int32_t> regs100 = {});
CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, uint8_t plat_len, uint8_t numtracks);
/* Allocate a StationSpec to a Station. This is called once per build operation. */

View File

@ -278,7 +278,7 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type
uint16_t callback = CALLBACK_FAILED;
if (spec->callback_mask.Test(ObjectCallbackMask::SlopeCheck)) {
TileIndex diff = t - tile;
callback = GetObjectCallback(CBID_OBJECT_LAND_SLOPE_CHECK, GetTileSlope(t), TileY(diff) << 4 | TileX(diff), spec, nullptr, t, view);
callback = GetObjectCallback(CBID_OBJECT_LAND_SLOPE_CHECK, GetTileSlope(t), TileY(diff) << 4 | TileX(diff), spec, nullptr, t, {}, view);
}
if (callback == CALLBACK_FAILED) {

View File

@ -237,7 +237,7 @@ public:
/* Get the extra message for the GUI */
if (spec->callback_mask.Test(ObjectCallbackMask::FundMoreText)) {
uint16_t callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, nullptr, INVALID_TILE, _object_gui.sel_view);
uint16_t callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, nullptr, INVALID_TILE, {}, _object_gui.sel_view);
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
if (callback_res > 0x400) {
ErrorUnknownCallbackResult(spec->grf_prop.grfid, CBID_OBJECT_FUND_MORE_TEXT, callback_res);

View File

@ -3327,10 +3327,11 @@ draw_default_foundation:
if (stopspec != nullptr) {
stop_draw_mode = stopspec->draw_mode;
st = BaseStation::GetByTile(ti->tile);
auto result = GetRoadStopLayout(ti, stopspec, st, type, view);
std::array<int32_t, 1> regs100;
auto result = GetRoadStopLayout(ti, stopspec, st, type, view, regs100);
if (result.has_value()) {
if (stopspec->flags.Test(RoadStopSpecFlag::DrawModeRegister)) {
stop_draw_mode = static_cast<RoadStopDrawMode>(GetRegister(0x100));
stop_draw_mode = static_cast<RoadStopDrawMode>(regs100[0]);
}
if (type == StationType::RoadWaypoint && stop_draw_mode.Test(RoadStopDrawMode::WaypGround)) {
draw_ground = true;

View File

@ -803,7 +803,7 @@ void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs,
/* Check for custom accepted cargo types */
if (hs->callback_mask.Test(HouseCallbackMask::AcceptCargo)) {
uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, tile == INVALID_TILE);
uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
if (callback != CALLBACK_FAILED) {
/* Replace accepted cargo types with translated values from callback */
accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
@ -814,7 +814,7 @@ void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs,
/* Check for custom cargo acceptance */
if (hs->callback_mask.Test(HouseCallbackMask::CargoAcceptance)) {
uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, tile == INVALID_TILE);
uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
if (callback != CALLBACK_FAILED) {
AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
@ -2868,7 +2868,7 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile)
uint8_t random_bits = Random();
if (hs->callback_mask.Test(HouseCallbackMask::AllowConstruction)) {
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, true, random_bits);
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
}

View File

@ -1410,7 +1410,7 @@ void DrawHouseInGUI(int x, int y, HouseID house_id, int view)
*/
static StringID GetHouseName(const HouseSpec *hs)
{
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, 1, 0, hs->Index(), nullptr, INVALID_TILE, true);
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, 1, 0, hs->Index(), nullptr, INVALID_TILE, {}, true);
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
if (callback_res > 0x400) {
ErrorUnknownCallbackResult(hs->grf_prop.grffile->grfid, CBID_HOUSE_CUSTOM_NAME, callback_res);
@ -1602,7 +1602,7 @@ static CargoTypes GetProducedCargoOfHouse(const HouseSpec *hs)
CargoTypes produced{};
if (hs->callback_mask.Test(HouseCallbackMask::ProduceCargo)) {
for (uint i = 0; i < 256; i++) {
uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, hs->Index(), nullptr, INVALID_TILE, true);
uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, hs->Index(), nullptr, INVALID_TILE, {}, true);
if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;

View File

@ -2701,10 +2701,12 @@ static const int8_t _vehicle_smoke_pos[8] = {
*/
static void SpawnAdvancedVisualEffect(const Vehicle *v)
{
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v);
std::array<int32_t, 4> regs100;
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v, regs100);
if (callback == CALLBACK_FAILED) return;
uint count = GB(callback, 0, 2);
assert(count <= std::size(regs100));
bool auto_center = HasBit(callback, 13);
bool auto_rotate = !HasBit(callback, 14);
@ -2725,7 +2727,7 @@ static void SpawnAdvancedVisualEffect(const Vehicle *v)
int8_t y_center = _vehicle_smoke_pos[t_dir] * l_center;
for (uint i = 0; i < count; i++) {
int32_t reg = GetRegister(0x100 + i);
int32_t reg = regs100[i];
uint type = GB(reg, 0, 8);
int8_t x = GB(reg, 8, 8);
int8_t y = GB(reg, 16, 8);