From aba0d27a2872b7be104e4b0ab9be58321515bd90 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 13 Jun 2023 15:55:46 +0200 Subject: [PATCH] Codechange: use StringParameters for remapping the NewGRF string control codes --- src/newgrf_text.cpp | 41 ++++++++++++++++++++--------------------- src/newgrf_text.h | 1 - src/strings.cpp | 4 ++-- src/strings_func.h | 14 ++++++++++++++ src/strings_internal.h | 2 ++ 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 1809a1239d..9eed2b8f71 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -842,12 +842,11 @@ void RewindTextRefStack() * FormatString for NewGRF specific "magic" string control codes * @param scc the string control code that has been read * @param str the string that we need to write - * @param argv the OpenTTD stack of values - * @param argv_size space on the stack \a argv - * @param modify_argv When true, modify the OpenTTD stack. + * @param parameters the OpenTTD string formatting parameters + * @param modify_parameters When true, modify the OpenTTD string formatting parameters. * @return the string control code to "execute" now */ -uint RemapNewGRFStringControlCode(uint scc, const char **str, int64 *argv, uint argv_size, bool modify_argv) +uint RemapNewGRFStringControlCode(uint scc, const char **str, StringParameters ¶meters, bool modify_parameters) { switch (scc) { default: break; @@ -877,7 +876,7 @@ uint RemapNewGRFStringControlCode(uint scc, const char **str, int64 *argv, uint case SCC_NEWGRF_PRINT_DWORD_FORCE: case SCC_NEWGRF_PRINT_WORD_STATION_NAME: case SCC_NEWGRF_PRINT_WORD_CARGO_NAME: - if (argv_size < 1) { + if (parameters.GetDataLeft() < 1) { Debug(misc, 0, "Too many NewGRF string parameters."); return 0; } @@ -887,47 +886,47 @@ uint RemapNewGRFStringControlCode(uint scc, const char **str, int64 *argv, uint case SCC_NEWGRF_PRINT_WORD_CARGO_LONG: case SCC_NEWGRF_PRINT_WORD_CARGO_SHORT: case SCC_NEWGRF_PRINT_WORD_CARGO_TINY: - if (argv_size < 2) { + if (parameters.GetDataLeft() < 2) { Debug(misc, 0, "Too many NewGRF string parameters."); return 0; } break; } - if (_newgrf_textrefstack.used && modify_argv) { + if (_newgrf_textrefstack.used && modify_parameters) { /* There is data on the NewGRF text stack, and we want to move them to OpenTTD's string stack. - * After this call, a new call is made with `modify_argv` set to false when the string is finally formatted. */ + * After this call, a new call is made with `modify_parameters` set to false when the string is finally formatted. */ switch (scc) { default: NOT_REACHED(); - case SCC_NEWGRF_PRINT_BYTE_SIGNED: *argv = _newgrf_textrefstack.PopSignedByte(); break; - case SCC_NEWGRF_PRINT_QWORD_CURRENCY: *argv = _newgrf_textrefstack.PopSignedQWord(); break; + case SCC_NEWGRF_PRINT_BYTE_SIGNED: parameters.SetParam(0, _newgrf_textrefstack.PopSignedByte()); break; + case SCC_NEWGRF_PRINT_QWORD_CURRENCY: parameters.SetParam(0, _newgrf_textrefstack.PopSignedQWord()); break; case SCC_NEWGRF_PRINT_DWORD_CURRENCY: - case SCC_NEWGRF_PRINT_DWORD_SIGNED: *argv = _newgrf_textrefstack.PopSignedDWord(); break; + case SCC_NEWGRF_PRINT_DWORD_SIGNED: parameters.SetParam(0, _newgrf_textrefstack.PopSignedDWord()); break; - case SCC_NEWGRF_PRINT_BYTE_HEX: *argv = _newgrf_textrefstack.PopUnsignedByte(); break; - case SCC_NEWGRF_PRINT_QWORD_HEX: *argv = _newgrf_textrefstack.PopUnsignedQWord(); break; + case SCC_NEWGRF_PRINT_BYTE_HEX: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedByte()); break; + case SCC_NEWGRF_PRINT_QWORD_HEX: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedQWord()); break; case SCC_NEWGRF_PRINT_WORD_SPEED: case SCC_NEWGRF_PRINT_WORD_VOLUME_LONG: case SCC_NEWGRF_PRINT_WORD_VOLUME_SHORT: - case SCC_NEWGRF_PRINT_WORD_SIGNED: *argv = _newgrf_textrefstack.PopSignedWord(); break; + case SCC_NEWGRF_PRINT_WORD_SIGNED: parameters.SetParam(0, _newgrf_textrefstack.PopSignedWord()); break; case SCC_NEWGRF_PRINT_WORD_HEX: case SCC_NEWGRF_PRINT_WORD_WEIGHT_LONG: case SCC_NEWGRF_PRINT_WORD_WEIGHT_SHORT: case SCC_NEWGRF_PRINT_WORD_POWER: case SCC_NEWGRF_PRINT_WORD_STATION_NAME: - case SCC_NEWGRF_PRINT_WORD_UNSIGNED: *argv = _newgrf_textrefstack.PopUnsignedWord(); break; + case SCC_NEWGRF_PRINT_WORD_UNSIGNED: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedWord()); break; case SCC_NEWGRF_PRINT_DWORD_FORCE: case SCC_NEWGRF_PRINT_DWORD_DATE_LONG: case SCC_NEWGRF_PRINT_DWORD_DATE_SHORT: - case SCC_NEWGRF_PRINT_DWORD_HEX: *argv = _newgrf_textrefstack.PopUnsignedDWord(); break; + case SCC_NEWGRF_PRINT_DWORD_HEX: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedDWord()); break; /* Dates from NewGRFs have 1920-01-01 as their zero point, convert it to OpenTTD's epoch. */ case SCC_NEWGRF_PRINT_WORD_DATE_LONG: - case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: *argv = _newgrf_textrefstack.PopUnsignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR; break; + case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: parameters.SetParam(0, _newgrf_textrefstack.PopUnsignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR); break; case SCC_NEWGRF_DISCARD_WORD: _newgrf_textrefstack.PopUnsignedWord(); break; @@ -937,17 +936,17 @@ uint RemapNewGRFStringControlCode(uint scc, const char **str, int64 *argv, uint case SCC_NEWGRF_PRINT_WORD_CARGO_LONG: case SCC_NEWGRF_PRINT_WORD_CARGO_SHORT: case SCC_NEWGRF_PRINT_WORD_CARGO_TINY: - argv[0] = GetCargoTranslation(_newgrf_textrefstack.PopUnsignedWord(), _newgrf_textrefstack.grffile); - argv[1] = _newgrf_textrefstack.PopUnsignedWord(); + parameters.SetParam(0, GetCargoTranslation(_newgrf_textrefstack.PopUnsignedWord(), _newgrf_textrefstack.grffile)); + parameters.SetParam(1, _newgrf_textrefstack.PopUnsignedWord()); break; case SCC_NEWGRF_PRINT_WORD_STRING_ID: - *argv = MapGRFStringID(_newgrf_textrefstack.grffile->grfid, _newgrf_textrefstack.PopUnsignedWord()); + parameters.SetParam(0, MapGRFStringID(_newgrf_textrefstack.grffile->grfid, _newgrf_textrefstack.PopUnsignedWord())); break; case SCC_NEWGRF_PRINT_WORD_CARGO_NAME: { CargoID cargo = GetCargoTranslation(_newgrf_textrefstack.PopUnsignedWord(), _newgrf_textrefstack.grffile); - *argv = cargo < NUM_CARGO ? 1ULL << cargo : 0; + parameters.SetParam(0, cargo < NUM_CARGO ? 1ULL << cargo : 0); break; } } diff --git a/src/newgrf_text.h b/src/newgrf_text.h index f177f25686..0963a6dde4 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -49,7 +49,6 @@ void RewindTextRefStack(); bool UsingNewGRFTextStack(); struct TextRefStack *CreateTextRefStackBackup(); void RestoreTextRefStackBackup(struct TextRefStack *backup); -uint RemapNewGRFStringControlCode(uint scc, const char **str, int64 *argv, uint argv_size, bool modify_argv); /** Mapping of language data between a NewGRF and OpenTTD. */ struct LanguageMap { diff --git a/src/strings.cpp b/src/strings.cpp index 5b059eefaf..72e83d81b8 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -868,8 +868,8 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara if (SCC_NEWGRF_FIRST <= b && b <= SCC_NEWGRF_LAST) { /* We need to pass some stuff as it might be modified. */ - //todo: should argve be passed here too? - b = RemapNewGRFStringControlCode(b, &str, (int64 *)args->GetDataPointer(), args->GetDataLeft(), dry_run); + StringParameters remaining = args->GetRemainingParameters(); + b = RemapNewGRFStringControlCode(b, &str, remaining, dry_run); if (b == 0) continue; } diff --git a/src/strings_func.h b/src/strings_func.h index ec3f82cd3f..d378f5394b 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -129,6 +129,20 @@ public: return &this->data[this->offset]; } + /** + * Get a new instance of StringParameters that is a "range" into the + * parameters existing parameters. Upon destruction the offset in the parent + * is not updated. However, calls to SetDParam do update the parameters. + * + * The returned StringParameters must not outlive this StringParameters. + * @return A "range" of the string parameters. + */ + StringParameters GetRemainingParameters() + { + return StringParameters(&this->data[this->offset], GetDataLeft(), + this->type == nullptr ? nullptr : &this->type[this->offset]); + } + /** Return the amount of elements which can still be read. */ uint GetDataLeft() const { diff --git a/src/strings_internal.h b/src/strings_internal.h index b87bda9c30..d471baadf1 100644 --- a/src/strings_internal.h +++ b/src/strings_internal.h @@ -119,4 +119,6 @@ void GenerateTownNameString(StringBuilder &builder, size_t lang, uint32_t seed); void GetTownName(StringBuilder &builder, const struct Town *t); void GRFTownNameGenerate(StringBuilder &builder, uint32 grfid, uint16 gen, uint32 seed); +uint RemapNewGRFStringControlCode(uint scc, const char **str, StringParameters ¶meters, bool modify_parameters); + #endif /* STRINGS_INTERNAL_H */