add some news item functions

This commit is contained in:
IntelOrca 2014-04-04 21:46:26 +01:00
parent 88f517f907
commit 5909a17dbc
8 changed files with 178 additions and 5 deletions

View file

@ -85,7 +85,9 @@
#define RCT2_ADDRESS_VIEWPORT_LIST 0x014234BC
#define RCT2_ADDRESS_NEW_VIEWPORT_PTR 0x01423570
#define RCT2_ADDRESS_OS_TIME_MONTH 0x01423A04
#define RCT2_ADDRESS_OS_TOTALPHYS 0x01423B5C
#define RCT2_ADDRESS_OS_TIME_DAY 0x01424304
static void RCT2_CALLPROC_EBPSAFE(int address)
{

View file

@ -159,4 +159,17 @@ void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, i
void gfx_invalidate_screen()
{
RCT2_CALLPROC_EBPSAFE(0x006ED7E5);
}
/**
*
* rct2: 0x006E732D
* left (ax)
* top (bx)
* right (dx)
* bottom (bp)
*/
void gfx_set_dirty_blocks(int left, int top, int right, int bottom)
{
RCT2_CALLPROC_X(0x006E732D, left, top, 0, right, 0, 0, bottom);
}

View file

@ -66,7 +66,7 @@ int gfx_get_string_width(char *buffer);
int clip_text(char *buffer, int width);
void gfx_fill_rect_inset(rct_drawpixelinfo *dpi, short left, short top, short right, short bottom, int colour, short _si);
void gfx_set_dirty_blocks(short left, short top, short right, short bottom);
void gfx_set_dirty_blocks(int left, int top, int right, int bottom);
void gfx_draw_dirty_blocks();
void gfx_redraw_screen_rect(short left, short top, short right, short bottom);
void gfx_invalidate_screen();

View file

@ -21,6 +21,7 @@
#include "addresses.h"
#include "news_item.h"
#include "rct2.h"
#include "window.h"
/**
*
@ -37,4 +38,123 @@ void news_item_init_queue()
RCT2_ADDRESS(0x01358750, uint8)[i] = 0;
RCT2_CALLPROC_EBPSAFE(0x0066BB79); // window_game_bottom_toolbar_invalidate_news_item();
}
/**
*
* rct2: 0x0066E252
*/
void news_item_update_current()
{
int _ebp;
short ax, bx, remove_time;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
// get_system_time();
ax = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, sint16);
bx = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, sint16);
if (bx != RCT2_GLOBAL(0x009DEA6B, sint16)) {
bx--;
if (bx == 0)
bx = 12;
if (bx != RCT2_GLOBAL(0x009DEA6B, sint16) || ax == 1) {
// loc_66E2AE
RCT2_GLOBAL(0x013573DC, sint32) = 10000;
if (RCT2_GLOBAL(0x013573DC, sint32) >= 0)
RCT2_GLOBAL(0x013573DC, sint32) = -RCT2_GLOBAL(0x013573DC, sint32);
}
} else {
if (ax != RCT2_GLOBAL(0x009DEA69, sint16)) {
ax--;
if (ax != RCT2_GLOBAL(0x009DEA69, sint16)) {
// loc_66E2AE
RCT2_GLOBAL(0x013573DC, sint32) = 10000;
if (RCT2_GLOBAL(0x013573DC, sint32) >= 0)
RCT2_GLOBAL(0x013573DC, sint32) = -RCT2_GLOBAL(0x013573DC, sint32);
}
}
}
RCT2_GLOBAL(0x009DEA69, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, sint16);
RCT2_GLOBAL(0x009DEA6B, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, sint16);
// Check if there is a current news item
if (newsItems[0].type == 0)
return;
RCT2_CALLPROC_EBPSAFE(0x0066BB79); // window_game_bottom_toolbar_invalidate_news_item();
// Update the current news item
newsItems[0].ticks++;
if (newsItems[0].ticks == 1 && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1)) {
// Play sound
sound_play_panned(39, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2);
}
// Removal of current news item
remove_time = 320;
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();
}
/**
*
* rct2: 0x0066E377
*/
void news_item_close_current()
{
int i;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
// Check if there is a current message
if (newsItems[0].type == NEWS_ITEM_NULL)
return;
// Find an available history news item slot for current message
i = news_item_get_new_history_slot();
// Set the history news item slot to the current news item
newsItems[i] = newsItems[0];
// Set the end of the end of the history list
if (i < 60)
newsItems[i + 1].type = NEWS_ITEM_NULL;
// Invalidate the news window
window_invalidate_by_id(WC_RECENT_NEWS, 0);
// Dequeue the current news item, shift news up
for (i = 0; i < 10; i++)
newsItems[i] = newsItems[i + 1];
newsItems[10].type = NEWS_ITEM_NULL;
// Invalidate current news item bar
RCT2_CALLPROC_EBPSAFE(0x0066BB79); // window_game_bottom_toolbar_invalidate_news_item();
}
/**
* Finds a spare history slot or replaces an existing one if there are no spare
* slots available.
*/
int news_item_get_new_history_slot()
{
int i;
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
// Find an available history news item slot
for (i = 11; i < 61; i++)
if (newsItems[i].type == NEWS_ITEM_NULL)
return i;
// Dequeue the first history news item, shift history up
for (i = 11; i < 60; i++)
newsItems[i] = newsItems[i + 1];
return 60;
}

