diff --git a/resources/g2/loader/loader_hybrid_supports.png b/resources/g2/loader/loader_hybrid_supports.png new file mode 100644 index 0000000000..8860ca12dd Binary files /dev/null and b/resources/g2/loader/loader_hybrid_supports.png differ diff --git a/resources/g2/loader/loader_hybrid_track.png b/resources/g2/loader/loader_hybrid_track.png new file mode 100644 index 0000000000..326fd4b5ea Binary files /dev/null and b/resources/g2/loader/loader_hybrid_track.png differ diff --git a/resources/g2/loader/loader_hybrid_vehicle.png b/resources/g2/loader/loader_hybrid_vehicle.png new file mode 100644 index 0000000000..914bf2447a Binary files /dev/null and b/resources/g2/loader/loader_hybrid_vehicle.png differ diff --git a/resources/g2/loader/loader_steel_supports.png b/resources/g2/loader/loader_steel_supports.png new file mode 100644 index 0000000000..9dc4c99874 Binary files /dev/null and b/resources/g2/loader/loader_steel_supports.png differ diff --git a/resources/g2/loader/loader_steel_track.png b/resources/g2/loader/loader_steel_track.png new file mode 100644 index 0000000000..d0c604426b Binary files /dev/null and b/resources/g2/loader/loader_steel_track.png differ diff --git a/resources/g2/loader/loader_steel_vehicle.png b/resources/g2/loader/loader_steel_vehicle.png new file mode 100644 index 0000000000..410b84f422 Binary files /dev/null and b/resources/g2/loader/loader_steel_vehicle.png differ diff --git a/resources/g2/loader/loader_wooden_supports.png b/resources/g2/loader/loader_wooden_supports.png new file mode 100644 index 0000000000..bf324c1b1e Binary files /dev/null and b/resources/g2/loader/loader_wooden_supports.png differ diff --git a/resources/g2/loader/loader_wooden_track.png b/resources/g2/loader/loader_wooden_track.png new file mode 100644 index 0000000000..adafe2432a Binary files /dev/null and b/resources/g2/loader/loader_wooden_track.png differ diff --git a/resources/g2/loader/loader_wooden_vehicle.png b/resources/g2/loader/loader_wooden_vehicle.png new file mode 100644 index 0000000000..5267ea5eb0 Binary files /dev/null and b/resources/g2/loader/loader_wooden_vehicle.png differ diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index d2f4bd51f3..862b804f48 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -311,6 +311,39 @@ { "path": "icons/colour_invisible_pressed.png" }, + { + "path": "loader/loader_hybrid_supports.png", + "y": 10 + }, + { + "path": "loader/loader_hybrid_track.png", + "y": 15 + }, + { + "path": "loader/loader_hybrid_vehicle.png" + }, + { + "path": "loader/loader_steel_supports.png", + "y": 27 + }, + { + "path": "loader/loader_steel_track.png", + "y": 16 + }, + { + "path": "loader/loader_steel_vehicle.png" + }, + { + "path": "loader/loader_wooden_supports.png", + "y": 3 + }, + { + "path": "loader/loader_wooden_track.png", + "y": 3 + }, + { + "path": "loader/loader_wooden_vehicle.png" + }, { "path": "palette_map/palette_map_dark_olive_dark.png", "palette": "keep", @@ -24912,12 +24945,12 @@ "palette": "keep" }, { - "path": "icons/medium-curve-left.png", + "path": "icons/medium-curve-left.png", "x": 2, "y": 6 }, { - "path": "icons/medium-curve-right.png", + "path": "icons/medium-curve-right.png", "x": 1, "y": 6 } diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 34f8835da2..4b6aece012 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -269,6 +269,11 @@ public: return nullptr; } + case WindowClass::ProgressWindow: + { + std::string message = intent->GetStringExtra(INTENT_EXTRA_MESSAGE); + return ProgressWindowOpen(message); + } case WindowClass::Ride: { const auto rideId = RideId::FromUnderlying(intent->GetSIntExtra(INTENT_EXTRA_RIDE_ID)); diff --git a/src/openrct2-ui/libopenrct2ui.vcxproj b/src/openrct2-ui/libopenrct2ui.vcxproj index 23fc5adcb4..9c6aeaafc4 100644 --- a/src/openrct2-ui/libopenrct2ui.vcxproj +++ b/src/openrct2-ui/libopenrct2ui.vcxproj @@ -193,6 +193,7 @@ + diff --git a/src/openrct2-ui/windows/ProgressWindow.cpp b/src/openrct2-ui/windows/ProgressWindow.cpp new file mode 100644 index 0000000000..c803f193a0 --- /dev/null +++ b/src/openrct2-ui/windows/ProgressWindow.cpp @@ -0,0 +1,192 @@ +/***************************************************************************** + * Copyright (c) 2014-2024 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace OpenRCT2::Ui::Windows +{ + enum ProgressWindowWidgetIdx + { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + }; + + static constexpr int32_t kWindowWidth = 400; + static constexpr int32_t kWindowHeight = 90; + + // clang-format off + static Widget kProgressWindowWidgets[] = { + MakeWidget({ 0, 0}, { kWindowWidth, kWindowHeight}, WindowWidgetType::Frame, WindowColour::Primary ), // panel / background + MakeWidget({ 1, 1}, {kWindowWidth - 3, 14}, WindowWidgetType::Caption, WindowColour::Primary, STR_STRINGID, STR_WINDOW_TITLE_TIP), // title bar + MakeWidget({kWindowWidth - 12, 2}, { 11, 12}, WindowWidgetType::CloseBox, WindowColour::Primary, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP), // close x button + kWidgetsEnd, + }; + + struct LoaderVehicleStyle + { + ImageId supports; + ImageId track; + ImageId vehicle; + }; + + static std::array kVehicleStyles = { { + { + ImageId{SPR_G2_LOADER_HYBRID_SUPPORTS, COLOUR_LIGHT_ORANGE, COLOUR_DARK_BROWN }, + ImageId{SPR_G2_LOADER_HYBRID_TRACK, COLOUR_LIGHT_ORANGE, COLOUR_LIGHT_ORANGE }, + ImageId{SPR_G2_LOADER_HYBRID_VEHICLE, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN, COLOUR_BRIGHT_RED } + }, + { + ImageId{SPR_G2_LOADER_STEEL_SUPPORTS, COLOUR_LIGHT_BROWN, COLOUR_BLACK }, + ImageId{SPR_G2_LOADER_STEEL_TRACK, COLOUR_LIGHT_BROWN, COLOUR_LIGHT_BROWN }, + ImageId{SPR_G2_LOADER_STEEL_VEHICLE, COLOUR_LIGHT_BLUE, COLOUR_WHITE, COLOUR_LIGHT_BLUE } + }, + { + ImageId{SPR_G2_LOADER_WOODEN_SUPPORTS, COLOUR_BLACK, COLOUR_WHITE }, + ImageId{SPR_G2_LOADER_WOODEN_TRACK, COLOUR_BORDEAUX_RED, COLOUR_BLACK }, + ImageId{SPR_G2_LOADER_WOODEN_VEHICLE, COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED, COLOUR_SATURATED_BROWN} + }, + } }; + + static uint8_t nextStyle = 0; + + // clang-format on + class ProgressWindow final : public Window + { + private: + std::string _captionTemplate; + std::string _currentCaption; + uint8_t style; + + public: + void OnOpen() override + { + widgets = kProgressWindowWidgets; + WindowInitScrollWidgets(*this); + + widgets[WIDX_CLOSE].type = WindowWidgetType::Empty; + + frame_no = 0; + min_width = kWindowWidth; + min_height = kWindowHeight; + max_width = min_width; + max_height = min_height; + + style = nextStyle++ % std::size(kVehicleStyles); + } + + void OnUpdate() override + { + frame_no += 3; + if (frame_no > width) + { + frame_no = 0; + style++; + if (style >= 3) + style = 0; + } + + InvalidateWidget(WIDX_BACKGROUND); + } + + void OnPrepareDraw() override + { + ResizeFrame(); + } + + void PrepareCaption() + { + std::stringstream caption; + caption << _captionTemplate; + caption << " (" << frame_no << " / " << width << ")"; + + _currentCaption = caption.str(); + + // Set window title + auto ft = Formatter::Common(); + ft.Add(STR_STRING); + ft.Add(_currentCaption.c_str()); + } + + void OnDraw(DrawPixelInfo& dpi) override + { + PrepareCaption(); + WindowDrawWidgets(*this, dpi); + + auto& widget = widgets[WIDX_TITLE]; + auto screenCoords = windowPos + ScreenCoordsXY{ widget.left, widget.bottom + 1 }; + + DrawPixelInfo clipDPI; + if (!ClipDrawPixelInfo(clipDPI, dpi, screenCoords, width - 3, height - widget.bottom - 3)) + return; + + auto& variant = kVehicleStyles[style]; + + // Draw supports sprite -- twice, to fill the window + auto trackCoords = ScreenCoordsXY{ widget.left, widget.bottom + 1 }; + GfxDrawSprite(clipDPI, variant.supports, trackCoords); + GfxDrawSprite(clipDPI, variant.supports, trackCoords + ScreenCoordsXY(256, 0)); + + // Draw track sprite -- twice, to fill the window + GfxDrawSprite(clipDPI, variant.track, trackCoords); + GfxDrawSprite(clipDPI, variant.track, trackCoords + ScreenCoordsXY(256, 0)); + + if (_totalCount == 0) + return; + + // Draw vehicle to indicate progress + auto* vehicle = GfxGetG1Element(variant.vehicle); + auto position = (-vehicle->width + 2) + (frame_no % width); + GfxDrawSprite(clipDPI, variant.vehicle, ScreenCoordsXY(position, widget.bottom + 1)); + } + + void SetCaptionTemplate(const std::string& text) + { + _captionTemplate = text; + Invalidate(); + } + }; + + WindowBase* ProgressWindowOpen(const std::string& text) + { + ProgressWindow* window; + if ((window = static_cast(WindowFindByClass(WindowClass::ProgressWindow))) != nullptr) + { + WindowBringToFront(*window); + } + else + { + window = WindowCreate( + WindowClass::ProgressWindow, kWindowWidth, kWindowHeight, + WF_10 | WF_TRANSPARENT | WF_CENTRE_SCREEN | WF_STICK_TO_FRONT); + } + + window->SetCaptionTemplate(text); + return window; + } + + // force close + void ProgressWindowClose() + { + auto window = WindowFindByClass(WindowClass::ProgressWindow); + if (window == nullptr) + { + return; + } + auto progressWindow = static_cast(window); + progressWindow->Close(); + } +} // namespace OpenRCT2::Ui::Windows diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index e5ffb282a2..624f34cbc4 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -167,6 +167,9 @@ namespace OpenRCT2::Ui::Windows WindowBase* NetworkStatusOpenPassword(); void WindowNetworkStatusClose(); + WindowBase* ProgressWindowOpen(const std::string& text); + void ProgressWindowClose(); + void WindowTextInputKey(WindowBase* w, uint32_t keycode); void WindowTextInputOpen( WindowBase* call_w, WidgetIndex call_widget, StringId title, StringId description, const Formatter& descriptionArgs, diff --git a/src/openrct2/interface/WindowClasses.h b/src/openrct2/interface/WindowClasses.h index c0bcdbed0d..30f4e81f1e 100644 --- a/src/openrct2/interface/WindowClasses.h +++ b/src/openrct2/interface/WindowClasses.h @@ -88,6 +88,7 @@ enum class WindowClass : uint8_t Transparency = 134, AssetPacks = 135, ResetShortcutKeysPrompt = 136, + ProgressWindow = 137, // Only used for colour schemes Staff = 220, diff --git a/src/openrct2/scenes/title/TitleScene.cpp b/src/openrct2/scenes/title/TitleScene.cpp index 5fafb6819d..c9dc43f685 100644 --- a/src/openrct2/scenes/title/TitleScene.cpp +++ b/src/openrct2/scenes/title/TitleScene.cpp @@ -29,6 +29,7 @@ #include "../../scenario/ScenarioRepository.h" #include "../../ui/UiContext.h" #include "../../util/Util.h" +#include "../../windows/Intent.h" #include "TitleSequence.h" #include "TitleSequenceManager.h" #include "TitleSequencePlayer.h" @@ -205,6 +206,11 @@ void TitleScene::CreateWindows() ContextOpenWindow(WindowClass::TitleOptions); ContextOpenWindow(WindowClass::TitleLogo); WindowResizeGui(ContextGetWidth(), ContextGetHeight()); + + auto intent = Intent(WindowClass::ProgressWindow); + intent.PutExtra(INTENT_EXTRA_MESSAGE, "Important stuff is loading"); + ContextOpenIntent(&intent); + _hideVersionInfo = false; } diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 235fe5d510..eb66c77299 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -976,6 +976,18 @@ enum SPR_G2_ICON_PALETTE_INVISIBLE, SPR_G2_ICON_PALETTE_INVISIBLE_PRESSED, + // G2 Loading progress + + SPR_G2_LOADER_HYBRID_SUPPORTS, + SPR_G2_LOADER_HYBRID_TRACK, + SPR_G2_LOADER_HYBRID_VEHICLE, + SPR_G2_LOADER_STEEL_SUPPORTS, + SPR_G2_LOADER_STEEL_TRACK, + SPR_G2_LOADER_STEEL_VEHICLE, + SPR_G2_LOADER_WOODEN_SUPPORTS, + SPR_G2_LOADER_WOODEN_TRACK, + SPR_G2_LOADER_WOODEN_VEHICLE, + // G2 Palette maps SPR_G2_PALETTE_BEGIN,