From a4d010415b047fe867e1840a0da328bd68213afb Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sun, 10 May 2020 17:10:28 -0300 Subject: [PATCH 01/16] Encapsulate gNewsItems --- src/openrct2/management/NewsItem.cpp | 2 +- src/openrct2/management/NewsItem.h | 2 -- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct2/S6Exporter.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 17ad8d09e6..ee2efddf90 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -23,7 +23,7 @@ #include "../windows/Intent.h" #include "../world/Sprite.h" -NewsItem gNewsItems[MAX_NEWS_ITEMS]; +static NewsItem gNewsItems[MAX_NEWS_ITEMS]; /** rct2: 0x0097BE7C */ const uint8_t news_type_properties[] = { diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index c1acfa40d2..afb51c040a 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -59,8 +59,6 @@ constexpr int32_t MAX_NEWS_ITEMS = 61; extern const uint8_t news_type_properties[10]; -extern NewsItem gNewsItems[MAX_NEWS_ITEMS]; - void news_item_init_queue(); void news_item_update_current(); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index ba7dd3b95e..bfc80418b5 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2531,7 +2531,7 @@ private: for (size_t i = 0; i < RCT12_MAX_NEWS_ITEMS; i++) { const rct12_news_item* src = &_s4.messages[i]; - NewsItem* dst = &gNewsItems[i]; + NewsItem* dst = news_item_get(static_cast(i)); dst->Type = src->Type; dst->Flags = src->Flags; diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 0479a8a152..ebb676e20e 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -399,7 +399,7 @@ void S6Exporter::Export() // News items for (size_t i = 0; i < RCT12_MAX_NEWS_ITEMS; i++) { - const NewsItem* src = &gNewsItems[i]; + const NewsItem* src = news_item_get(static_cast(i)); rct12_news_item* dst = &_s6.news_items[i]; dst->Type = src->Type; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index eed88c0408..0f604d1d97 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -419,7 +419,7 @@ public: for (size_t i = 0; i < RCT12_MAX_NEWS_ITEMS; i++) { const rct12_news_item* src = &_s6.news_items[i]; - NewsItem* dst = &gNewsItems[i]; + NewsItem* dst = news_item_get(static_cast(i)); if (src->Type < std::size(news_type_properties)) { dst->Type = src->Type; From 230162534b542567b64ea5cac32fc2fffaeb6950 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sun, 10 May 2020 17:31:15 -0300 Subject: [PATCH 02/16] Create constants for sizes of NewsItem queues --- src/openrct2-ui/windows/News.cpp | 8 ++++---- src/openrct2/management/NewsItem.cpp | 12 ++++++------ src/openrct2/management/NewsItem.h | 5 +++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index f43e01bf65..9a98f0e42d 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -150,7 +150,7 @@ static void window_news_update(rct_window* w) j = w->news.var_480; w->news.var_480 = -1; - for (i = 11; i < 61; i++) + for (i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) return; @@ -188,7 +188,7 @@ static void window_news_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_ int32_t itemHeight = window_news_get_item_height(); *height = 0; - for (int32_t i = 11; i < 61; i++) + for (int32_t i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) break; @@ -208,7 +208,7 @@ static void window_news_scrollmousedown(rct_window* w, int32_t scrollIndex, cons buttonIndex = 0; auto mutableScreenCoords = screenCoords; - for (i = 11; i < 61; i++) + for (i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) break; @@ -266,7 +266,7 @@ static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32 int32_t i, x, y, yy, press; y = 0; - for (i = 11; i < 61; i++) + for (i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) { NewsItem* const newsItem = news_item_get(i); if (news_item_is_empty(i)) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index ee2efddf90..255c47a18f 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -164,11 +164,11 @@ void news_item_close_current() window_invalidate_by_class(WC_RECENT_NEWS); // Dequeue the current news item, shift news up - for (i = 0; i < NEWS_ITEM_HISTORY_START - 1; i++) + for (i = 0; i < MAX_RECENT_NEWS_ITEMS - 1; i++) { newsItems[i] = newsItems[i + 1]; } - newsItems[NEWS_ITEM_HISTORY_START - 1].Type = NEWS_ITEM_NULL; + newsItems[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; // Invalidate current news item bar auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); @@ -190,7 +190,7 @@ static void news_item_shift_history_up() static int32_t news_item_get_new_history_slot() { // Find an available history news item slot - for (int32_t i = NEWS_ITEM_HISTORY_START; i < MAX_NEWS_ITEMS; i++) + for (int32_t i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) return i; @@ -301,7 +301,7 @@ static NewsItem* news_item_first_open_queue_slot() while (newsItem->Type != NEWS_ITEM_NULL) { - if (newsItem + 1 >= &gNewsItems[NEWS_ITEM_HISTORY_START - 1]) + if (newsItem + 1 >= &gNewsItems[MAX_RECENT_NEWS_ITEMS - 1]) news_item_close_current(); else newsItem++; @@ -438,7 +438,7 @@ void news_item_open_subject(int32_t type, int32_t subject) void news_item_disable_news(uint8_t type, uint32_t assoc) { // TODO: write test invalidating windows - for (int32_t i = 0; i < NEWS_ITEM_HISTORY_START; i++) + for (int32_t i = 0; i < MAX_RECENT_NEWS_ITEMS; i++) { if (!news_item_is_empty(i)) { @@ -459,7 +459,7 @@ void news_item_disable_news(uint8_t type, uint32_t assoc) } } - for (int32_t i = NEWS_ITEM_HISTORY_START; i < MAX_NEWS_ITEMS; i++) + for (int32_t i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) { if (!news_item_is_empty(i)) { diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index afb51c040a..82bc8b3e42 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -54,8 +54,9 @@ struct NewsItem utf8 Text[256]; }; -constexpr int32_t NEWS_ITEM_HISTORY_START = 11; -constexpr int32_t MAX_NEWS_ITEMS = 61; +constexpr int32_t MAX_RECENT_NEWS_ITEMS = 11; +constexpr int32_t MAX_OLD_NEWS_ITEMS = 50; +constexpr int32_t MAX_NEWS_ITEMS = MAX_RECENT_NEWS_ITEMS + MAX_OLD_NEWS_ITEMS; extern const uint8_t news_type_properties[10]; From f4778a8c010abe749b36403c48517c0107e85914 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sun, 10 May 2020 18:28:09 -0300 Subject: [PATCH 03/16] Split gNewsItems into two --- src/openrct2/management/NewsItem.cpp | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 255c47a18f..14aca8aa9a 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -23,7 +23,8 @@ #include "../windows/Intent.h" #include "../world/Sprite.h" -static NewsItem gNewsItems[MAX_NEWS_ITEMS]; +static NewsItem gRecentNewsItems[MAX_RECENT_NEWS_ITEMS]; +static NewsItem gOldNewsItems[MAX_OLD_NEWS_ITEMS]; /** rct2: 0x0097BE7C */ const uint8_t news_type_properties[] = { @@ -55,7 +56,10 @@ NewsItem* news_item_get(int32_t index) { if (news_item_is_valid_idx(index)) { - return &gNewsItems[index]; + if (index < MAX_RECENT_NEWS_ITEMS) + return &gRecentNewsItems[index]; + else + return &gOldNewsItems[index - MAX_RECENT_NEWS_ITEMS]; } else { @@ -143,22 +147,20 @@ void news_item_update_current() */ void news_item_close_current() { - int32_t i; - NewsItem* newsItems = gNewsItems; // Check if there is a current message if (news_item_is_queue_empty()) return; // Find an available history news item slot for current message - i = news_item_get_new_history_slot(); + int32_t i = news_item_get_new_history_slot() - MAX_RECENT_NEWS_ITEMS; // Set the history news item slot to the current news item - newsItems[i] = newsItems[0]; + gOldNewsItems[i] = gRecentNewsItems[0]; // Set the end of the end of the history list - if (i < MAX_NEWS_ITEMS - 1) - newsItems[i + 1].Type = NEWS_ITEM_NULL; + if (i < MAX_OLD_NEWS_ITEMS - 1) + gOldNewsItems[i + 1].Type = NEWS_ITEM_NULL; // Invalidate the news window window_invalidate_by_class(WC_RECENT_NEWS); @@ -166,9 +168,9 @@ void news_item_close_current() // Dequeue the current news item, shift news up for (i = 0; i < MAX_RECENT_NEWS_ITEMS - 1; i++) { - newsItems[i] = newsItems[i + 1]; + gRecentNewsItems[i] = gRecentNewsItems[i + 1]; } - newsItems[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; + gRecentNewsItems[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; // Invalidate current news item bar auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); @@ -297,16 +299,15 @@ std::optional news_item_get_subject_location(int32_t type, int32_t su static NewsItem* news_item_first_open_queue_slot() { - NewsItem* newsItem = gNewsItems; - - while (newsItem->Type != NEWS_ITEM_NULL) + int32_t i = 0; + for (;gRecentNewsItems[i].Type != NEWS_ITEM_NULL;) { - if (newsItem + 1 >= &gNewsItems[MAX_RECENT_NEWS_ITEMS - 1]) + if (i >= MAX_RECENT_NEWS_ITEMS - 2) news_item_close_current(); else - newsItem++; + i++; } - return newsItem; + return &gRecentNewsItems[i]; } /** From c40dd3d3d0db23b6f19cd4b67caa3ac96a2eb8d2 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sun, 10 May 2020 21:35:45 -0300 Subject: [PATCH 04/16] Access news queues directly or with iterators --- src/openrct2/management/NewsItem.cpp | 115 +++++++++++---------------- src/openrct2/management/NewsItem.h | 5 ++ 2 files changed, 50 insertions(+), 70 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 14aca8aa9a..30c29e7b2a 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -40,7 +40,7 @@ const uint8_t news_type_properties[] = { NEWS_TYPE_HAS_SUBJECT, // NEWS_ITEM_GRAPH }; -static int32_t news_item_get_new_history_slot(); +static void news_item_append_to_old_history(NewsItem& item); bool news_item_is_valid_idx(int32_t index) { @@ -70,12 +70,12 @@ NewsItem* news_item_get(int32_t index) bool news_item_is_empty(int32_t index) { NewsItem* news = news_item_get(index); - return news != nullptr && news->Type == NEWS_ITEM_NULL; + return news != nullptr && news->IsEmpty(); } bool news_item_is_queue_empty() { - return news_item_is_empty(0); + return gRecentNewsItems[0].IsEmpty(); } /** @@ -84,8 +84,8 @@ bool news_item_is_queue_empty() */ void news_item_init_queue() { - news_item_get(0)->Type = NEWS_ITEM_NULL; - news_item_get(NEWS_ITEM_HISTORY_START)->Type = NEWS_ITEM_NULL; + gRecentNewsItems[0].Type = NEWS_ITEM_NULL; + gOldNewsItems[0].Type = NEWS_ITEM_NULL; // Throttles for warning types (PEEP_*_WARNING) for (auto& warningThrottle : gPeepWarningThrottle) @@ -100,7 +100,7 @@ void news_item_init_queue() static void news_item_tick_current() { int32_t ticks; - ticks = ++news_item_get(0)->Ticks; + ticks = ++gRecentNewsItems[0].Ticks; // Only play news item sound when in normal playing mode if (ticks == 1 && (gScreenFlags == SCREEN_FLAGS_PLAYING)) { @@ -112,12 +112,13 @@ static void news_item_tick_current() static bool news_item_is_current_old() { int32_t remove_time = 320; - if (!news_item_is_empty(5) && !news_item_is_empty(4) && !news_item_is_empty(3) && !news_item_is_empty(2)) + if (!gRecentNewsItems[5].IsEmpty() && !gRecentNewsItems[4].IsEmpty() && !gRecentNewsItems[3].IsEmpty() + && !gRecentNewsItems[2].IsEmpty()) { remove_time = 256; } - return news_item_get(0)->Ticks >= remove_time; + return gRecentNewsItems[0].Ticks >= remove_time; } /** @@ -147,29 +148,17 @@ void news_item_update_current() */ void news_item_close_current() { - // Check if there is a current message if (news_item_is_queue_empty()) return; - // Find an available history news item slot for current message - int32_t i = news_item_get_new_history_slot() - MAX_RECENT_NEWS_ITEMS; - - // Set the history news item slot to the current news item - gOldNewsItems[i] = gRecentNewsItems[0]; - - // Set the end of the end of the history list - if (i < MAX_OLD_NEWS_ITEMS - 1) - gOldNewsItems[i + 1].Type = NEWS_ITEM_NULL; + news_item_append_to_old_history(gRecentNewsItems[0]); // Invalidate the news window window_invalidate_by_class(WC_RECENT_NEWS); // Dequeue the current news item, shift news up - for (i = 0; i < MAX_RECENT_NEWS_ITEMS - 1; i++) - { - gRecentNewsItems[i] = gRecentNewsItems[i + 1]; - } + memmove(gRecentNewsItems, gRecentNewsItems + 1, sizeof(NewsItem) * (std::size(gRecentNewsItems) - 1)); gRecentNewsItems[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; // Invalidate current news item bar @@ -177,30 +166,28 @@ void news_item_close_current() context_broadcast_intent(&intent); } -static void news_item_shift_history_up() -{ - const int32_t history_idx = NEWS_ITEM_HISTORY_START; - NewsItem* history_start = news_item_get(history_idx); - const size_t count = sizeof(NewsItem) * (MAX_NEWS_ITEMS - 1 - history_idx); - memmove(history_start, history_start + 1, count); -} - /** * Finds a spare history slot or replaces an existing one if there are no spare * slots available. */ -static int32_t news_item_get_new_history_slot() +static void news_item_append_to_old_history(NewsItem& item) { - // Find an available history news item slot - for (int32_t i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) + auto it = std::begin(gOldNewsItems); + for (; it < std::end(gOldNewsItems); ++it) { - if (news_item_is_empty(i)) - return i; + if (it->IsEmpty()) + { + *it = item; + ++it; + if (it != std::end(gOldNewsItems)) + it->Type = NEWS_ITEM_NULL; + return; + } } // Dequeue the first history news item, shift history up - news_item_shift_history_up(); - return MAX_NEWS_ITEMS - 1; + memmove(gOldNewsItems, gOldNewsItems + 1, sizeof(NewsItem) * (std::size(gOldNewsItems) - 1)); + gOldNewsItems[MAX_OLD_NEWS_ITEMS - 1] = item; } /** @@ -299,15 +286,15 @@ std::optional news_item_get_subject_location(int32_t type, int32_t su static NewsItem* news_item_first_open_queue_slot() { - int32_t i = 0; - for (;gRecentNewsItems[i].Type != NEWS_ITEM_NULL;) + auto it = std::begin(gRecentNewsItems); + for (; !it->IsEmpty();) { - if (i >= MAX_RECENT_NEWS_ITEMS - 2) + if (it + 2 >= std::end(gRecentNewsItems)) news_item_close_current(); else - i++; + it++; } - return &gRecentNewsItems[i]; + return &*it; } /** @@ -439,41 +426,29 @@ void news_item_open_subject(int32_t type, int32_t subject) void news_item_disable_news(uint8_t type, uint32_t assoc) { // TODO: write test invalidating windows - for (int32_t i = 0; i < MAX_RECENT_NEWS_ITEMS; i++) + for (auto it = std::begin(gRecentNewsItems); it < std::end(gRecentNewsItems); ++it) { - if (!news_item_is_empty(i)) - { - NewsItem* const newsItem = news_item_get(i); - if (type == newsItem->Type && assoc == newsItem->Assoc) - { - newsItem->Flags |= NEWS_FLAG_HAS_BUTTON; - if (i == 0) - { - auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); - context_broadcast_intent(&intent); - } - } - } - else - { + if (it->IsEmpty()) break; + if (type == it->Type && assoc == it->Assoc) + { + it->Flags |= NEWS_FLAG_HAS_BUTTON; + if (it == std::begin(gRecentNewsItems)) + { + auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); + context_broadcast_intent(&intent); + } } } - for (int32_t i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) + for (auto it = std::begin(gOldNewsItems); it < std::end(gOldNewsItems); ++it) { - if (!news_item_is_empty(i)) - { - NewsItem* const newsItem = news_item_get(i); - if (type == newsItem->Type && assoc == newsItem->Assoc) - { - newsItem->Flags |= NEWS_FLAG_HAS_BUTTON; - window_invalidate_by_class(WC_RECENT_NEWS); - } - } - else - { + if (it->IsEmpty()) break; + if (type == it->Type && assoc == it->Assoc) + { + it->Flags |= NEWS_FLAG_HAS_BUTTON; + window_invalidate_by_class(WC_RECENT_NEWS); } } } diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index 82bc8b3e42..5c77c1bf17 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -52,6 +52,11 @@ struct NewsItem uint16_t MonthYear; uint8_t Day; utf8 Text[256]; + + constexpr bool IsEmpty() const noexcept + { + return Type == NEWS_ITEM_NULL; + } }; constexpr int32_t MAX_RECENT_NEWS_ITEMS = 11; From f7ec58d53f5f63435e80d93df3de9a3a7f5f9a5c Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sun, 10 May 2020 21:57:05 -0300 Subject: [PATCH 05/16] Use for-range and std::find_if --- src/openrct2/management/NewsItem.cpp | 36 +++++++++++++--------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 30c29e7b2a..debdaa163d 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -172,17 +172,15 @@ void news_item_close_current() */ static void news_item_append_to_old_history(NewsItem& item) { - auto it = std::begin(gOldNewsItems); - for (; it < std::end(gOldNewsItems); ++it) + auto it = std::find_if( + std::begin(gOldNewsItems), std::end(gOldNewsItems), [](const auto& newsItem) { return newsItem.IsEmpty(); }); + if (it != std::end(gOldNewsItems)) { - if (it->IsEmpty()) - { - *it = item; - ++it; - if (it != std::end(gOldNewsItems)) - it->Type = NEWS_ITEM_NULL; - return; - } + *it = item; + ++it; + if (it != std::end(gOldNewsItems)) + it->Type = NEWS_ITEM_NULL; + return; } // Dequeue the first history news item, shift history up @@ -426,14 +424,14 @@ void news_item_open_subject(int32_t type, int32_t subject) void news_item_disable_news(uint8_t type, uint32_t assoc) { // TODO: write test invalidating windows - for (auto it = std::begin(gRecentNewsItems); it < std::end(gRecentNewsItems); ++it) + for (auto& newsItem : gRecentNewsItems) { - if (it->IsEmpty()) + if (newsItem.IsEmpty()) break; - if (type == it->Type && assoc == it->Assoc) + if (type == newsItem.Type && assoc == newsItem.Assoc) { - it->Flags |= NEWS_FLAG_HAS_BUTTON; - if (it == std::begin(gRecentNewsItems)) + newsItem.Flags |= NEWS_FLAG_HAS_BUTTON; + if (&newsItem == &*std::begin(gRecentNewsItems)) { auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); context_broadcast_intent(&intent); @@ -441,13 +439,13 @@ void news_item_disable_news(uint8_t type, uint32_t assoc) } } - for (auto it = std::begin(gOldNewsItems); it < std::end(gOldNewsItems); ++it) + for (auto& newsItem : gOldNewsItems) { - if (it->IsEmpty()) + if (newsItem.IsEmpty()) break; - if (type == it->Type && assoc == it->Assoc) + if (type == newsItem.Type && assoc == newsItem.Assoc) { - it->Flags |= NEWS_FLAG_HAS_BUTTON; + newsItem.Flags |= NEWS_FLAG_HAS_BUTTON; window_invalidate_by_class(WC_RECENT_NEWS); } } From c9574c1070d38b09c64aa68d13cefffc72f8af1a Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sun, 10 May 2020 23:56:59 -0300 Subject: [PATCH 06/16] Create class NewsItemQueue --- src/openrct2/management/NewsItem.cpp | 114 +++++++++++++++------------ src/openrct2/management/NewsItem.h | 42 ++++++++++ 2 files changed, 107 insertions(+), 49 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index debdaa163d..10d5864d2c 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -23,8 +23,7 @@ #include "../windows/Intent.h" #include "../world/Sprite.h" -static NewsItem gRecentNewsItems[MAX_RECENT_NEWS_ITEMS]; -static NewsItem gOldNewsItems[MAX_OLD_NEWS_ITEMS]; +static NewsItemQueue gNewsItems; /** rct2: 0x0097BE7C */ const uint8_t news_type_properties[] = { @@ -40,8 +39,6 @@ const uint8_t news_type_properties[] = { NEWS_TYPE_HAS_SUBJECT, // NEWS_ITEM_GRAPH }; -static void news_item_append_to_old_history(NewsItem& item); - bool news_item_is_valid_idx(int32_t index) { if (index >= MAX_NEWS_ITEMS) @@ -53,13 +50,18 @@ bool news_item_is_valid_idx(int32_t index) } NewsItem* news_item_get(int32_t index) +{ + return gNewsItems.At(index); +} + +NewsItem* NewsItemQueue::At(int32_t index) { if (news_item_is_valid_idx(index)) { if (index < MAX_RECENT_NEWS_ITEMS) - return &gRecentNewsItems[index]; + return &Recent[index]; else - return &gOldNewsItems[index - MAX_RECENT_NEWS_ITEMS]; + return &Old[index - MAX_RECENT_NEWS_ITEMS]; } else { @@ -69,23 +71,33 @@ NewsItem* news_item_get(int32_t index) bool news_item_is_empty(int32_t index) { - NewsItem* news = news_item_get(index); + NewsItem* news = gNewsItems.At(index); return news != nullptr && news->IsEmpty(); } bool news_item_is_queue_empty() { - return gRecentNewsItems[0].IsEmpty(); + return gNewsItems.IsEmpty(); +} + +bool NewsItemQueue::IsEmpty() const +{ + return Current().IsEmpty(); } /** * * rct2: 0x0066DF32 */ +void NewsItemQueue::Init() +{ + Current().Type = NEWS_ITEM_NULL; + Oldest().Type = NEWS_ITEM_NULL; +} + void news_item_init_queue() { - gRecentNewsItems[0].Type = NEWS_ITEM_NULL; - gOldNewsItems[0].Type = NEWS_ITEM_NULL; + gNewsItems.Init(); // Throttles for warning types (PEEP_*_WARNING) for (auto& warningThrottle : gPeepWarningThrottle) @@ -97,10 +109,14 @@ void news_item_init_queue() context_broadcast_intent(&intent); } +uint16_t NewsItemQueue::IncrementTicks() +{ + return ++Current().Ticks; +} + static void news_item_tick_current() { - int32_t ticks; - ticks = ++gRecentNewsItems[0].Ticks; + int32_t ticks = gNewsItems.IncrementTicks(); // Only play news item sound when in normal playing mode if (ticks == 1 && (gScreenFlags == SCREEN_FLAGS_PLAYING)) { @@ -109,16 +125,18 @@ static void news_item_tick_current() } } -static bool news_item_is_current_old() +int32_t NewsItemQueue::RemoveTime() const { - int32_t remove_time = 320; - if (!gRecentNewsItems[5].IsEmpty() && !gRecentNewsItems[4].IsEmpty() && !gRecentNewsItems[3].IsEmpty() - && !gRecentNewsItems[2].IsEmpty()) + if (!Recent[5].IsEmpty() && !Recent[4].IsEmpty() && !Recent[3].IsEmpty() && !Recent[2].IsEmpty()) { - remove_time = 256; + return 256; } + return 320; +} - return gRecentNewsItems[0].Ticks >= remove_time; +bool NewsItemQueue::IsCurrentOld() const +{ + return Current().Ticks >= RemoveTime(); } /** @@ -128,7 +146,7 @@ static bool news_item_is_current_old() void news_item_update_current() { // Check if there is a current news item - if (news_item_is_queue_empty()) + if (gNewsItems.IsEmpty()) return; auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); @@ -138,8 +156,8 @@ void news_item_update_current() news_item_tick_current(); // Removal of current news item - if (news_item_is_current_old()) - news_item_close_current(); + if (gNewsItems.IsCurrentOld()) + gNewsItems.MoveCurrentToOld(); } /** @@ -147,19 +165,24 @@ void news_item_update_current() * rct2: 0x0066E377 */ void news_item_close_current() +{ + gNewsItems.MoveCurrentToOld(); +} + +void NewsItemQueue::MoveCurrentToOld() { // Check if there is a current message - if (news_item_is_queue_empty()) + if (IsEmpty()) return; - news_item_append_to_old_history(gRecentNewsItems[0]); + AppendToOld(Current()); // Invalidate the news window window_invalidate_by_class(WC_RECENT_NEWS); // Dequeue the current news item, shift news up - memmove(gRecentNewsItems, gRecentNewsItems + 1, sizeof(NewsItem) * (std::size(gRecentNewsItems) - 1)); - gRecentNewsItems[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; + memmove(Recent, Recent + 1, sizeof(NewsItem) * (std::size(Recent) - 1)); + Recent[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; // Invalidate current news item bar auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); @@ -170,22 +193,21 @@ void news_item_close_current() * Finds a spare history slot or replaces an existing one if there are no spare * slots available. */ -static void news_item_append_to_old_history(NewsItem& item) +void NewsItemQueue::AppendToOld(NewsItem& item) { - auto it = std::find_if( - std::begin(gOldNewsItems), std::end(gOldNewsItems), [](const auto& newsItem) { return newsItem.IsEmpty(); }); - if (it != std::end(gOldNewsItems)) + auto it = std::find_if(std::begin(Old), std::end(Old), [](const auto& newsItem) { return newsItem.IsEmpty(); }); + if (it != std::end(Old)) { *it = item; ++it; - if (it != std::end(gOldNewsItems)) + if (it != std::end(Old)) it->Type = NEWS_ITEM_NULL; return; } // Dequeue the first history news item, shift history up - memmove(gOldNewsItems, gOldNewsItems + 1, sizeof(NewsItem) * (std::size(gOldNewsItems) - 1)); - gOldNewsItems[MAX_OLD_NEWS_ITEMS - 1] = item; + memmove(Old, Old + 1, sizeof(NewsItem) * (std::size(Old) - 1)); + Old[MAX_OLD_NEWS_ITEMS - 1] = item; } /** @@ -282,13 +304,13 @@ std::optional news_item_get_subject_location(int32_t type, int32_t su return subjectLoc; } -static NewsItem* news_item_first_open_queue_slot() +NewsItem* NewsItemQueue::FirstOpenSlot() { - auto it = std::begin(gRecentNewsItems); + auto it = std::begin(Recent); for (; !it->IsEmpty();) { - if (it + 2 >= std::end(gRecentNewsItems)) - news_item_close_current(); + if (it + 2 >= std::end(Recent)) + MoveCurrentToOld(); else it++; } @@ -311,7 +333,7 @@ NewsItem* news_item_add_to_queue(uint8_t type, rct_string_id string_id, uint32_t NewsItem* news_item_add_to_queue_raw(uint8_t type, const utf8* text, uint32_t assoc) { - NewsItem* newsItem = news_item_first_open_queue_slot(); + NewsItem* newsItem = gNewsItems.FirstOpenSlot(); newsItem->Type = type; newsItem->Flags = 0; newsItem->Assoc = assoc; @@ -424,36 +446,30 @@ void news_item_open_subject(int32_t type, int32_t subject) void news_item_disable_news(uint8_t type, uint32_t assoc) { // TODO: write test invalidating windows - for (auto& newsItem : gRecentNewsItems) - { - if (newsItem.IsEmpty()) - break; + gNewsItems.ForeachRecentNews([type, assoc](auto& newsItem) { if (type == newsItem.Type && assoc == newsItem.Assoc) { newsItem.Flags |= NEWS_FLAG_HAS_BUTTON; - if (&newsItem == &*std::begin(gRecentNewsItems)) + if (&newsItem == &gNewsItems.Current()) { auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); context_broadcast_intent(&intent); } } - } + }); - for (auto& newsItem : gOldNewsItems) - { - if (newsItem.IsEmpty()) - break; + gNewsItems.ForeachOldNews([type, assoc](auto& newsItem) { if (type == newsItem.Type && assoc == newsItem.Assoc) { newsItem.Flags |= NEWS_FLAG_HAS_BUTTON; window_invalidate_by_class(WC_RECENT_NEWS); } - } + }); } void news_item_add_to_queue_custom(NewsItem* newNewsItem) { - NewsItem* newsItem = news_item_first_open_queue_slot(); + NewsItem* newsItem = gNewsItems.FirstOpenSlot(); *newsItem = *newNewsItem; newsItem++; newsItem->Type = NEWS_ITEM_NULL; diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index 5c77c1bf17..db434ddcc0 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -63,6 +63,48 @@ constexpr int32_t MAX_RECENT_NEWS_ITEMS = 11; constexpr int32_t MAX_OLD_NEWS_ITEMS = 50; constexpr int32_t MAX_NEWS_ITEMS = MAX_RECENT_NEWS_ITEMS + MAX_OLD_NEWS_ITEMS; +struct NewsItemQueue +{ + NewsItem* At(int32_t index); + bool IsEmpty() const; + void Init(); + uint16_t IncrementTicks(); + NewsItem& Current() { return Recent[0]; } + const NewsItem& Current() const { return Recent[0]; } + NewsItem& Oldest() { return Old[0]; } + const NewsItem& Oldest() const { return Old[0]; } + bool IsCurrentOld() const; + void MoveCurrentToOld(); + NewsItem* FirstOpenSlot(); + + template void ForeachRecentNews(Predicate&& p) + { + for (auto& newsItem : Recent) + { + if (newsItem.IsEmpty()) + break; + p(newsItem); + } + } + + template void ForeachOldNews(Predicate&& p) + { + for (auto& newsItem : Old) + { + if (newsItem.IsEmpty()) + break; + p(newsItem); + } + } + +private: + int32_t RemoveTime() const; + void AppendToOld(NewsItem& item); + + NewsItem Recent[MAX_RECENT_NEWS_ITEMS]; + NewsItem Old[MAX_OLD_NEWS_ITEMS]; +}; + extern const uint8_t news_type_properties[10]; void news_item_init_queue(); From d64b3bb15274ca2e0e7cd61dc0e8f52b05a4b743 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Mon, 11 May 2020 00:32:14 -0300 Subject: [PATCH 07/16] Format NewsItem.h --- src/openrct2/management/NewsItem.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index db434ddcc0..e41d20e2e8 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -69,10 +69,22 @@ struct NewsItemQueue bool IsEmpty() const; void Init(); uint16_t IncrementTicks(); - NewsItem& Current() { return Recent[0]; } - const NewsItem& Current() const { return Recent[0]; } - NewsItem& Oldest() { return Old[0]; } - const NewsItem& Oldest() const { return Old[0]; } + NewsItem& Current() + { + return Recent[0]; + } + const NewsItem& Current() const + { + return Recent[0]; + } + NewsItem& Oldest() + { + return Old[0]; + } + const NewsItem& Oldest() const + { + return Old[0]; + } bool IsCurrentOld() const; void MoveCurrentToOld(); NewsItem* FirstOpenSlot(); From a88f02fdb2ec9b039c31b52614143e761cc1906e Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Mon, 11 May 2020 00:38:01 -0300 Subject: [PATCH 08/16] Create operator[] in NewsItemQueue --- src/openrct2/management/NewsItem.cpp | 15 ++++++++++----- src/openrct2/management/NewsItem.h | 5 ++++- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct2/S6Exporter.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 10d5864d2c..97374b6ced 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -23,7 +23,7 @@ #include "../windows/Intent.h" #include "../world/Sprite.h" -static NewsItemQueue gNewsItems; +NewsItemQueue gNewsItems; /** rct2: 0x0097BE7C */ const uint8_t news_type_properties[] = { @@ -54,14 +54,19 @@ NewsItem* news_item_get(int32_t index) return gNewsItems.At(index); } +NewsItem& NewsItemQueue::operator[](size_t index) +{ + if (index < MAX_RECENT_NEWS_ITEMS) + return Recent[index]; + else + return Old[index - MAX_RECENT_NEWS_ITEMS]; +} + NewsItem* NewsItemQueue::At(int32_t index) { if (news_item_is_valid_idx(index)) { - if (index < MAX_RECENT_NEWS_ITEMS) - return &Recent[index]; - else - return &Old[index - MAX_RECENT_NEWS_ITEMS]; + return &(*this)[index]; } else { diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index e41d20e2e8..3f9bb24dc0 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -63,8 +63,11 @@ constexpr int32_t MAX_RECENT_NEWS_ITEMS = 11; constexpr int32_t MAX_OLD_NEWS_ITEMS = 50; constexpr int32_t MAX_NEWS_ITEMS = MAX_RECENT_NEWS_ITEMS + MAX_OLD_NEWS_ITEMS; +extern const uint8_t news_type_properties[10]; + struct NewsItemQueue { + NewsItem& operator[](size_t index); NewsItem* At(int32_t index); bool IsEmpty() const; void Init(); @@ -117,7 +120,7 @@ private: NewsItem Old[MAX_OLD_NEWS_ITEMS]; }; -extern const uint8_t news_type_properties[10]; +extern NewsItemQueue gNewsItems; void news_item_init_queue(); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index bfc80418b5..ba7dd3b95e 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2531,7 +2531,7 @@ private: for (size_t i = 0; i < RCT12_MAX_NEWS_ITEMS; i++) { const rct12_news_item* src = &_s4.messages[i]; - NewsItem* dst = news_item_get(static_cast(i)); + NewsItem* dst = &gNewsItems[i]; dst->Type = src->Type; dst->Flags = src->Flags; diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index ebb676e20e..0479a8a152 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -399,7 +399,7 @@ void S6Exporter::Export() // News items for (size_t i = 0; i < RCT12_MAX_NEWS_ITEMS; i++) { - const NewsItem* src = news_item_get(static_cast(i)); + const NewsItem* src = &gNewsItems[i]; rct12_news_item* dst = &_s6.news_items[i]; dst->Type = src->Type; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 0f604d1d97..eed88c0408 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -419,7 +419,7 @@ public: for (size_t i = 0; i < RCT12_MAX_NEWS_ITEMS; i++) { const rct12_news_item* src = &_s6.news_items[i]; - NewsItem* dst = news_item_get(static_cast(i)); + NewsItem* dst = &gNewsItems[i]; if (src->Type < std::size(news_type_properties)) { dst->Type = src->Type; From ecdd35e334cc297cb74c15482091939b92540572 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Mon, 11 May 2020 00:43:50 -0300 Subject: [PATCH 09/16] Use MAX_RECENT_NEWS_ITEMS where feasible --- src/openrct2-ui/windows/News.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index 9a98f0e42d..4ad986f03b 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -238,7 +238,7 @@ static void window_news_scrollmousedown(rct_window* w, int32_t scrollIndex, cons if (buttonIndex != 0) { - w->news.var_480 = i - 11; + w->news.var_480 = i - MAX_RECENT_NEWS_ITEMS; w->news.var_482 = buttonIndex; w->news.var_484 = 4; w->Invalidate(); @@ -301,7 +301,7 @@ static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32 press = 0; if (w->news.var_480 != -1) { - const uint8_t idx = 11 + w->news.var_480; + const uint8_t idx = MAX_RECENT_NEWS_ITEMS + w->news.var_480; news_item_is_valid_idx(idx); if (i == idx && w->news.var_482 == 1) press = INSET_RECT_FLAG_BORDER_INSET; @@ -378,7 +378,7 @@ static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32 press = 0; if (w->news.var_480 != -1) { - const uint8_t idx = 11 + w->news.var_480; + const uint8_t idx = MAX_RECENT_NEWS_ITEMS + w->news.var_480; news_item_is_valid_idx(idx); if (i == idx && w->news.var_482 == 2) press = 0x20; From efa92a28fa964f7e7df6053fa9b3553875680264 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Mon, 25 May 2020 11:53:05 -0300 Subject: [PATCH 10/16] Merge NEWS_ITEM_HISTORY_START variable --- src/openrct2-ui/windows/News.cpp | 14 +++++++------- src/openrct2/management/NewsItem.cpp | 6 +++--- src/openrct2/management/NewsItem.h | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/openrct2-ui/windows/News.cpp b/src/openrct2-ui/windows/News.cpp index 4ad986f03b..0de33f3f4f 100644 --- a/src/openrct2-ui/windows/News.cpp +++ b/src/openrct2-ui/windows/News.cpp @@ -150,7 +150,7 @@ static void window_news_update(rct_window* w) j = w->news.var_480; w->news.var_480 = -1; - for (i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) + for (i = NEWS_ITEM_HISTORY_START; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) return; @@ -188,7 +188,7 @@ static void window_news_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_ int32_t itemHeight = window_news_get_item_height(); *height = 0; - for (int32_t i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) + for (int32_t i = NEWS_ITEM_HISTORY_START; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) break; @@ -208,7 +208,7 @@ static void window_news_scrollmousedown(rct_window* w, int32_t scrollIndex, cons buttonIndex = 0; auto mutableScreenCoords = screenCoords; - for (i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) + for (i = NEWS_ITEM_HISTORY_START; i < MAX_NEWS_ITEMS; i++) { if (news_item_is_empty(i)) break; @@ -238,7 +238,7 @@ static void window_news_scrollmousedown(rct_window* w, int32_t scrollIndex, cons if (buttonIndex != 0) { - w->news.var_480 = i - MAX_RECENT_NEWS_ITEMS; + w->news.var_480 = i - NEWS_ITEM_HISTORY_START; w->news.var_482 = buttonIndex; w->news.var_484 = 4; w->Invalidate(); @@ -266,7 +266,7 @@ static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32 int32_t i, x, y, yy, press; y = 0; - for (i = MAX_RECENT_NEWS_ITEMS; i < MAX_NEWS_ITEMS; i++) + for (i = NEWS_ITEM_HISTORY_START; i < MAX_NEWS_ITEMS; i++) { NewsItem* const newsItem = news_item_get(i); if (news_item_is_empty(i)) @@ -301,7 +301,7 @@ static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32 press = 0; if (w->news.var_480 != -1) { - const uint8_t idx = MAX_RECENT_NEWS_ITEMS + w->news.var_480; + const uint8_t idx = NEWS_ITEM_HISTORY_START + w->news.var_480; news_item_is_valid_idx(idx); if (i == idx && w->news.var_482 == 1) press = INSET_RECT_FLAG_BORDER_INSET; @@ -378,7 +378,7 @@ static void window_news_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32 press = 0; if (w->news.var_480 != -1) { - const uint8_t idx = MAX_RECENT_NEWS_ITEMS + w->news.var_480; + const uint8_t idx = NEWS_ITEM_HISTORY_START + w->news.var_480; news_item_is_valid_idx(idx); if (i == idx && w->news.var_482 == 2) press = 0x20; diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 97374b6ced..8acb9f319a 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -56,10 +56,10 @@ NewsItem* news_item_get(int32_t index) NewsItem& NewsItemQueue::operator[](size_t index) { - if (index < MAX_RECENT_NEWS_ITEMS) + if (index < NEWS_ITEM_HISTORY_START) return Recent[index]; else - return Old[index - MAX_RECENT_NEWS_ITEMS]; + return Old[index - NEWS_ITEM_HISTORY_START]; } NewsItem* NewsItemQueue::At(int32_t index) @@ -187,7 +187,7 @@ void NewsItemQueue::MoveCurrentToOld() // Dequeue the current news item, shift news up memmove(Recent, Recent + 1, sizeof(NewsItem) * (std::size(Recent) - 1)); - Recent[MAX_RECENT_NEWS_ITEMS - 1].Type = NEWS_ITEM_NULL; + Recent[NEWS_ITEM_HISTORY_START - 1].Type = NEWS_ITEM_NULL; // Invalidate current news item bar auto intent = Intent(INTENT_ACTION_INVALIDATE_TICKER_NEWS); diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index 3f9bb24dc0..5b3c16058f 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -59,9 +59,9 @@ struct NewsItem } }; -constexpr int32_t MAX_RECENT_NEWS_ITEMS = 11; +constexpr int32_t NEWS_ITEM_HISTORY_START = 11; constexpr int32_t MAX_OLD_NEWS_ITEMS = 50; -constexpr int32_t MAX_NEWS_ITEMS = MAX_RECENT_NEWS_ITEMS + MAX_OLD_NEWS_ITEMS; +constexpr int32_t MAX_NEWS_ITEMS = NEWS_ITEM_HISTORY_START + MAX_OLD_NEWS_ITEMS; extern const uint8_t news_type_properties[10]; @@ -116,7 +116,7 @@ private: int32_t RemoveTime() const; void AppendToOld(NewsItem& item); - NewsItem Recent[MAX_RECENT_NEWS_ITEMS]; + NewsItem Recent[NEWS_ITEM_HISTORY_START]; NewsItem Old[MAX_OLD_NEWS_ITEMS]; }; From 4f698387f6fb9f031c1e4d1b504f360b434ebec2 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Mon, 25 May 2020 11:58:05 -0300 Subject: [PATCH 11/16] Move NewsItemQueue methods implementation to .cpp --- src/openrct2/management/NewsItem.cpp | 20 ++++++++++++++++++++ src/openrct2/management/NewsItem.h | 20 ++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 8acb9f319a..570a1f24e6 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -39,6 +39,26 @@ const uint8_t news_type_properties[] = { NEWS_TYPE_HAS_SUBJECT, // NEWS_ITEM_GRAPH }; +NewsItem& NewsItemQueue::Current() +{ + return Recent[0]; +} + +const NewsItem& NewsItemQueue::Current() const +{ + return Recent[0]; +} + +NewsItem& NewsItemQueue::Oldest() +{ + return Old[0]; +} + +const NewsItem& NewsItemQueue::Oldest() const +{ + return Old[0]; +} + bool news_item_is_valid_idx(int32_t index) { if (index >= MAX_NEWS_ITEMS) diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index 5b3c16058f..f6f545ac2e 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -72,22 +72,10 @@ struct NewsItemQueue bool IsEmpty() const; void Init(); uint16_t IncrementTicks(); - NewsItem& Current() - { - return Recent[0]; - } - const NewsItem& Current() const - { - return Recent[0]; - } - NewsItem& Oldest() - { - return Old[0]; - } - const NewsItem& Oldest() const - { - return Old[0]; - } + NewsItem& Current(); + const NewsItem& Current() const; + NewsItem& Oldest(); + const NewsItem& Oldest() const; bool IsCurrentOld() const; void MoveCurrentToOld(); NewsItem* FirstOpenSlot(); From b6d3868c9d5da3f1dbe2bc072eb0f569d066e6a3 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Mon, 25 May 2020 12:00:55 -0300 Subject: [PATCH 12/16] Rename FirstOpenSlot to FirstOpenOrCreateSlot --- src/openrct2/management/NewsItem.cpp | 6 +++--- src/openrct2/management/NewsItem.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 570a1f24e6..c481905bd3 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -329,7 +329,7 @@ std::optional news_item_get_subject_location(int32_t type, int32_t su return subjectLoc; } -NewsItem* NewsItemQueue::FirstOpenSlot() +NewsItem* NewsItemQueue::FirstOpenOrCreateSlot() { auto it = std::begin(Recent); for (; !it->IsEmpty();) @@ -358,7 +358,7 @@ NewsItem* news_item_add_to_queue(uint8_t type, rct_string_id string_id, uint32_t NewsItem* news_item_add_to_queue_raw(uint8_t type, const utf8* text, uint32_t assoc) { - NewsItem* newsItem = gNewsItems.FirstOpenSlot(); + NewsItem* newsItem = gNewsItems.FirstOpenOrCreateSlot(); newsItem->Type = type; newsItem->Flags = 0; newsItem->Assoc = assoc; @@ -494,7 +494,7 @@ void news_item_disable_news(uint8_t type, uint32_t assoc) void news_item_add_to_queue_custom(NewsItem* newNewsItem) { - NewsItem* newsItem = gNewsItems.FirstOpenSlot(); + NewsItem* newsItem = gNewsItems.FirstOpenOrCreateSlot(); *newsItem = *newNewsItem; newsItem++; newsItem->Type = NEWS_ITEM_NULL; diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index f6f545ac2e..ea3a56d1f4 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -78,7 +78,7 @@ struct NewsItemQueue const NewsItem& Oldest() const; bool IsCurrentOld() const; void MoveCurrentToOld(); - NewsItem* FirstOpenSlot(); + NewsItem* FirstOpenOrCreateSlot(); template void ForeachRecentNews(Predicate&& p) { From 502f11400e782bb6a0f6e633b0b74c8f6d777012 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sat, 30 May 2020 14:11:14 -0300 Subject: [PATCH 13/16] Add const version of NewsItemQueue::At --- src/openrct2/management/NewsItem.cpp | 5 +++++ src/openrct2/management/NewsItem.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index c481905bd3..bdaeecbc2b 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -83,6 +83,11 @@ NewsItem& NewsItemQueue::operator[](size_t index) } NewsItem* NewsItemQueue::At(int32_t index) +{ + return const_cast(const_cast(*this).At(index)); +} + +const NewsItem* NewsItemQueue::At(int32_t index) const { if (news_item_is_valid_idx(index)) { diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index ea3a56d1f4..d2ad07163a 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -69,6 +69,7 @@ struct NewsItemQueue { NewsItem& operator[](size_t index); NewsItem* At(int32_t index); + const NewsItem* At(int32_t index) const; bool IsEmpty() const; void Init(); uint16_t IncrementTicks(); From b30c76eee9e64f2c1a6516f535180b154502e457 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sat, 30 May 2020 14:29:51 -0300 Subject: [PATCH 14/16] Renaming 'old' to 'archived' in NewsItem --- src/openrct2/management/NewsItem.cpp | 34 ++++++++++++++-------------- src/openrct2/management/NewsItem.h | 16 ++++++------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index bdaeecbc2b..3d19c090a5 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -51,12 +51,12 @@ const NewsItem& NewsItemQueue::Current() const NewsItem& NewsItemQueue::Oldest() { - return Old[0]; + return Archived[0]; } const NewsItem& NewsItemQueue::Oldest() const { - return Old[0]; + return Archived[0]; } bool news_item_is_valid_idx(int32_t index) @@ -79,7 +79,7 @@ NewsItem& NewsItemQueue::operator[](size_t index) if (index < NEWS_ITEM_HISTORY_START) return Recent[index]; else - return Old[index - NEWS_ITEM_HISTORY_START]; + return Archived[index - NEWS_ITEM_HISTORY_START]; } NewsItem* NewsItemQueue::At(int32_t index) @@ -164,7 +164,7 @@ int32_t NewsItemQueue::RemoveTime() const return 320; } -bool NewsItemQueue::IsCurrentOld() const +bool NewsItemQueue::CurrentShouldBeArchived() const { return Current().Ticks >= RemoveTime(); } @@ -186,8 +186,8 @@ void news_item_update_current() news_item_tick_current(); // Removal of current news item - if (gNewsItems.IsCurrentOld()) - gNewsItems.MoveCurrentToOld(); + if (gNewsItems.CurrentShouldBeArchived()) + gNewsItems.ArchiveCurrent(); } /** @@ -196,16 +196,16 @@ void news_item_update_current() */ void news_item_close_current() { - gNewsItems.MoveCurrentToOld(); + gNewsItems.ArchiveCurrent(); } -void NewsItemQueue::MoveCurrentToOld() +void NewsItemQueue::ArchiveCurrent() { // Check if there is a current message if (IsEmpty()) return; - AppendToOld(Current()); + AppendToArchive(Current()); // Invalidate the news window window_invalidate_by_class(WC_RECENT_NEWS); @@ -223,21 +223,21 @@ void NewsItemQueue::MoveCurrentToOld() * Finds a spare history slot or replaces an existing one if there are no spare * slots available. */ -void NewsItemQueue::AppendToOld(NewsItem& item) +void NewsItemQueue::AppendToArchive(NewsItem& item) { - auto it = std::find_if(std::begin(Old), std::end(Old), [](const auto& newsItem) { return newsItem.IsEmpty(); }); - if (it != std::end(Old)) + auto it = std::find_if(std::begin(Archived), std::end(Archived), [](const auto& newsItem) { return newsItem.IsEmpty(); }); + if (it != std::end(Archived)) { *it = item; ++it; - if (it != std::end(Old)) + if (it != std::end(Archived)) it->Type = NEWS_ITEM_NULL; return; } // Dequeue the first history news item, shift history up - memmove(Old, Old + 1, sizeof(NewsItem) * (std::size(Old) - 1)); - Old[MAX_OLD_NEWS_ITEMS - 1] = item; + memmove(Archived, Archived + 1, sizeof(NewsItem) * (std::size(Archived) - 1)); + Archived[MAX_NEWS_ITEMS_ARCHIVE - 1] = item; } /** @@ -340,7 +340,7 @@ NewsItem* NewsItemQueue::FirstOpenOrCreateSlot() for (; !it->IsEmpty();) { if (it + 2 >= std::end(Recent)) - MoveCurrentToOld(); + ArchiveCurrent(); else it++; } @@ -488,7 +488,7 @@ void news_item_disable_news(uint8_t type, uint32_t assoc) } }); - gNewsItems.ForeachOldNews([type, assoc](auto& newsItem) { + gNewsItems.ForeachArchivedNews([type, assoc](auto& newsItem) { if (type == newsItem.Type && assoc == newsItem.Assoc) { newsItem.Flags |= NEWS_FLAG_HAS_BUTTON; diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index d2ad07163a..d320de6575 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -60,8 +60,8 @@ struct NewsItem }; constexpr int32_t NEWS_ITEM_HISTORY_START = 11; -constexpr int32_t MAX_OLD_NEWS_ITEMS = 50; -constexpr int32_t MAX_NEWS_ITEMS = NEWS_ITEM_HISTORY_START + MAX_OLD_NEWS_ITEMS; +constexpr int32_t MAX_NEWS_ITEMS_ARCHIVE = 50; +constexpr int32_t MAX_NEWS_ITEMS = NEWS_ITEM_HISTORY_START + MAX_NEWS_ITEMS_ARCHIVE; extern const uint8_t news_type_properties[10]; @@ -77,8 +77,8 @@ struct NewsItemQueue const NewsItem& Current() const; NewsItem& Oldest(); const NewsItem& Oldest() const; - bool IsCurrentOld() const; - void MoveCurrentToOld(); + bool CurrentShouldBeArchived() const; + void ArchiveCurrent(); NewsItem* FirstOpenOrCreateSlot(); template void ForeachRecentNews(Predicate&& p) @@ -91,9 +91,9 @@ struct NewsItemQueue } } - template void ForeachOldNews(Predicate&& p) + template void ForeachArchivedNews(Predicate&& p) { - for (auto& newsItem : Old) + for (auto& newsItem : Archived) { if (newsItem.IsEmpty()) break; @@ -103,10 +103,10 @@ struct NewsItemQueue private: int32_t RemoveTime() const; - void AppendToOld(NewsItem& item); + void AppendToArchive(NewsItem& item); NewsItem Recent[NEWS_ITEM_HISTORY_START]; - NewsItem Old[MAX_OLD_NEWS_ITEMS]; + NewsItem Archived[MAX_NEWS_ITEMS_ARCHIVE]; }; extern NewsItemQueue gNewsItems; From b519247bad7530ae68849af2fa170e9d2346ee81 Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sat, 30 May 2020 14:31:54 -0300 Subject: [PATCH 15/16] Rename FirstOpenOrCreateSlot to FirstOpenOrNewSlot --- src/openrct2/management/NewsItem.cpp | 6 +++--- src/openrct2/management/NewsItem.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 3d19c090a5..9b788c37fc 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -334,7 +334,7 @@ std::optional news_item_get_subject_location(int32_t type, int32_t su return subjectLoc; } -NewsItem* NewsItemQueue::FirstOpenOrCreateSlot() +NewsItem* NewsItemQueue::FirstOpenOrNewSlot() { auto it = std::begin(Recent); for (; !it->IsEmpty();) @@ -363,7 +363,7 @@ NewsItem* news_item_add_to_queue(uint8_t type, rct_string_id string_id, uint32_t NewsItem* news_item_add_to_queue_raw(uint8_t type, const utf8* text, uint32_t assoc) { - NewsItem* newsItem = gNewsItems.FirstOpenOrCreateSlot(); + NewsItem* newsItem = gNewsItems.FirstOpenOrNewSlot(); newsItem->Type = type; newsItem->Flags = 0; newsItem->Assoc = assoc; @@ -499,7 +499,7 @@ void news_item_disable_news(uint8_t type, uint32_t assoc) void news_item_add_to_queue_custom(NewsItem* newNewsItem) { - NewsItem* newsItem = gNewsItems.FirstOpenOrCreateSlot(); + NewsItem* newsItem = gNewsItems.FirstOpenOrNewSlot(); *newsItem = *newNewsItem; newsItem++; newsItem->Type = NEWS_ITEM_NULL; diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index d320de6575..e5a49e7778 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -79,7 +79,7 @@ struct NewsItemQueue const NewsItem& Oldest() const; bool CurrentShouldBeArchived() const; void ArchiveCurrent(); - NewsItem* FirstOpenOrCreateSlot(); + NewsItem* FirstOpenOrNewSlot(); template void ForeachRecentNews(Predicate&& p) { From a94fc10c77bd1cd637cb63b66d18071e780e676d Mon Sep 17 00:00:00 2001 From: hdpoliveira Date: Sat, 30 May 2020 14:37:58 -0300 Subject: [PATCH 16/16] Add const version of NewsItemQueue::operator[] --- src/openrct2/management/NewsItem.cpp | 5 +++++ src/openrct2/management/NewsItem.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 9b788c37fc..cd264c428c 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -75,6 +75,11 @@ NewsItem* news_item_get(int32_t index) } NewsItem& NewsItemQueue::operator[](size_t index) +{ + return const_cast(const_cast(*this)[index]); +} + +const NewsItem& NewsItemQueue::operator[](size_t index) const { if (index < NEWS_ITEM_HISTORY_START) return Recent[index]; diff --git a/src/openrct2/management/NewsItem.h b/src/openrct2/management/NewsItem.h index e5a49e7778..3623bac716 100644 --- a/src/openrct2/management/NewsItem.h +++ b/src/openrct2/management/NewsItem.h @@ -68,6 +68,7 @@ extern const uint8_t news_type_properties[10]; struct NewsItemQueue { NewsItem& operator[](size_t index); + const NewsItem& operator[](size_t index) const; NewsItem* At(int32_t index); const NewsItem* At(int32_t index) const; bool IsEmpty() const;