View file

@ -54,5 +54,6 @@ typedef struct {
} rct_news_item;
void news_item_init_queue();
void news_item_close_current();
#endif

View file

@ -105,7 +105,7 @@ void rct2_init()
osinterface_init();
RCT2_CALLPROC_EBPSAFE(0x006BA8E0); // init_audio();
RCT2_CALLPROC_EBPSAFE(0x006E6EAC); // viewport_init_all();
RCT2_CALLPROC_EBPSAFE(0x0066DF32); // news_item_init_queue()
news_item_init_queue();
RCT2_CALLPROC_EBPSAFE(0x006C45E7); // get local time
RCT2_CALLPROC_EBPSAFE(0x00667104);
RCT2_CALLPROC_EBPSAFE(0x006C4209);

View file

@ -20,6 +20,7 @@
#include "addresses.h"
#include "audio.h"
#include "gfx.h"
#include "rct2.h"
#include "widget.h"
#include "window.h"
@ -193,10 +194,45 @@ rct_window *window_find_by_id(rct_windowclass cls, rct_windownumber number)
*/
void window_invalidate(rct_window *window)
{
RCT2_CALLPROC_X(0x006EB31A, 0, 0, 0, 0, window, 0, 0);
if (window != NULL)
gfx_set_dirty_blocks(window->x, window->y, window->x + window->width, window->y + window->height);
}
// if (window != NULL)
// gfx_set_dirty_blocks(window->x, window->y, window->x + window->width, window->y + window->height);
/**
*
* rct2: 0x006EC3AC
*
* @param cls (ax)
* @param number (bx)
*/
void window_invalidate_by_id(uint16 cls, rct_windownumber number)
{
rct_window* w;
rct_widget* widget;
uint8 widgetIndex;
if (cls & 0x80) {
widgetIndex = cls >> 8;
cls &= 0x7F;
for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++) {
if (w->classification == cls && w->number == number) {
widget = &w->widgets[widgetIndex];
if (widget->left != -2) {
gfx_set_dirty_blocks(w->x + widget->left, w->y + widget->top,
w->x + widget->right + 1, w->y + widget->bottom + 1);
}
}
}
} else if (cls & 0x40) {
cls &= 0xBF;
for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++)
if (w->classification == cls)
window_invalidate(w);
} else {
for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++)
if (w->classification == cls && w->number == number)
window_invalidate(w);
}
}
/**

View file

@ -271,6 +271,7 @@ rct_window *window_create(int x, int y, int width, int height, uint32 *event_han
void window_close(rct_window *window);
rct_window *window_find_by_id(rct_windowclass cls, rct_windownumber number);
void window_invalidate(rct_window *window);
void window_invalidate_by_id(uint16 cls, rct_windownumber number);
void window_init_scroll_widgets(rct_window *w);
int window_get_scroll_data_index(rct_window *w, int widget_index);