Merge pull request #1671 from janisozaur/develop

Refactor rct_news_item
This commit is contained in:
Duncan 2015-07-25 10:39:41 +01:00
commit 94b04c011c
5 changed files with 132 additions and 68 deletions

View File

@ -28,11 +28,42 @@
#include "../world/sprite.h" #include "../world/sprite.h"
#include "news_item.h" #include "news_item.h"
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item); rct_news_item *gNewsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
void window_game_bottom_toolbar_invalidate_news_item(); void window_game_bottom_toolbar_invalidate_news_item();
static int news_item_get_new_history_slot(); static int news_item_get_new_history_slot();
#define MAX_NEWS 60
bool news_item_is_valid_idx(const uint8 idx)
{
if (idx > MAX_NEWS)
{
log_error("Tried to get news item past MAX_NEWS.");
return false;
}
return true;
}
rct_news_item *news_item_get(const uint8 idx)
{
if (news_item_is_valid_idx(idx))
{
return &gNewsItems[idx];
} else {
return NULL;
}
}
bool news_item_is_empty(const uint8 idx)
{
return news_item_get(idx)->type == NEWS_ITEM_NULL;
}
bool news_item_is_queue_empty()
{
return news_item_is_empty(0);
}
/** /**
* *
* rct2: 0x0066DF32 * rct2: 0x0066DF32
@ -40,16 +71,41 @@ static int news_item_get_new_history_slot();
void news_item_init_queue() void news_item_init_queue()
{ {
int i; int i;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
newsItems[0].type = NEWS_ITEM_NULL; news_item_get(0)->type = NEWS_ITEM_NULL;
newsItems[11].type = NEWS_ITEM_NULL; news_item_get(11)->type = NEWS_ITEM_NULL;
// Throttles for warning types (PEEP_*_WARNING)
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
RCT2_ADDRESS(0x01358750, uint8)[i] = 0; RCT2_ADDRESS(0x01358750, uint8)[i] = 0;
window_game_bottom_toolbar_invalidate_news_item(); window_game_bottom_toolbar_invalidate_news_item();
} }
static void news_item_tick_current()
{
int ticks;
ticks = news_item_get(0)->ticks++;
if (ticks == 1 && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1)) {
// Play sound
sound_play_panned(SOUND_NEWS_ITEM, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2, 0, 0, 0);
}
}
static bool news_item_is_current_old()
{
int remove_time = 320;
if (!news_item_is_empty(5) &&
!news_item_is_empty(4) &&
!news_item_is_empty(3) &&
!news_item_is_empty(2))
remove_time = 256;
if (news_item_get(0)->ticks >= remove_time)
return true;
return false;
}
/** /**
* *
* rct2: 0x0066E252 * rct2: 0x0066E252
@ -57,7 +113,6 @@ void news_item_init_queue()
void news_item_update_current() void news_item_update_current()
{ {
short ax, bx, remove_time; short ax, bx, remove_time;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
get_system_time(); get_system_time();
@ -91,27 +146,16 @@ void news_item_update_current()
RCT2_GLOBAL(0x009DEA6B, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, sint16); RCT2_GLOBAL(0x009DEA6B, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, sint16);
// Check if there is a current news item // Check if there is a current news item
if (newsItems[0].type == 0) if (news_item_is_queue_empty())
return; return;
window_game_bottom_toolbar_invalidate_news_item(); window_game_bottom_toolbar_invalidate_news_item();
// Update the current news item // Update the current news item
newsItems[0].ticks++; news_item_tick_current();
if (newsItems[0].ticks == 1 && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1)) {
// Play sound
sound_play_panned(SOUND_NEWS_ITEM, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2, 0, 0, 0);
}
// Removal of current news item // Removal of current news item
remove_time = 320; if (news_item_is_current_old())
if (newsItems[2].type != 0 &&
newsItems[3].type != 0 &&
newsItems[4].type != 0 &&
newsItems[5].type != 0)
remove_time = 256;
if (newsItems[0].ticks >= remove_time)
news_item_close_current(); news_item_close_current();
} }
@ -125,7 +169,7 @@ void news_item_close_current()
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item); rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
// Check if there is a current message // Check if there is a current message
if (newsItems[0].type == NEWS_ITEM_NULL) if (news_item_is_queue_empty())
return; return;
// Find an available history news item slot for current message // Find an available history news item slot for current message
@ -135,7 +179,7 @@ void news_item_close_current()
newsItems[i] = newsItems[0]; newsItems[i] = newsItems[0];
// Set the end of the end of the history list // Set the end of the end of the history list
if (i < 60) if (i < MAX_NEWS)
newsItems[i + 1].type = NEWS_ITEM_NULL; newsItems[i + 1].type = NEWS_ITEM_NULL;
// Invalidate the news window // Invalidate the news window
@ -150,6 +194,15 @@ void news_item_close_current()
window_game_bottom_toolbar_invalidate_news_item(); window_game_bottom_toolbar_invalidate_news_item();
} }
static void news_item_shift_history_up()
{
const int history_idx = 11;
rct_news_item *history_start = news_item_get(history_idx);
const size_t count = sizeof(rct_news_item) * (MAX_NEWS - 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 * Finds a spare history slot or replaces an existing one if there are no spare
* slots available. * slots available.
@ -157,17 +210,15 @@ void news_item_close_current()
static int news_item_get_new_history_slot() static int news_item_get_new_history_slot()
{ {
int i; int i;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
// Find an available history news item slot // Find an available history news item slot
for (i = 11; i < 61; i++) for (i = 11; i <= MAX_NEWS; i++)
if (newsItems[i].type == NEWS_ITEM_NULL) if (news_item_is_empty(i))
return i; return i;
// Dequeue the first history news item, shift history up // Dequeue the first history news item, shift history up
for (i = 11; i < 60; i++) news_item_shift_history_up();
newsItems[i] = newsItems[i + 1]; return MAX_NEWS;
return 60;
} }
/** /**
@ -264,7 +315,7 @@ void news_item_add_to_queue_raw(uint8 type, const char *text, uint32 assoc)
// find first open slot // find first open slot
while (newsItem->type != NEWS_ITEM_NULL) { while (newsItem->type != NEWS_ITEM_NULL) {
if (newsItem + 1 >= (rct_news_item*)0x13CB1CC) if (newsItem + 1 >= (rct_news_item*)0x13CB1CC) // &news_list[10]
news_item_close_current(); news_item_close_current();
else else
newsItem++; newsItem++;
@ -358,24 +409,36 @@ void news_item_open_subject(int type, int subject)
* rct2: 0x0066E407 * rct2: 0x0066E407
*/ */
void news_item_disable_news(uint8 type, uint32 assoc) { void news_item_disable_news(uint8 type, uint32 assoc) {
rct_news_item* newsItem = newsItems; // TODO: write test invalidating windows
while (newsItem->type != NEWS_ITEM_NULL) { int i;
for (i = 0; i < 11; i++)
{
if (!news_item_is_empty(i))
{
rct_news_item * const newsItem;
if (type == newsItem->type && assoc == newsItem->assoc) { if (type == newsItem->type && assoc == newsItem->assoc) {
newsItem->flags |= 0x1; newsItem->flags |= 0x1;
if (newsItem == RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)) { if (i == 0) {
window_game_bottom_toolbar_invalidate_news_item(); window_game_bottom_toolbar_invalidate_news_item();
} }
} }
newsItem++; } else {
break;
}
} }
newsItem = &newsItems[11]; //0x13CB2D8 for (i = 11; i <= MAX_NEWS; i++)
while (newsItem->type != NEWS_ITEM_NULL) { {
if (!news_item_is_empty(i))
{
rct_news_item * const newsItem = news_item_get(i);
if (type == newsItem->type && assoc == newsItem->assoc) { if (type == newsItem->type && assoc == newsItem->assoc) {
newsItem->flags |= 0x1; newsItem->flags |= 0x1;
window_invalidate_by_class(WC_RECENT_NEWS); window_invalidate_by_class(WC_RECENT_NEWS);
} }
newsItem++; } else {
break;
}
} }
} }

