diff --git a/src/openrct2-ui/windows/Error.cpp b/src/openrct2-ui/windows/Error.cpp index 74c707eb44..962a8209f8 100644 --- a/src/openrct2-ui/windows/Error.cpp +++ b/src/openrct2-ui/windows/Error.cpp @@ -27,42 +27,91 @@ static rct_widget window_error_widgets[] = { MakeWidget({0, 0}, {200, 42}, WindowWidgetType::ImgBtn, WindowColour::Primary), WIDGETS_END, }; - -static void WindowErrorUnknown5(rct_window *w); -static void WindowErrorPaint(rct_window *w, rct_drawpixelinfo *dpi); - -static WindowEventList window_error_events([](auto& events) -{ - events.unknown_05 = &WindowErrorUnknown5; - events.paint = &WindowErrorPaint; -}); // clang-format on -static std::string _window_error_text; -static uint16_t _window_error_num_lines; - -/** - * - * rct2: 0x0066792F - * - * bx: title - * dx: message - */ -rct_window* WindowErrorOpen(StringId title, StringId message, const Formatter& args) +class ErrorWindow final : public Window { - auto titlez = format_string(title, args.Data()); - auto messagez = format_string(message, args.Data()); - return WindowErrorOpen(titlez, messagez); -} +private: + std::string _text; + uint16_t _numLines; + +public: + ErrorWindow(std::string text, uint16_t numLines) + : _text(text) + , _numLines(numLines) + { + } + + void OnOpen() override + { + window_error_widgets[WIDX_BACKGROUND].right = width; + window_error_widgets[WIDX_BACKGROUND].bottom = height; + + widgets = window_error_widgets; + error.var_480 = 0; + if (!gDisableErrorWindowSound) + { + OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Error, 0, windowPos.x + (width / 2)); + } + } + + void OnDraw(rct_drawpixelinfo& dpi) override + { + ScreenCoordsXY leftTop{ windowPos }; + ScreenCoordsXY rightBottom{ windowPos + ScreenCoordsXY{ width - 1, height - 1 } }; + ScreenCoordsXY leftBottom{ leftTop.x, rightBottom.y }; + ScreenCoordsXY rightTop{ rightBottom.x, leftTop.y }; + + gfx_filter_rect( + &dpi, ScreenRect{ leftTop + ScreenCoordsXY{ 1, 1 }, rightBottom - ScreenCoordsXY{ 1, 1 } }, + FilterPaletteID::Palette45); + gfx_filter_rect(&dpi, ScreenRect{ leftTop, rightBottom }, FilterPaletteID::PaletteGlassSaturatedRed); + + gfx_filter_rect( + &dpi, ScreenRect{ leftTop + ScreenCoordsXY{ 0, 2 }, leftBottom - ScreenCoordsXY{ 0, 2 } }, + FilterPaletteID::PaletteDarken3); + gfx_filter_rect( + &dpi, ScreenRect{ rightTop + ScreenCoordsXY{ 0, 2 }, rightBottom - ScreenCoordsXY{ 0, 2 } }, + FilterPaletteID::PaletteDarken3); + gfx_filter_rect( + &dpi, ScreenRect{ leftBottom + ScreenCoordsXY{ 2, 0 }, rightBottom - ScreenCoordsXY{ 2, 0 } }, + FilterPaletteID::PaletteDarken3); + gfx_filter_rect( + &dpi, ScreenRect{ leftTop + ScreenCoordsXY{ 2, 0 }, rightTop - ScreenCoordsXY{ 2, 0 } }, + FilterPaletteID::PaletteDarken3); + + gfx_filter_rect( + &dpi, ScreenRect{ rightTop + ScreenCoordsXY{ 1, 1 }, rightTop + ScreenCoordsXY{ 1, 1 } }, + FilterPaletteID::PaletteDarken3); + gfx_filter_rect( + &dpi, ScreenRect{ rightTop + ScreenCoordsXY{ -1, 1 }, rightTop + ScreenCoordsXY{ -1, 1 } }, + FilterPaletteID::PaletteDarken3); + gfx_filter_rect( + &dpi, ScreenRect{ leftBottom + ScreenCoordsXY{ 1, -1 }, leftBottom + ScreenCoordsXY{ 1, -1 } }, + FilterPaletteID::PaletteDarken3); + gfx_filter_rect( + &dpi, ScreenRect{ rightBottom - ScreenCoordsXY{ 1, 1 }, rightBottom - ScreenCoordsXY{ 1, 1 } }, + FilterPaletteID::PaletteDarken3); + + draw_string_centred_raw( + &dpi, { leftTop + ScreenCoordsXY{ (width + 1) / 2 - 1, 1 } }, _numLines, _text.data(), FontStyle::Medium); + } + + void OnUnknown5() override + { + error.var_480++; + if (error.var_480 >= 8) + { + Close(); + } + } +}; rct_window* WindowErrorOpen(std::string_view title, std::string_view message) { - int32_t numLines, width, height, maxY; - rct_window* w; - window_close_by_class(WindowClass::Error); - auto& buffer = _window_error_text; - buffer.assign("{BLACK}"); + + std::string buffer = "{BLACK}"; buffer.append(title); // Format the message @@ -82,98 +131,39 @@ rct_window* WindowErrorOpen(std::string_view title, std::string_view message) // Check if there is any text to display if (buffer.size() <= 1) + { return nullptr; + } - width = gfx_get_string_width_new_lined(buffer.data(), FontStyle::Medium); + int32_t width = gfx_get_string_width_new_lined(buffer.data(), FontStyle::Medium); width = std::clamp(width, 64, 196); + int32_t numLines{}; gfx_wrap_string(buffer.data(), width + 1, FontStyle::Medium, &numLines); - _window_error_num_lines = numLines; width = width + 3; - height = (numLines + 1) * font_get_line_height(FontStyle::Medium) + 4; - - window_error_widgets[WIDX_BACKGROUND].right = width; - window_error_widgets[WIDX_BACKGROUND].bottom = height; - + int32_t height = (numLines + 1) * font_get_line_height(FontStyle::Medium) + 4; int32_t screenWidth = context_get_width(); int32_t screenHeight = context_get_height(); const CursorState* state = context_get_cursor_state(); ScreenCoordsXY windowPosition = state->position - ScreenCoordsXY(width / 2, -26); windowPosition.x = std::clamp(windowPosition.x, 0, screenWidth); windowPosition.y = std::max(22, windowPosition.y); - maxY = screenHeight - height; + int32_t maxY = screenHeight - height; if (windowPosition.y > maxY) { windowPosition.y = std::min(windowPosition.y - height - 40, maxY); } - w = WindowCreate( - windowPosition, width, height, &window_error_events, WindowClass::Error, + auto errorWindow = std::make_unique(buffer, numLines); + return WindowCreate( + std::move(errorWindow), WindowClass::Error, windowPosition, width, height, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_RESIZABLE); - w->widgets = window_error_widgets; - w->error.var_480 = 0; - if (!gDisableErrorWindowSound) - { - OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Error, 0, w->windowPos.x + (w->width / 2)); - } - - return w; } -/** - * - * rct2: 0x00667BFE - */ -static void WindowErrorUnknown5(rct_window* w) +rct_window* WindowErrorOpen(StringId title, StringId message, const Formatter& args) { - w->error.var_480++; - if (w->error.var_480 >= 8) - window_close(*w); -} - -/** - * - * rct2: 0x00667AA3 - */ -static void WindowErrorPaint(rct_window* w, rct_drawpixelinfo* dpi) -{ - ScreenCoordsXY leftTop{ w->windowPos }; - ScreenCoordsXY rightBottom{ w->windowPos + ScreenCoordsXY{ w->width - 1, w->height - 1 } }; - ScreenCoordsXY leftBottom{ leftTop.x, rightBottom.y }; - ScreenCoordsXY rightTop{ rightBottom.x, leftTop.y }; - - gfx_filter_rect( - dpi, ScreenRect{ leftTop + ScreenCoordsXY{ 1, 1 }, rightBottom - ScreenCoordsXY{ 1, 1 } }, FilterPaletteID::Palette45); - gfx_filter_rect(dpi, ScreenRect{ leftTop, rightBottom }, FilterPaletteID::PaletteGlassSaturatedRed); - - gfx_filter_rect( - dpi, ScreenRect{ leftTop + ScreenCoordsXY{ 0, 2 }, leftBottom - ScreenCoordsXY{ 0, 2 } }, - FilterPaletteID::PaletteDarken3); - gfx_filter_rect( - dpi, ScreenRect{ rightTop + ScreenCoordsXY{ 0, 2 }, rightBottom - ScreenCoordsXY{ 0, 2 } }, - FilterPaletteID::PaletteDarken3); - gfx_filter_rect( - dpi, ScreenRect{ leftBottom + ScreenCoordsXY{ 2, 0 }, rightBottom - ScreenCoordsXY{ 2, 0 } }, - FilterPaletteID::PaletteDarken3); - gfx_filter_rect( - dpi, ScreenRect{ leftTop + ScreenCoordsXY{ 2, 0 }, rightTop - ScreenCoordsXY{ 2, 0 } }, - FilterPaletteID::PaletteDarken3); - - gfx_filter_rect( - dpi, ScreenRect{ rightTop + ScreenCoordsXY{ 1, 1 }, rightTop + ScreenCoordsXY{ 1, 1 } }, - FilterPaletteID::PaletteDarken3); - gfx_filter_rect( - dpi, ScreenRect{ rightTop + ScreenCoordsXY{ -1, 1 }, rightTop + ScreenCoordsXY{ -1, 1 } }, - FilterPaletteID::PaletteDarken3); - gfx_filter_rect( - dpi, ScreenRect{ leftBottom + ScreenCoordsXY{ 1, -1 }, leftBottom + ScreenCoordsXY{ 1, -1 } }, - FilterPaletteID::PaletteDarken3); - gfx_filter_rect( - dpi, ScreenRect{ rightBottom - ScreenCoordsXY{ 1, 1 }, rightBottom - ScreenCoordsXY{ 1, 1 } }, - FilterPaletteID::PaletteDarken3); - - draw_string_centred_raw( - dpi, { leftTop + ScreenCoordsXY{ (w->width + 1) / 2 - 1, 1 } }, _window_error_num_lines, _window_error_text.data(), - FontStyle::Medium); + auto titlez = format_string(title, args.Data()); + auto messagez = format_string(message, args.Data()); + return WindowErrorOpen(titlez, messagez); } diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 9814aba2de..01bf1f4e01 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -1448,9 +1448,14 @@ void window_event_dropdown_call(rct_window* w, WidgetIndex widgetIndex, int32_t void window_event_unknown_05_call(rct_window* w) { - if (w->event_handlers != nullptr) - if (w->event_handlers->unknown_05 != nullptr) - w->event_handlers->unknown_05(w); + if (w->event_handlers == nullptr) + { + w->OnUnknown5(); + } + else if (w->event_handlers->unknown_05 != nullptr) + { + w->event_handlers->unknown_05(w); + } } void window_event_update_call(rct_window* w) diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index 7fcefb77da..4e0b1f2732 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -194,6 +194,9 @@ struct rct_window { } virtual CursorID OnCursor(WidgetIndex, const ScreenCoordsXY&, CursorID); + virtual void OnUnknown5() + { + } }; #ifdef __WARN_SUGGEST_FINAL_METHODS__