1
0
Fork 0

Codechange: Remove direct access to temporary storage from TextRefStack.

pull/14224/head
frosch 2025-05-05 21:35:11 +02:00 committed by frosch
parent 6faa667644
commit eb9bbb2456
12 changed files with 46 additions and 40 deletions

View File

@ -796,7 +796,8 @@ static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_
*/
static std::optional<std::string> GetNewGRFAdditionalText(EngineID engine)
{
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, nullptr);
std::array<int32_t, 6> regs100;
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, nullptr, regs100);
if (callback == CALLBACK_FAILED || callback == 0x400) return std::nullopt;
const GRFFile *grffile = Engine::Get(engine)->GetGRF();
assert(grffile != nullptr);
@ -805,7 +806,7 @@ static std::optional<std::string> GetNewGRFAdditionalText(EngineID engine)
return std::nullopt;
}
return GetGRFStringWithTextStack(grffile, GRFSTR_MISC_GRF_TEXT + callback, 6);
return GetGRFStringWithTextStack(grffile, GRFSTR_MISC_GRF_TEXT + callback, regs100);
}
/**

View File

@ -101,13 +101,14 @@ static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind,
if (indspec->callback_mask.Test(IndustryCallbackMask::CargoSuffix)) {
TileIndex t = (cst != CST_FUND) ? ind->location.tile : INVALID_TILE;
uint16_t callback = GetIndustryCallback(CBID_INDUSTRY_CARGO_SUFFIX, 0, (cst << 8) | cargo, const_cast<Industry *>(ind), ind_type, t);
std::array<int32_t, 6> regs100;
uint16_t callback = GetIndustryCallback(CBID_INDUSTRY_CARGO_SUFFIX, 0, (cst << 8) | cargo, const_cast<Industry *>(ind), ind_type, t, regs100);
if (callback == CALLBACK_FAILED) return;
if (indspec->grf_prop.grffile->grf_version < 8) {
if (GB(callback, 0, 8) == 0xFF) return;
if (callback < 0x400) {
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback, 6);
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback, regs100);
suffix.display = CSD_CARGO_AMOUNT_TEXT;
return;
}
@ -121,12 +122,12 @@ static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind,
return;
}
if (callback < 0x400) {
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback, 6);
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback, regs100);
suffix.display = CSD_CARGO_AMOUNT_TEXT;
return;
}
if (callback >= 0x800 && callback < 0xC00) {
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback - 0x800, 6);
suffix.text = GetGRFStringWithTextStack(indspec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback - 0x800, regs100);
suffix.display = CSD_CARGO_TEXT;
return;
}
@ -590,12 +591,13 @@ public:
/* Get the additional purchase info text, if it has not already been queried. */
if (indsp->callback_mask.Test(IndustryCallbackMask::FundMoreText)) {
uint16_t callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, nullptr, this->selected_type, INVALID_TILE);
std::array<int32_t, 6> regs100;
uint16_t callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, nullptr, this->selected_type, INVALID_TILE, regs100);
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
if (callback_res > 0x400) {
ErrorUnknownCallbackResult(indsp->grf_prop.grfid, CBID_INDUSTRY_FUND_MORE_TEXT, callback_res);
} else {
std::string str = GetGRFStringWithTextStack(indsp->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, 6);
std::string str = GetGRFStringWithTextStack(indsp->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
if (!str.empty()) {
DrawStringMultiLine(ir, str, TC_YELLOW);
}
@ -972,12 +974,13 @@ public:
/* Get the extra message for the GUI */
if (ind->callback_mask.Test(IndustryCallbackMask::WindowMoreText)) {
uint16_t callback_res = GetIndustryCallback(CBID_INDUSTRY_WINDOW_MORE_TEXT, 0, 0, i, i->type, i->location.tile);
std::array<int32_t, 6> regs100;
uint16_t callback_res = GetIndustryCallback(CBID_INDUSTRY_WINDOW_MORE_TEXT, 0, 0, i, i->type, i->location.tile, regs100);
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
if (callback_res > 0x400) {
ErrorUnknownCallbackResult(ind->grf_prop.grfid, CBID_INDUSTRY_WINDOW_MORE_TEXT, callback_res);
} else {
std::string str = GetGRFStringWithTextStack(ind->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, 6);
std::string str = GetGRFStringWithTextStack(ind->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
if (!str.empty()) {
ir.top += WidgetDimensions::scaled.vsep_wide;
ir.top = DrawStringMultiLine(ir, str, TC_YELLOW);

View File

@ -463,11 +463,12 @@ uint32_t GetCompanyInfo(CompanyID owner, const Livery *l)
/**
* Get the error message from a shape/location/slope check callback result.
* @param cb_res Callback result to translate. If bit 10 is set this is a standard error message, otherwise a NewGRF provided string.
* @param textstack Text parameter stack.
* @param grffile NewGRF to use to resolve a custom error message.
* @param default_error Error message to use for the generic error.
* @return CommandCost indicating success or the error message.
*/
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, const GRFFile *grffile, StringID default_error)
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span<const int32_t> textstack, const GRFFile *grffile, StringID default_error)
{
CommandCost res;
@ -478,7 +479,7 @@ CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, const GRF
if (!IsLocalCompany()) return res;
StringID stringid = GetGRFStringID(grffile->grfid, GRFSTR_MISC_GRF_TEXT + cb_res);
auto params = GetGRFSringTextStackParameters(grffile, stringid, 4);
auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack);
res.SetEncodedMessage(GetEncodedStringWithArgs(stringid, params));
} else {
switch (cb_res) {

View File

@ -304,7 +304,7 @@ uint32_t GetTerrainType(TileIndex tile, TileContext context = TCX_NORMAL);
TileIndex GetNearbyTile(uint8_t parameter, TileIndex tile, bool signed_offsets = true, Axis axis = INVALID_AXIS);
uint32_t GetNearbyTileInformation(TileIndex tile, bool grf_version8);
uint32_t GetCompanyInfo(CompanyID owner, const struct Livery *l = nullptr);
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, const GRFFile *grffile, StringID default_error);
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span<const int32_t> textstack, const GRFFile *grffile, StringID default_error);
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res);
bool ConvertBooleanCallback(const struct GRFFile *grffile, uint16_t cbid, uint16_t cb_res);

View File

@ -560,13 +560,14 @@ 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({});
std::array<int32_t, 4> regs100;
uint16_t result = object.ResolveCallback(regs100);
/* 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. */
if (result == CALLBACK_FAILED) return CommandCost();
return GetErrorMessageFromLocationCallbackResult(result, indspec->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
return GetErrorMessageFromLocationCallbackResult(result, regs100, indspec->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
}
/**

View File

@ -239,7 +239,8 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind
ind.random = initial_random_bits;
ind.founder = founder;
uint16_t callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | (uint32_t)layout_index, gfx, &ind, ind_tile);
std::array<int32_t, 4> regs100;
uint16_t callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | static_cast<uint32_t>(layout_index), gfx, &ind, ind_tile, regs100);
if (callback_res == CALLBACK_FAILED) {
if (!IsSlopeRefused(GetTileSlope(ind_tile), its->slopes_refused)) return CommandCost();
return CommandCost(STR_ERROR_SITE_UNSUITABLE);
@ -249,7 +250,7 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind
return CommandCost(STR_ERROR_SITE_UNSUITABLE);
}
return GetErrorMessageFromLocationCallbackResult(callback_res, its->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
return GetErrorMessageFromLocationCallbackResult(callback_res, regs100, its->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
}
/* Simple wrapper for GetHouseCallback to keep the animation unified. */

View File

@ -688,14 +688,15 @@ 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({});
std::array<int32_t, 4> regs100;
uint16_t cb_res = object.ResolveCallback(regs100);
/* Failed callback means success. */
if (cb_res == CALLBACK_FAILED) return CommandCost();
/* The meaning of bit 10 is inverted for a grf version < 8. */
if (statspec->grf_prop.grffile->grf_version < 8) ToggleBit(cb_res, 10);
return GetErrorMessageFromLocationCallbackResult(cb_res, statspec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
return GetErrorMessageFromLocationCallbackResult(cb_res, regs100, statspec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
}

View File

@ -680,15 +680,10 @@ struct TextRefStack {
uint8_t position = 0;
const GRFFile *grffile = nullptr;
TextRefStack(const GRFFile *grffile, uint8_t num_entries) : grffile(grffile)
TextRefStack(const GRFFile *grffile, std::span<const int32_t> textstack) : grffile(grffile)
{
extern TemporaryStorageArray<int32_t, 0x110> _temp_store;
assert(num_entries < sizeof(uint32_t) * std::size(stack));
auto stack_it = this->stack.begin();
for (uint i = 0; i < num_entries; i++) {
uint32_t value = _temp_store.GetValue(0x100 + i);
for (int32_t value : textstack) {
for (uint j = 0; j < 32; j += 8) {
*stack_it++ = GB(value, j, 8);
}
@ -960,10 +955,10 @@ static void HandleNewGRFStringControlCodes(std::string_view str, TextRefStack &s
* Process the text ref stack for a GRF String and return its parameters.
* @param grffile GRFFile of string.
* @param stringid StringID of string.
* @param num_entries Number of temporary storage registers to import.
* @param textstack Text parameter stack.
* @returns Parameters for GRF string.
*/
std::vector<StringParameter> GetGRFSringTextStackParameters(const GRFFile *grffile, StringID stringid, uint8_t num_entries)
std::vector<StringParameter> GetGRFSringTextStackParameters(const GRFFile *grffile, StringID stringid, std::span<const int32_t> textstack)
{
if (stringid == INVALID_STRING_ID) return {};
@ -972,7 +967,7 @@ std::vector<StringParameter> GetGRFSringTextStackParameters(const GRFFile *grffi
std::vector<StringParameter> params;
params.reserve(20);
TextRefStack stack{grffile, num_entries};
TextRefStack stack{grffile, textstack};
HandleNewGRFStringControlCodes(str, stack, params);
return params;
@ -982,12 +977,12 @@ std::vector<StringParameter> GetGRFSringTextStackParameters(const GRFFile *grffi
* Format a GRF string using the text ref stack for parameters.
* @param grffile GRFFile of string.
* @param grfstringid GRFStringID of string.
* @param num_entries Number of temporary storage registers to import.
* @param textstack Text parameter stack.
* @returns Formatted string.
*/
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, uint8_t num_entries)
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span<const int32_t> textstack)
{
StringID stringid = GetGRFStringID(grffile->grfid, grfstringid);
auto params = GetGRFSringTextStackParameters(grffile, stringid, num_entries);
auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack);
return GetStringWithArgs(stringid, params);
}

View File

@ -28,7 +28,7 @@ void AddGRFTextToList(GRFTextWrapper &list, std::string_view text_to_add);
bool CheckGrfLangID(uint8_t lang_id, uint8_t grf_version);
std::vector<StringParameter> GetGRFSringTextStackParameters(const struct GRFFile *grffile, StringID stringid, uint8_t num_entries);
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, uint8_t num_entries);
std::vector<StringParameter> GetGRFSringTextStackParameters(const struct GRFFile *grffile, StringID stringid, std::span<const int32_t> textstack);
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span<const int32_t> textstack);
#endif /* NEWGRF_TEXT_H */

View File

@ -276,9 +276,10 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type
for (TileIndex t : ta) {
uint16_t callback = CALLBACK_FAILED;
std::array<int32_t, 4> regs100;
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, regs100, view);
}
if (callback == CALLBACK_FAILED) {
@ -286,7 +287,7 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type
} else {
/* The meaning of bit 10 is inverted for a grf version < 8. */
if (spec->grf_prop.grffile->grf_version < 8) ToggleBit(callback, 10);
CommandCost ret = GetErrorMessageFromLocationCallbackResult(callback, spec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
CommandCost ret = GetErrorMessageFromLocationCallbackResult(callback, regs100, spec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
if (ret.Failed()) return ret;
}
}

View File

@ -237,12 +237,13 @@ 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);
std::array<int32_t, 6> regs100;
uint16_t callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, nullptr, INVALID_TILE, regs100, _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);
} else {
std::string str = GetGRFStringWithTextStack(spec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, 6);
std::string str = GetGRFStringWithTextStack(spec->grf_prop.grffile, GRFSTR_MISC_GRF_TEXT + callback_res, regs100);
if (!str.empty()) {
tr.top = DrawStringMultiLine(tr, str, TC_ORANGE);
}

View File

@ -1599,13 +1599,14 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin
}
if (e->info.callback_mask.Test(VehicleCallbackMask::Name)) {
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_NAME, static_cast<uint32_t>(arg >> 32), 0, e->index, nullptr);
std::array<int32_t, 6> regs100;
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_NAME, static_cast<uint32_t>(arg >> 32), 0, e->index, nullptr, regs100);
/* Not calling ErrorUnknownCallbackResult due to being inside string processing. */
if (callback != CALLBACK_FAILED && callback < 0x400) {
const GRFFile *grffile = e->GetGRF();
assert(grffile != nullptr);
builder += GetGRFStringWithTextStack(grffile, GRFSTR_MISC_GRF_TEXT + callback, 6);
builder += GetGRFStringWithTextStack(grffile, GRFSTR_MISC_GRF_TEXT + callback, regs100);
break;
}
}