diff options
-rw-r--r-- | src/industry_gui.cpp | 2 | ||||
-rw-r--r-- | src/misc_gui.cpp | 11 | ||||
-rw-r--r-- | src/newgrf_industries.cpp | 5 | ||||
-rw-r--r-- | src/newgrf_industrytiles.cpp | 5 | ||||
-rw-r--r-- | src/newgrf_text.cpp | 60 | ||||
-rw-r--r-- | src/newgrf_text.h | 5 |
6 files changed, 67 insertions, 21 deletions
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 98d9b268d..341ff1e2a 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -503,7 +503,7 @@ static void IndustryViewWndProc(Window *w, WindowEvent *e) if (message != STR_NULL && message != STR_UNDEFINED) { y += 10; - PrepareTextRefStackUsage(); + PrepareTextRefStackUsage(6); DrawString(2, y, message, 0); StopTextRefStackUsage(); } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 64bb1e9f1..e3b644927 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -9,6 +9,7 @@ #include "functions.h" #include "landscape.h" #include "newgrf.h" +#include "newgrf_text.h" #include "saveload.h" #include "strings.h" #include "table/sprites.h" @@ -505,6 +506,13 @@ static void ErrmsgWndProc(Window *w, WindowEvent *e) CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params)); DrawWindowWidgets(w); CopyInDParam(0, _errmsg_decode_params, lengthof(_errmsg_decode_params)); + + /* If the error message comes from a NewGRF, we must use the text ref. stack reserved for error messages. + * If the message doesn't come from a NewGRF, it won't use the TTDP-style text ref. stack, so we won't hurt anything + */ + SwitchToErrorRefStack(); + RewindTextRefStack(); + if (!IsWindowOfPrototype(w, _errmsg_face_widgets)) { DrawStringMultiCenter( 120, @@ -533,6 +541,9 @@ static void ErrmsgWndProc(Window *w, WindowEvent *e) _errmsg_message_1, w->width - 2); } + + /* Switch back to the normal text ref. stack for NewGRF texts */ + SwitchToNormalRefStack(); break; case WE_MOUSELOOP: diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 8b8ffb443..3fda15112 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -458,6 +458,11 @@ bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspe * the building of the industry, as that's how it's done in TTDP. */ if (group == NULL || group->type != SGT_CALLBACK) return true; + /* Copy some parameters from the registers to the error message text ref. stack */ + SwitchToErrorRefStack(); + PrepareTextRefStackUsage(4); + SwitchToNormalRefStack(); + switch (group->g.callback.result) { case 0x400: return true; case 0x401: _error_message = STR_0239_SITE_UNSUITABLE; break; diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index f090d12c5..ae69591d5 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -265,6 +265,11 @@ bool PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, return callback_res != 0; } + /* Copy some parameters from the registers to the error message text ref. stack */ + SwitchToErrorRefStack(); + PrepareTextRefStackUsage(4); + SwitchToNormalRefStack(); + switch (callback_res) { case 0x400: return true; case 0x401: _error_message = STR_0239_SITE_UNSUITABLE; return false; diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index b395d8be7..4fdec3f06 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -538,21 +538,28 @@ struct TextRefStack { this->stack[this->position + 1] = GB(word, 8, 8); } - void ResetStack() { this->used = true; this->position = 0; } + void ResetStack() { this->position = 0; this->used = true; } + void RewindStack() { this->position = 0; } }; +static TextRefStack _newgrf_normal_textrefstack; +static TextRefStack _newgrf_error_textrefstack; + /** The stack that is used for TTDP compatible string code parsing */ -static TextRefStack _newgrf_textrefstack; +static TextRefStack *_newgrf_textrefstack = &_newgrf_normal_textrefstack; -/** Prepare the TTDP compatible string code parsing */ -void PrepareTextRefStackUsage() +/** + * Prepare the TTDP compatible string code parsing + * @param numEntries number of entries to copy from the registers + */ +void PrepareTextRefStackUsage(byte numEntries) { extern TemporaryStorageArray<uint32, 0x110> _temp_store; - _newgrf_textrefstack.ResetStack(); + _newgrf_textrefstack->ResetStack(); - byte *p = _newgrf_textrefstack.stack; - for (uint i = 0; i < 6; i++) { + byte *p = _newgrf_textrefstack->stack; + for (uint i = 0; i < numEntries; i++) { for (uint j = 0; j < 32; j += 8) { *p = GB(_temp_store.Get(0x100 + i), j, 8); p++; @@ -561,7 +568,22 @@ void PrepareTextRefStackUsage() } /** Stop using the TTDP compatible string code parsing */ -void StopTextRefStackUsage() { _newgrf_textrefstack.used = false; } +void StopTextRefStackUsage() { _newgrf_textrefstack->used = false; } + +void SwitchToNormalRefStack() +{ + _newgrf_textrefstack = &_newgrf_normal_textrefstack; +} + +void SwitchToErrorRefStack() +{ + _newgrf_textrefstack = &_newgrf_error_textrefstack; +} + +void RewindTextRefStack() +{ + _newgrf_textrefstack->RewindStack(); +} /** * FormatString for NewGRF specific "magic" string control codes @@ -571,31 +593,31 @@ void StopTextRefStackUsage() { _newgrf_textrefstack.used = false; } */ uint RemapNewGRFStringControlCode(uint scc, char **buff, const char **str, int64 *argv) { - if (_newgrf_textrefstack.used) { + if (_newgrf_textrefstack->used) { switch (scc) { default: NOT_REACHED(); - case SCC_NEWGRF_PRINT_SIGNED_BYTE: *argv = _newgrf_textrefstack.PopSignedByte(); break; - case SCC_NEWGRF_PRINT_SIGNED_WORD: *argv = _newgrf_textrefstack.PopSignedWord(); break; - case SCC_NEWGRF_PRINT_QWORD_CURRENCY: *argv = _newgrf_textrefstack.PopUnsignedQWord(); break; + case SCC_NEWGRF_PRINT_SIGNED_BYTE: *argv = _newgrf_textrefstack->PopSignedByte(); break; + case SCC_NEWGRF_PRINT_SIGNED_WORD: *argv = _newgrf_textrefstack->PopSignedWord(); break; + case SCC_NEWGRF_PRINT_QWORD_CURRENCY: *argv = _newgrf_textrefstack->PopUnsignedQWord(); break; case SCC_NEWGRF_PRINT_DWORD_CURRENCY: - case SCC_NEWGRF_PRINT_DWORD: *argv = _newgrf_textrefstack.PopSignedDWord(); break; + case SCC_NEWGRF_PRINT_DWORD: *argv = _newgrf_textrefstack->PopSignedDWord(); break; case SCC_NEWGRF_PRINT_WORD_SPEED: case SCC_NEWGRF_PRINT_WORD_LITRES: - case SCC_NEWGRF_PRINT_UNSIGNED_WORD: *argv = _newgrf_textrefstack.PopUnsignedWord(); break; + case SCC_NEWGRF_PRINT_UNSIGNED_WORD: *argv = _newgrf_textrefstack->PopUnsignedWord(); break; case SCC_NEWGRF_PRINT_DATE: - case SCC_NEWGRF_PRINT_MONTH_YEAR: *argv = _newgrf_textrefstack.PopSignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR; break; + case SCC_NEWGRF_PRINT_MONTH_YEAR: *argv = _newgrf_textrefstack->PopSignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR; break; - case SCC_NEWGRF_DISCARD_WORD: _newgrf_textrefstack.PopUnsignedWord(); break; + case SCC_NEWGRF_DISCARD_WORD: _newgrf_textrefstack->PopUnsignedWord(); break; - case SCC_NEWGRF_ROTATE_TOP_4_WORDS: _newgrf_textrefstack.RotateTop4Words(); break; - case SCC_NEWGRF_PUSH_WORD: _newgrf_textrefstack.PushWord(Utf8Consume(str)); break; + case SCC_NEWGRF_ROTATE_TOP_4_WORDS: _newgrf_textrefstack->RotateTop4Words(); break; + case SCC_NEWGRF_PUSH_WORD: _newgrf_textrefstack->PushWord(Utf8Consume(str)); break; case SCC_NEWGRF_UNPRINT: *buff -= Utf8Consume(str); break; case SCC_NEWGRF_PRINT_STRING_ID: - *argv = _newgrf_textrefstack.PopUnsignedWord(); + *argv = _newgrf_textrefstack->PopUnsignedWord(); if (*argv == STR_NULL) *argv = STR_EMPTY; break; } diff --git a/src/newgrf_text.h b/src/newgrf_text.h index 6db086d0e..9f77036d8 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -15,8 +15,11 @@ char *TranslateTTDPatchCodes(const char *str); bool CheckGrfLangID(byte lang_id, byte grf_version); -void PrepareTextRefStackUsage(); +void PrepareTextRefStackUsage(byte numEntries); void StopTextRefStackUsage(); +void SwitchToNormalRefStack(); +void SwitchToErrorRefStack(); +void RewindTextRefStack(); uint RemapNewGRFStringControlCode(uint scc, char **buff, const char **str, int64 *argv); #endif /* NEWGRF_TEXT_H */ |