diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index f59ec75f33..aea3630010 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -796,7 +796,8 @@ static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_ */ static std::optional GetNewGRFAdditionalText(EngineID engine) { - uint16_t callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, nullptr); + std::array 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 GetNewGRFAdditionalText(EngineID engine) return std::nullopt; } - return GetGRFStringWithTextStack(grffile, GRFSTR_MISC_GRF_TEXT + callback, 6); + return GetGRFStringWithTextStack(grffile, GRFSTR_MISC_GRF_TEXT + callback, regs100); } /** diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 1314d76202..188f11ffc0 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -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(ind), ind_type, t); + std::array regs100; + uint16_t callback = GetIndustryCallback(CBID_INDUSTRY_CARGO_SUFFIX, 0, (cst << 8) | cargo, const_cast(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 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 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); diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index c4b642407b..aee170bdb0 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -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 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) { diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 0754a8887f..47ff3115a8 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -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 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); diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 767bde9975..31ad22f578 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -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 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); } /** diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 9d63efdd48..01c44f9865 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -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 regs100; + uint16_t callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | static_cast(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. */ diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 28a2e862c3..bad735cc93 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -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 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); } diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 21fcbb7ec7..7394b49629 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -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 textstack) : grffile(grffile) { - extern TemporaryStorageArray _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 GetGRFSringTextStackParameters(const GRFFile *grffile, StringID stringid, uint8_t num_entries) +std::vector GetGRFSringTextStackParameters(const GRFFile *grffile, StringID stringid, std::span textstack) { if (stringid == INVALID_STRING_ID) return {}; @@ -972,7 +967,7 @@ std::vector GetGRFSringTextStackParameters(const GRFFile *grffi std::vector 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 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 textstack) { StringID stringid = GetGRFStringID(grffile->grfid, grfstringid); - auto params = GetGRFSringTextStackParameters(grffile, stringid, num_entries); + auto params = GetGRFSringTextStackParameters(grffile, stringid, textstack); return GetStringWithArgs(stringid, params); } diff --git a/src/newgrf_text.h b/src/newgrf_text.h index b9dffd81ad..7442c1f9ec 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -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 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 GetGRFSringTextStackParameters(const struct GRFFile *grffile, StringID stringid, std::span textstack); +std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span textstack); #endif /* NEWGRF_TEXT_H */ diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 97de750b41..874146b9f0 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -276,9 +276,10 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type for (TileIndex t : ta) { uint16_t callback = CALLBACK_FAILED; + std::array 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; } } diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 8c1e12dca9..a65fad163b 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -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 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); } diff --git a/src/strings.cpp b/src/strings.cpp index 8b803246bd..e0bcb91b7f 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -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(arg >> 32), 0, e->index, nullptr); + std::array regs100; + uint16_t callback = GetVehicleCallback(CBID_VEHICLE_NAME, static_cast(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; } }