View File

@ -60,5 +60,9 @@ void news_item_add_to_queue(uint8 type, rct_string_id string_id, uint32 assoc);
void news_item_add_to_queue_raw(uint8 type, const char *text, uint32 assoc); void news_item_add_to_queue_raw(uint8 type, const char *text, uint32 assoc);
void news_item_open_subject(int type, int subject); void news_item_open_subject(int type, int subject);
void news_item_disable_news(uint8 type, uint32 assoc); void news_item_disable_news(uint8 type, uint32 assoc);
rct_news_item *news_item_get(const uint8 idx);
bool news_item_is_empty(const uint8 idx);
bool news_item_is_queue_empty();
bool news_item_is_valid_idx(const uint8 idx);
#endif #endif

View File

@ -557,7 +557,7 @@ enum {
#define GET_PEEP(sprite_index) &(g_sprite_list[sprite_index].peep) #define GET_PEEP(sprite_index) &(g_sprite_list[sprite_index].peep)
/** /**
* Helper macro loop for enumerating through all the non null rides. To avoid needing a end loop counterpart, statements are * Helper macro loop for enumerating through all the peeps. To avoid needing a end loop counterpart, statements are
* applied in tautology if statements. * applied in tautology if statements.
*/ */
#define FOR_ALL_PEEPS(sprite_index, peep) \ #define FOR_ALL_PEEPS(sprite_index, peep) \

View File

@ -182,15 +182,15 @@ static void window_game_bottom_toolbar_mouseup(rct_window *w, int widgetIndex)
news_item_close_current(); news_item_close_current();
break; break;
case WIDX_NEWS_SUBJECT: case WIDX_NEWS_SUBJECT:
newsItem = &(RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)[0]); newsItem = news_item_get(0);
news_item_open_subject(newsItem->type, newsItem->assoc); news_item_open_subject(newsItem->type, newsItem->assoc);
break; break;
case WIDX_NEWS_LOCATE: case WIDX_NEWS_LOCATE:
newsItem = &(RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)[0]); if (news_item_is_queue_empty())
if (newsItem->type == NEWS_ITEM_NULL)
break; break;
{ {
newsItem = news_item_get(0);
int x, y, z; int x, y, z;
int subject = newsItem->assoc; int subject = newsItem->assoc;
@ -268,12 +268,12 @@ static void window_game_bottom_toolbar_invalidate(rct_window *w)
window_game_bottom_toolbar_widgets[WIDX_LEFT_INSET].type = WWT_EMPTY; window_game_bottom_toolbar_widgets[WIDX_LEFT_INSET].type = WWT_EMPTY;
window_game_bottom_toolbar_widgets[WIDX_RIGHT_INSET].type = WWT_EMPTY; window_game_bottom_toolbar_widgets[WIDX_RIGHT_INSET].type = WWT_EMPTY;
newsItem = &(RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)[0]); if (news_item_is_queue_empty()) {
if (newsItem->type == 0) {
window_game_bottom_toolbar_widgets[WIDX_MIDDLE_INSET].type = WWT_EMPTY; window_game_bottom_toolbar_widgets[WIDX_MIDDLE_INSET].type = WWT_EMPTY;
window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].type = WWT_EMPTY; window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].type = WWT_EMPTY;
window_game_bottom_toolbar_widgets[WIDX_NEWS_LOCATE].type = WWT_EMPTY; window_game_bottom_toolbar_widgets[WIDX_NEWS_LOCATE].type = WWT_EMPTY;
} else { } else {
newsItem = news_item_get(0);
window_game_bottom_toolbar_widgets[WIDX_MIDDLE_INSET].type = WWT_25; window_game_bottom_toolbar_widgets[WIDX_MIDDLE_INSET].type = WWT_25;
window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].type = WWT_FLATBTN; window_game_bottom_toolbar_widgets[WIDX_NEWS_SUBJECT].type = WWT_FLATBTN;
window_game_bottom_toolbar_widgets[WIDX_NEWS_LOCATE].type = WWT_FLATBTN; window_game_bottom_toolbar_widgets[WIDX_NEWS_LOCATE].type = WWT_FLATBTN;
@ -320,7 +320,7 @@ static void window_game_bottom_toolbar_invalidate(rct_window *w)
void window_game_bottom_toolbar_invalidate_news_item() void window_game_bottom_toolbar_invalidate_news_item()
{ {
window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].type = window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET].type =
RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)[0].type == NEWS_ITEM_NULL ? WWT_EMPTY : WWT_IMGBTN; news_item_is_queue_empty() ? WWT_EMPTY : WWT_IMGBTN;
widget_invalidate_by_class(WC_BOTTOM_TOOLBAR, WIDX_MIDDLE_OUTSET); widget_invalidate_by_class(WC_BOTTOM_TOOLBAR, WIDX_MIDDLE_OUTSET);
} }
@ -353,7 +353,7 @@ static void window_game_bottom_toolbar_paint(rct_window *w, rct_drawpixelinfo *d
window_game_bottom_toolbar_draw_left_panel(dpi, w); window_game_bottom_toolbar_draw_left_panel(dpi, w);
window_game_bottom_toolbar_draw_right_panel(dpi, w); window_game_bottom_toolbar_draw_right_panel(dpi, w);
if (RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)[0].type != 0) if (!news_item_is_queue_empty())
window_game_bottom_toolbar_draw_news_item(dpi, w); window_game_bottom_toolbar_draw_news_item(dpi, w);
else if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8)) else if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8))
window_game_bottom_toolbar_draw_tutorial_text(dpi, w); window_game_bottom_toolbar_draw_tutorial_text(dpi, w);
@ -509,7 +509,7 @@ static void window_game_bottom_toolbar_draw_news_item(rct_drawpixelinfo *dpi, rc
rct_widget *middleOutsetWidget; rct_widget *middleOutsetWidget;
middleOutsetWidget = &window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET]; middleOutsetWidget = &window_game_bottom_toolbar_widgets[WIDX_MIDDLE_OUTSET];
newsItem = &(RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)[0]); newsItem = news_item_get(0);
// Current news item // Current news item
gfx_fill_rect_inset( gfx_fill_rect_inset(

View File

@ -140,7 +140,6 @@ static void window_news_mouseup(rct_window *w, int widgetIndex)
static void window_news_update(rct_window *w) static void window_news_update(rct_window *w)
{ {
int i, j, x, y, z; int i, j, x, y, z;
rct_news_item *newsItems;
if (w->news.var_480 == -1) if (w->news.var_480 == -1)
return; return;
@ -150,22 +149,22 @@ static void window_news_update(rct_window *w)
window_invalidate(w); window_invalidate(w);
sound_play_panned(SOUND_CLICK_2, w->x + (w->width / 2), 0, 0, 0); sound_play_panned(SOUND_CLICK_2, w->x + (w->width / 2), 0, 0, 0);
newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
j = w->news.var_480; j = w->news.var_480;
w->news.var_480 = -1; w->news.var_480 = -1;
for (i = 11; i < 61; i++) { for (i = 11; i < 61; i++) {
if (newsItems[i].type == NEWS_ITEM_NULL) if (news_item_is_empty(i))
return; return;
if (j == 0) { if (j == 0) {
if (newsItems[i].flags & 1) rct_news_item * const newsItem = news_item_get(i);
if (newsItem->flags & 1)
return; return;
if (w->news.var_482 == 1) { if (w->news.var_482 == 1) {
news_item_open_subject(newsItems[i].type, newsItems[i].assoc); news_item_open_subject(newsItem->type, newsItem->assoc);
return; return;
} }
else if (w->news.var_482 > 1) { else if (w->news.var_482 > 1) {
news_item_get_subject_location(newsItems[i].type, newsItems[i].assoc, &x, &y, &z); news_item_get_subject_location(newsItem->type, newsItem->assoc, &x, &y, &z);
if (x != SPRITE_LOCATION_NULL) if (x != SPRITE_LOCATION_NULL)
if ((w = window_get_main()) != NULL) if ((w = window_get_main()) != NULL)
window_scroll_to_location(w, x, y, z); window_scroll_to_location(w, x, y, z);
@ -183,11 +182,10 @@ static void window_news_update(rct_window *w)
static void window_news_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height) static void window_news_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height)
{ {
int i; int i;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
*height = 0; *height = 0;
for (i = 11; i < 61; i++) { for (i = 11; i < 61; i++) {
if (newsItems[i].type == NEWS_ITEM_NULL) if (news_item_is_empty(i))
break; break;
*height += 42; *height += 42;
@ -201,16 +199,15 @@ static void window_news_scrollgetsize(rct_window *w, int scrollIndex, int *width
static void window_news_scrollmousedown(rct_window *w, int scrollIndex, int x, int y) static void window_news_scrollmousedown(rct_window *w, int scrollIndex, int x, int y)
{ {
int i, buttonIndex; int i, buttonIndex;
rct_news_item *newsItems;
buttonIndex = 0; buttonIndex = 0;
newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
for (i = 11; i < 61; i++) { for (i = 11; i < 61; i++) {
if (newsItems[i].type == NEWS_ITEM_NULL) if (news_item_is_empty(i))
break; break;
if (y < 42) { if (y < 42) {
if (newsItems[i].flags & 1) { rct_news_item * const newsItem = news_item_get(i);
if (newsItem->flags & 1) {
buttonIndex = 0; buttonIndex = 0;
break; break;
} else if (y < 14) { } else if (y < 14) {
@ -223,12 +220,12 @@ static void window_news_scrollmousedown(rct_window *w, int scrollIndex, int x, i
buttonIndex = 0; buttonIndex = 0;
break; break;
} else if (x < 351) { } else if (x < 351) {
if (RCT2_ADDRESS(0x0097BE7C, uint8)[newsItems[i].type] & 2) { if (RCT2_ADDRESS(0x0097BE7C, uint8)[newsItem->type] & 2) {
buttonIndex = 1; buttonIndex = 1;
break; break;
} }
} else if (x < 376) { } else if (x < 376) {
if (RCT2_ADDRESS(0x0097BE7C, uint8)[newsItems[i].type] & 1) { if (RCT2_ADDRESS(0x0097BE7C, uint8)[newsItem->type] & 1) {
buttonIndex = 2; buttonIndex = 2;
break; break;
} }
@ -276,13 +273,11 @@ static void window_news_invalidate(rct_window *w)
static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex) static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
{ {
int i, x, y, yy, press; int i, x, y, yy, press;
rct_news_item *newsItems, *newsItem, *newsItem2;
y = 0; y = 0;
newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
for (i = 11; i < 61; i++) { for (i = 11; i < 61; i++) {
newsItem = &newsItems[i]; rct_news_item * const newsItem = news_item_get(i);
if (newsItem->type == NEWS_ITEM_NULL) if (news_item_is_empty(i))
break; break;
if (y >= dpi->y + dpi->height) if (y >= dpi->y + dpi->height)
break; break;
@ -313,8 +308,9 @@ static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int s
press = 0; press = 0;
if (w->news.var_480 != -1) { if (w->news.var_480 != -1) {
newsItem2 = &newsItems[11 + w->news.var_480]; const uint8 idx = 11 + w->news.var_480;
if (newsItem == newsItem2 && w->news.var_482 == 1) news_item_is_valid_idx(idx);
if (i == idx && w->news.var_482 == 1)
press = 0x20; press = 0x20;
} }
gfx_fill_rect_inset(dpi, x, yy, x + 23, yy + 23, w->colours[2], press); gfx_fill_rect_inset(dpi, x, yy, x + 23, yy + 23, w->colours[2], press);
@ -376,8 +372,9 @@ static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int s
press = 0; press = 0;
if (w->news.var_480 != -1) { if (w->news.var_480 != -1) {
newsItem2 = &newsItems[11 + w->news.var_480]; const uint8 idx = 11 + w->news.var_480;
if (newsItem == newsItem2 && w->news.var_482 == 2) news_item_is_valid_idx(idx);
if (i == idx && w->news.var_482 == 2)
press = 0x20; press = 0x20;
} }
gfx_fill_rect_inset(dpi, x, yy, x + 23, yy + 23, w->colours[2], press); gfx_fill_rect_inset(dpi, x, yy, x + 23, yy + 23, w->colours[2], press);
@ -386,4 +383,4 @@ static void window_news_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int s
y += 42; y += 42;
} }
} }