From 6b0ba5c6d098c874c1954cf21ef35e6ab3981fa1 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 19 Apr 2014 03:16:20 +0100 Subject: [PATCH] add ride list window --- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 3 + src/sprites.h | 44 +++++ src/strings.h | 23 +++ src/widget.c | 3 + src/window.c | 21 +++ src/window.h | 9 +- src/window_game_top_toolbar.c | 2 +- src/window_park.c | 9 +- src/window_ride_list.c | 290 ++++++++++++++++++++++++++++++ 10 files changed, 395 insertions(+), 10 deletions(-) create mode 100644 src/window_ride_list.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index bc7d2b5ba8..4b6c6a56ea 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -78,6 +78,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index c211d29799..f37cadcd0e 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -224,6 +224,9 @@ Windows + + Windows + diff --git a/src/sprites.h b/src/sprites.h index b23dd10b47..0286a6e71c 100644 --- a/src/sprites.h +++ b/src/sprites.h @@ -41,6 +41,7 @@ enum { SPR_CLOSED = 5179, SPR_OPEN = 5180, SPR_TESTING = 5181, + SPR_TOGGLE_OPEN_CLOSE = 5182, SPR_RIDE = 5187, SPR_TRACK_PEEP = 5188, @@ -78,6 +79,49 @@ enum { SPR_TAB_STATS_5 = SPR_TAB_STATS_0 + 5, SPR_TAB_STATS_6 = SPR_TAB_STATS_0 + 6, + SPR_TAB_SHOPS_AND_STALLS_0 = 5351, + SPR_TAB_SHOPS_AND_STALLS_1 = SPR_TAB_SHOPS_AND_STALLS_0 + 1, + SPR_TAB_SHOPS_AND_STALLS_2 = SPR_TAB_SHOPS_AND_STALLS_0 + 2, + SPR_TAB_SHOPS_AND_STALLS_3 = SPR_TAB_SHOPS_AND_STALLS_0 + 3, + SPR_TAB_SHOPS_AND_STALLS_4 = SPR_TAB_SHOPS_AND_STALLS_0 + 4, + SPR_TAB_SHOPS_AND_STALLS_5 = SPR_TAB_SHOPS_AND_STALLS_0 + 5, + SPR_TAB_SHOPS_AND_STALLS_6 = SPR_TAB_SHOPS_AND_STALLS_0 + 6, + SPR_TAB_SHOPS_AND_STALLS_7 = SPR_TAB_SHOPS_AND_STALLS_0 + 7, + SPR_TAB_SHOPS_AND_STALLS_8 = SPR_TAB_SHOPS_AND_STALLS_0 + 8, + SPR_TAB_SHOPS_AND_STALLS_9 = SPR_TAB_SHOPS_AND_STALLS_0 + 9, + SPR_TAB_SHOPS_AND_STALLS_10 = SPR_TAB_SHOPS_AND_STALLS_0 + 10, + SPR_TAB_SHOPS_AND_STALLS_11 = SPR_TAB_SHOPS_AND_STALLS_0 + 11, + SPR_TAB_SHOPS_AND_STALLS_12 = SPR_TAB_SHOPS_AND_STALLS_0 + 12, + SPR_TAB_SHOPS_AND_STALLS_13 = SPR_TAB_SHOPS_AND_STALLS_0 + 13, + SPR_TAB_SHOPS_AND_STALLS_14 = SPR_TAB_SHOPS_AND_STALLS_0 + 14, + SPR_TAB_SHOPS_AND_STALLS_15 = SPR_TAB_SHOPS_AND_STALLS_0 + 15, + + SPR_TAB_KIOSKS_AND_FACILITIES_0 = 5367, + SPR_TAB_KIOSKS_AND_FACILITIES_1 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 1, + SPR_TAB_KIOSKS_AND_FACILITIES_2 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 2, + SPR_TAB_KIOSKS_AND_FACILITIES_3 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 3, + SPR_TAB_KIOSKS_AND_FACILITIES_4 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 4, + SPR_TAB_KIOSKS_AND_FACILITIES_5 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 5, + SPR_TAB_KIOSKS_AND_FACILITIES_6 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 6, + SPR_TAB_KIOSKS_AND_FACILITIES_7 = SPR_TAB_KIOSKS_AND_FACILITIES_0 + 7, + + SPR_TAB_RIDE_0 = 5442, + SPR_TAB_RIDE_1 = SPR_TAB_RIDE_0 + 1, + SPR_TAB_RIDE_2 = SPR_TAB_RIDE_0 + 2, + SPR_TAB_RIDE_3 = SPR_TAB_RIDE_0 + 3, + SPR_TAB_RIDE_4 = SPR_TAB_RIDE_0 + 4, + SPR_TAB_RIDE_5 = SPR_TAB_RIDE_0 + 5, + SPR_TAB_RIDE_6 = SPR_TAB_RIDE_0 + 6, + SPR_TAB_RIDE_7 = SPR_TAB_RIDE_0 + 7, + SPR_TAB_RIDE_8 = SPR_TAB_RIDE_0 + 8, + SPR_TAB_RIDE_9 = SPR_TAB_RIDE_0 + 9, + SPR_TAB_RIDE_10 = SPR_TAB_RIDE_0 + 10, + SPR_TAB_RIDE_11 = SPR_TAB_RIDE_0 + 11, + SPR_TAB_RIDE_12 = SPR_TAB_RIDE_0 + 12, + SPR_TAB_RIDE_13 = SPR_TAB_RIDE_0 + 13, + SPR_TAB_RIDE_14 = SPR_TAB_RIDE_0 + 14, + SPR_TAB_RIDE_15 = SPR_TAB_RIDE_0 + 15, + SPR_AWARD_MOST_UNTIDY = 5469, SPR_MOST_TIDY = SPR_AWARD_MOST_UNTIDY + 1, SPR_BEST_ROLLERCOASTERS = SPR_AWARD_MOST_UNTIDY + 2, diff --git a/src/strings.h b/src/strings.h index 977d7b4bb1..b6137b8326 100644 --- a/src/strings.h +++ b/src/strings.h @@ -150,10 +150,15 @@ enum { STR_CANCEL = 972, STR_OK = 973, + STR_RIDES = 974, + STR_SHOPS_AND_STALLS = 975, + STR_RESTROOMS_AND_INFORMATION_KIOSKS = 976, + STR_RAISE_COST_AMOUNT = 984, STR_LOWER_COST_AMOUNT = 985, STR_COST_AMOUNT = 986, + STR_OPEN_OR_CLOSE_ALL_RIDES = 1009, STR_OPEN_OR_CLOSE_PARK_TIP = 1010, STR_CLOSE_PARK = 1013, @@ -200,6 +205,18 @@ enum { STR_GUESTS_FILTER_THINKING = STR_GUESTS_FILTER + 1, STR_GUESTS_FILTER_THINKING_ABOUT = STR_GUESTS_FILTER + 2, + STR_RIDE_LIST_INFORMATION_TYPE_TIP = 8144, + + STR_STATUS = 1826, + STR_POPULARITY = 1827, + STR_SATISFACTION = 1828, + STR_PROFIT = 1829, + STR_QUEUE_LENGTH = 1830, + STR_QUEUE_TIME = 1831, + STR_RELIABILITY = 1832, + STR_DOWN_TIME = 1833, + STR_GUESTS_FAVOURITE = 1834, + STR_NUM_GUESTS = 1846, STR_BUILD_RIDE_TIP = 1895, @@ -280,6 +297,8 @@ enum { STR_ENTER_NAME_INTO_SCENARIO_CHART = 2790, STR_COMPLETED_BY_WITH_COMPANY_VALUE = 2794, + STR_SORT = 2795, + STR_RIDE_LIST_SORT_TIP = 2796, STR_TOTAL_ADMISSIONS = 2800, STR_INCOME_FROM_ADMISSIONS = 2801, @@ -319,6 +338,10 @@ enum { STR_REAL_PARKS = STR_BEGINNER_PARKS + 3, STR_OTHER_PARKS = STR_BEGINNER_PARKS + 4, + STR_LIST_RIDES_TIP = 3104, + STR_LIST_SHOPS_AND_STALLS_TIP = 3105, + STR_LIST_KIOSKS_AND_FACILITIES_TIP = 3106, + STR_SCROLL_LEFT_TIP = 3145, STR_SCROLL_RIGHT_TIP = STR_SCROLL_LEFT_TIP + 1, STR_SCROLL_LEFT_FAST_TIP = STR_SCROLL_LEFT_TIP + 2, diff --git a/src/widget.c b/src/widget.c index 47e571de2e..6ae2213947 100644 --- a/src/widget.c +++ b/src/widget.c @@ -551,6 +551,9 @@ static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widge } // Draw text + if (widget->image == (uint32)-1) + return; + l = widget->left + w->x + 2; t = widget->top + w->y + 1; width = widget->right - widget->left - 4; diff --git a/src/window.c b/src/window.c index b85a972f9c..97ba44cba1 100644 --- a/src/window.c +++ b/src/window.c @@ -175,6 +175,27 @@ rct_window *window_create(int x, int y, int width, int height, uint32 *event_han return w; } +/** + * Opens a new window, supposedly automatically positioned + * rct2: 0x006EA9B1 + * + * @param width (bx) + * @param height (ebx >> 16) + * @param events (edx) + * @param flags (ch) + * @param class (cl) + */ +rct_window *window_create_auto_pos(int width, int height, uint32 *event_handlers, rct_windowclass cls, uint16 flags) +{ + int eax, ebx, ecx, edx, esi, edi, ebp; + + ebx = (height << 16) | width; + ecx = (flags << 8) | cls; + edx = event_handlers; + RCT2_CALLFUNC_X(0x006EA9B1, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + return esi; +} + /** * Closes the specified window. * rct2: 0x006ECD4C diff --git a/src/window.h b/src/window.h index 513469eb39..0cbd415d84 100644 --- a/src/window.h +++ b/src/window.h @@ -110,7 +110,12 @@ typedef struct rct_window { rct_windownumber number; // 0x03C uint16 flags; // 0x03E rct_scroll scrolls[3]; // 0x040 - uint8 pad_076[0x40A]; + uint8 pad_076[0x400]; + sint16 var_476; + sint16 pad_478; + sint16 var_47A; + sint16 pad_47C; + sint16 pad_47E; sint16 var_480; sint16 var_482; // viewport target x sint16 var_484; // viewport target y @@ -267,6 +272,7 @@ enum { void window_dispatch_update_all(); void window_update_all(); rct_window *window_create(int x, int y, int width, int height, uint32 *event_handlers, rct_windowclass cls, uint16 flags); +rct_window *window_create_auto_pos(int width, int height, uint32 *event_handlers, rct_windowclass cls, uint16 flags); void window_close(rct_window *window); void window_close_by_id(rct_windowclass cls, rct_windownumber number); rct_window *window_find_by_id(rct_windowclass cls, rct_windownumber number); @@ -309,6 +315,7 @@ void window_land_open(); void window_water_open(); void window_park_entrance_open(); void window_park_objective_open(); +void window_ride_list_open(); void window_cheats_open(); #endif \ No newline at end of file diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index b97412a97f..7a0d425151 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -217,7 +217,7 @@ static void window_game_top_toolbar_mouseup() RCT2_CALLPROC_EBPSAFE(0x006B3CFF); break; case WIDX_RIDES: - RCT2_CALLPROC_EBPSAFE(0x006B30BC); + window_ride_list_open(); break; case WIDX_PARK: window_park_entrance_open(); diff --git a/src/window_park.c b/src/window_park.c index 105fa691b4..08996804eb 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -588,14 +588,7 @@ rct_window *window_park_open() { rct_window* w; - { - int eax, ebx, ecx, edx, esi, edi, ebp; - ebx = 0xAE00E6; - ecx = 0x4001B; - edx = 0x0097BB6C; - RCT2_CALLFUNC_X(0x006EA9B1, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - w = esi; - } + w = window_create_auto_pos(230, 174, window_park_entrance_events, WC_PARK_INFORMATION, 0x0400); w->widgets = window_park_entrance_widgets; w->enabled_widgets = window_park_page_enabled_widgets[WINDOW_PARK_PAGE_ENTRANCE]; w->number = 0; diff --git a/src/window_ride_list.c b/src/window_ride_list.c new file mode 100644 index 0000000000..9fb48001c3 --- /dev/null +++ b/src/window_ride_list.c @@ -0,0 +1,290 @@ +/***************************************************************************** + * Copyright (c) 2014 Ted John + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * This file is part of OpenRCT2. + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + +#include +#include "addresses.h" +#include "park.h" +#include "strings.h" +#include "sprites.h" +#include "widget.h" +#include "window.h" + +enum { + PAGE_RIDES, + PAGE_SHOPS_AND_STALLS, + PAGE_KIOSKS_AND_FACILITIES +}; + +static enum WINDOW_RIDE_LIST_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_PAGE_BACKGROUND, + WIDX_OPEN_CLOSE_ALL, + WIDX_CURRENT_INFORMATION_TYPE, + WIDX_INFORMATION_TYPE_DROPDOWN, + WIDX_SORT, + WIDX_TAB_1, + WIDX_TAB_2, + WIDX_TAB_3, + WIDX_LIST +}; + +static rct_widget window_ride_list_widgets[] = { + { WWT_FRAME, 0, 0, 339, 0, 239, 0x0FFFFFFFF, 65535 }, // panel / background + { WWT_CAPTION, 0, 1, 338, 1, 14, 0x0FFFFFFFF, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 327, 337, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_RESIZE, 1, 0, 339, 43, 239, 0x0FFFFFFFF, 65535 }, // tab page background + { WWT_FLATBTN, 1, 315, 338, 60, 83, SPR_TOGGLE_OPEN_CLOSE, STR_OPEN_OR_CLOSE_ALL_RIDES }, // open / close all toggle + { WWT_DROPDOWN, 1, 164, 273, 46, 57, 0x0FFFFFFFF, 65535 }, // current information type + { WWT_DROPDOWN_BUTTON, 1, 262, 272, 47, 56, 876, STR_RIDE_LIST_INFORMATION_TYPE_TIP }, // information type dropdown button + { WWT_DROPDOWN_BUTTON, 1, 280, 333, 46, 57, STR_SORT, STR_RIDE_LIST_SORT_TIP }, // sort button + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, STR_LIST_RIDES_TIP }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, STR_LIST_SHOPS_AND_STALLS_TIP }, // tab 2 + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, STR_LIST_KIOSKS_AND_FACILITIES_TIP }, // tab 3 + { WWT_SCROLL, 1, 3, 336, 60, 236, 2, 65535 }, // list + { WIDGETS_END }, +}; + +static void window_ride_list_emptysub() { } +static void window_ride_list_mouseup(); +static void window_ride_list_update(); +static void window_ride_list_tooltip(); +static void window_ride_list_invalidate(); +static void window_ride_list_paint(); + +static uint32 window_ride_list_events[] = { + window_ride_list_emptysub, + window_ride_list_mouseup, + window_ride_list_emptysub, + window_ride_list_mousedown, + window_ride_list_dropdown, + window_ride_list_emptysub, + window_ride_list_update, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_tooltip, + window_ride_list_emptysub, + window_ride_list_emptysub, + window_ride_list_invalidate, + window_ride_list_paint, + window_ride_list_emptysub +}; + +enum { + INFORMATION_TYPE_STATUS, + INFORMATION_TYPE_POPULARITY, + INFORMATION_TYPE_SATISFACTION, + INFORMATION_TYPE_PROFIT, + INFORMATION_TYPE_QUEUE_LENGTH, + INFORMATION_TYPE_QUEUE_TIME, + INFORMATION_TYPE_RELIABILITY, + INFORMATION_TYPE_DOWN_TIME, + INFORMATION_TYPE_GUESTS_FAVOURITE +}; + +static void window_ride_list_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); + +static int window_ride_list_information_type; + +/** + * + * rct2: 0x006B30BC + */ +void window_ride_list_open() +{ + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_RIDE_LIST, 0); + if (window == NULL) { + window = window_create_auto_pos(340, 240, window_ride_list_events, WC_PARK_INFORMATION, 0x0400); + window->widgets = window_ride_list_widgets; + window->enabled_widgets = + (1 << WIDX_CLOSE) | + (1 << WIDX_OPEN_CLOSE_ALL) | + (1 << WIDX_CURRENT_INFORMATION_TYPE) | + (1 << WIDX_INFORMATION_TYPE_DROPDOWN) | + (1 << WIDX_SORT) | + (1 << WIDX_TAB_1) | + (1 << WIDX_TAB_2) | + (1 << WIDX_TAB_3); + window_init_scroll_widgets(window); + window->page = PAGE_RIDES; + window->var_476 = 0; + window->var_47A = -1; + window->var_48E = 0; + window->min_width = 340; + window->min_height = 240; + window->max_width = 400; + window->max_height = 450; + window->flags = WF_RESIZABLE; + window->colours[0] = 1; + window->colours[1] = 26; + window->colours[2] = 26; + } + window_ride_list_information_type = INFORMATION_TYPE_STATUS; + window->var_490 = 0; +} + +static void window_ride_list_mouseup() +{ + int i; + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_SORT: + w->var_490 = window_ride_list_information_type; + w->var_476 = 0; + w->var_47A = -1; + break; + case WIDX_TAB_1: + case WIDX_TAB_2: + case WIDX_TAB_3: + if (w->page != widgetIndex - WIDX_TAB_1) { + w->page = widgetIndex - WIDX_TAB_1; + w->var_476 = 0; + w->var_47A = -1; + if (w->page != PAGE_RIDES && window_ride_list_information_type > INFORMATION_TYPE_PROFIT) + window_ride_list_information_type = INFORMATION_TYPE_PROFIT; + window_invalidate(w); + } + break; + } +} + +static void window_ride_list_mousedown() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi +} + +static void window_ride_list_dropdown() +{ + short widgetIndex; + rct_window *w; + + __asm mov widgetIndex, dx + __asm mov w, esi +} + +static void window_ride_list_update() +{ + rct_window *w; + + __asm mov w, esi + + w->var_48E = (w->var_48E + 1) % 64; + widget_invalidate(w->classification, w->number, WIDX_TAB_1 + w->page); + if (window_ride_list_information_type != INFORMATION_TYPE_STATUS) + window_invalidate(w); +} + +static void window_ride_list_tooltip() +{ + RCT2_GLOBAL(0x013CE952, uint16) = STR_LIST; +} + +static void window_ride_list_invalidate() +{ + int i, x, y; + rct_window *w; + + __asm mov w, esi + + window_ride_list_widgets[WIDX_CURRENT_INFORMATION_TYPE].image = STR_STATUS + window_ride_list_information_type; + + // Set correct active tab + for (i = 0; i < 3; i++) + w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); + w->pressed_widgets |= 1 << (WIDX_TAB_1 + w->page); + + window_ride_list_widgets[WIDX_TITLE].image = STR_RIDES + w->page; + + w->widgets[WIDX_BACKGROUND].right = w->width - 1; + w->widgets[WIDX_BACKGROUND].bottom = w->height - 1; + w->widgets[WIDX_PAGE_BACKGROUND].right = w->width - 1; + w->widgets[WIDX_PAGE_BACKGROUND].bottom = w->height - 1; + w->widgets[WIDX_TITLE].right = w->width - 2; + w->widgets[WIDX_CLOSE].left = w->width - 13; + w->widgets[WIDX_CLOSE].right = w->width - 3; + w->widgets[WIDX_LIST].right = w->width - 26; + w->widgets[WIDX_LIST].bottom = w->height - 4; + w->widgets[WIDX_OPEN_CLOSE_ALL].right = w->width - 2; + w->widgets[WIDX_OPEN_CLOSE_ALL].left = w->width - 25; +} + +static void window_ride_list_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + __asm mov w, esi + __asm mov dpi, edi + + window_draw_widgets(w, dpi); + window_ride_list_draw_tab_images(dpi, w); +} + +static void window_ride_list_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w) +{ + int sprite_idx; + + // Rides tab + sprite_idx = SPR_TAB_RIDE_0; + if (w->page == PAGE_RIDES) + sprite_idx += w->var_48E / 4; + gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_1].left, w->y + w->widgets[WIDX_TAB_1].top); + + // Shops and stalls tab + sprite_idx = SPR_TAB_SHOPS_AND_STALLS_0; + if (w->page == PAGE_SHOPS_AND_STALLS) + sprite_idx += w->var_48E / 4; + gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_2].left, w->y + w->widgets[WIDX_TAB_2].top); + + // Information kiosks and facilities tab + sprite_idx = SPR_TAB_KIOSKS_AND_FACILITIES_0; + if (w->page == PAGE_KIOSKS_AND_FACILITIES) + sprite_idx += (w->var_48E / 4) % 8; + gfx_draw_sprite(dpi, sprite_idx, w->x + w->widgets[WIDX_TAB_3].left, w->y + w->widgets[WIDX_TAB_3].top); +} \ No newline at end of file