From 7a83a8b1a85ee8e715021d8991ad495faf6b8a24 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 3 Apr 2014 19:49:00 +0100 Subject: [PATCH] fix window problems and add scenario select --- projects/openrct2.vcxproj | 4 ++ projects/openrct2.vcxproj.filters | 6 ++ src/addresses.h | 25 +++++++ src/intro.c | 25 +++---- src/widget.c | 77 ++++++++++++++++++++++ src/widget.h | 4 ++ src/window.c | 106 +++++++++++++++++++++++++++++- src/window.h | 4 ++ src/window_title_exit.c | 2 +- src/window_title_logo.c | 4 +- src/window_title_menu.c | 37 ++++++++++- src/window_title_scenarioselect.c | 73 ++++++++++++++++++++ 12 files changed, 349 insertions(+), 18 deletions(-) create mode 100644 src/widget.c create mode 100644 src/window_title_scenarioselect.c diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index ed5c5a5c55..a436c6a336 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -44,11 +44,13 @@ + + @@ -99,6 +101,7 @@ Level3 Disabled true + 1Byte true @@ -113,6 +116,7 @@ true true MultiThreaded + 1Byte true diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 2d18f28aab..d76e652147 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -116,6 +116,12 @@ Windows + + Source Files + + + Windows + diff --git a/src/addresses.h b/src/addresses.h index 52ca4bc08b..9f9943aaee 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -108,4 +108,29 @@ static void RCT2_CALLPROC_X(int address, int _eax, int _ebx, int _ecx, int _edx, } } +static void RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_edx, int *_esi, int *_edi, int *_ebp) +{ + __asm { + push ebp + push address + mov eax, [_eax] + mov ebx, [_ebx] + mov ecx, [_ecx] + mov edx, [_edx] + mov esi, [_esi] + mov edi, [_edi] + mov ebp, [_ebp] + call[esp] + add esp, 4 + pop ebp + // mov[_ebp], ebp + mov[_edi], edi + mov[_esi], esi + mov[_edx], edx + mov[_ecx], ecx + mov[_ebx], ebx + mov [_eax], eax + } +} + #endif \ No newline at end of file diff --git a/src/intro.c b/src/intro.c index fd91386b3f..3c18041ab5 100644 --- a/src/intro.c +++ b/src/intro.c @@ -24,6 +24,7 @@ #include "intro.h" #include "rct2.h" #include "osinterface.h" +#include "sprites.h" #include "strings.h" static void screen_intro_process_mouse_input(); @@ -103,10 +104,10 @@ void intro_update() 129); // Draw the logo - gfx_draw_sprite(screenDPI, 0x5ABA, (screenWidth / 2) - 320 + 69, _tick_counter + 69); - gfx_draw_sprite(screenDPI, 0x5ABB, (screenWidth / 2) - 320 + 319, _tick_counter + 69); - gfx_draw_sprite(screenDPI, 0x5ABC, (screenWidth / 2) - 320 + 69, _tick_counter + 319); - gfx_draw_sprite(screenDPI, 0x5ABD, (screenWidth / 2) - 320 + 319, _tick_counter + 319); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_00, (screenWidth / 2) - 320 + 69, _tick_counter + 69); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_10, (screenWidth / 2) - 320 + 319, _tick_counter + 69); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_01, (screenWidth / 2) - 320 + 69, _tick_counter + 319); + gfx_draw_sprite(screenDPI, SPR_INTRO_INFOGRAMES_11, (screenWidth / 2) - 320 + 319, _tick_counter + 319); // Check if logo is off the screen .ish if (_tick_counter > 520) { @@ -144,8 +145,8 @@ void intro_update() gfx_clear(screenDPI, 10); // Draw Chris Sawyer logo - gfx_draw_sprite(screenDPI, 0x5AAF, (screenWidth / 2) - 320 + 70, _tick_counter); - gfx_draw_sprite(screenDPI, 0x5AB0, (screenWidth / 2) - 320 + 320, _tick_counter); + gfx_draw_sprite(screenDPI, SPR_INTRO_CHRIS_SAWYER_00, (screenWidth / 2) - 320 + 70, _tick_counter); + gfx_draw_sprite(screenDPI, SPR_INTRO_CHRIS_SAWYER_10, (screenWidth / 2) - 320 + 320, _tick_counter); // Check if logo is at 259 pixels if (_tick_counter == 259) { @@ -170,12 +171,12 @@ void intro_update() gfx_clear(screenDPI, 245); // Draw RollerCoaster Tycoon 2 logo - gfx_draw_sprite(screenDPI, 0x5AB2, (screenWidth / 2) - 320 + 0, 0); - gfx_draw_sprite(screenDPI, 0x5AB3, (screenWidth / 2) - 320 + 220, 0); - gfx_draw_sprite(screenDPI, 0x5AB4, (screenWidth / 2) - 320 + 440, 0); - gfx_draw_sprite(screenDPI, 0x5AB5, (screenWidth / 2) - 320 + 0, 240); - gfx_draw_sprite(screenDPI, 0x5AB6, (screenWidth / 2) - 320 + 220, 240); - gfx_draw_sprite(screenDPI, 0x5AB7, (screenWidth / 2) - 320 + 440, 240); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_00, (screenWidth / 2) - 320 + 0, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_10, (screenWidth / 2) - 320 + 220, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_20, (screenWidth / 2) - 320 + 440, 0); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_01, (screenWidth / 2) - 320 + 0, 240); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_11, (screenWidth / 2) - 320 + 220, 240); + gfx_draw_sprite(screenDPI, SPR_INTRO_LOGO_21, (screenWidth / 2) - 320 + 440, 240); // Set palette thing gfx_transpose_palette(23224, 0); diff --git a/src/widget.c b/src/widget.c new file mode 100644 index 0000000000..09bae1fc11 --- /dev/null +++ b/src/widget.c @@ -0,0 +1,77 @@ +/***************************************************************************** + * 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 "widget.h" +#include "window.h" + +/** + * + * rct2: 0x006EAF26 + */ +void widget_scroll_update_thumbs(rct_window *w, int widget_index) +{ + rct_widget* widget; + rct_scroll* scroll; + int x, y, view_size; + + widget = &w->widgets[widget_index]; + scroll = &w->scrolls[window_get_scroll_data_index(w, widget_index)]; + + if (scroll->flags & HSCROLLBAR_VISIBLE) { + view_size = widget->right - widget->left - 21; + if (scroll->flags & VSCROLLBAR_VISIBLE) + view_size -= 11; + x = scroll->h_left * view_size; + if (scroll->h_right != 0) + x /= scroll->h_right; + scroll->h_thumb_left = x + 11; + + x = widget->right - widget->left - 2; + if (scroll->flags & VSCROLLBAR_VISIBLE) + x -= 11; + x += scroll->h_left; + if (scroll->h_right != 0) + x = (x * view_size) / scroll->h_right; + x += 11; + view_size += 10; + scroll->h_thumb_right = min(x, view_size); + } + + if (scroll->flags & VSCROLLBAR_VISIBLE) { + view_size = widget->bottom - widget->top - 21; + if (scroll->flags & HSCROLLBAR_VISIBLE) + view_size -= 11; + y = scroll->v_top * view_size; + if (scroll->v_bottom != 0) + y /= scroll->v_bottom; + scroll->v_thumb_top = y + 11; + + y = widget->bottom - widget->top - 2; + if (scroll->flags & HSCROLLBAR_VISIBLE) + y -= 11; + y += scroll->v_top; + if (scroll->v_bottom != 0) + y = (y * view_size) / scroll->v_bottom; + y += 11; + view_size += 10; + scroll->v_thumb_bottom = min(y, view_size); + } +} \ No newline at end of file diff --git a/src/widget.h b/src/widget.h index a65ba755dd..face7f482c 100644 --- a/src/widget.h +++ b/src/widget.h @@ -21,6 +21,8 @@ #ifndef _WIDGET_H_ #define _WIDGET_H_ +#include "window.h" + typedef enum { WWT_EMPTY = 0, WWT_FRAME = 1, @@ -42,4 +44,6 @@ typedef enum { } WINDOW_WIDGET_TYPES; #define WIDGETS_END WWT_LAST, 0, 0, 0, 0, 0, 0, 0 +void widget_scroll_update_thumbs(rct_window *w, int widget_index); + #endif \ No newline at end of file diff --git a/src/window.c b/src/window.c index de0b938149..fd423e1bb5 100644 --- a/src/window.c +++ b/src/window.c @@ -21,6 +21,7 @@ #include "addresses.h" #include "audio.h" #include "rct2.h" +#include "widget.h" #include "window.h" #define RCT2_FIRST_WINDOW (RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window)) @@ -206,5 +207,108 @@ void window_invalidate(rct_window *window) */ void window_init_scroll_widgets(rct_window *w) { - RCT2_CALLPROC_X(0x006EAEB8, 0, 0, 0, 0, w, 0, 0); + rct_widget* widget; + rct_scroll* scroll; + int widget_index, scroll_index; + + widget_index = 0; + scroll_index = 0; + for (widget = w->widgets; widget->type != WWT_LAST; widget++) { + if (widget->type != WWT_SCROLL) { + widget_index++; + continue; + } + + scroll = &w->scrolls[scroll_index]; + + { + int _eax = 0, _ebx = scroll_index * sizeof(rct_scroll), _ecx = 0, _edx = 0, _esi = w, _edi = widget_index * sizeof(rct_widget), _ebp = 0; + RCT2_CALLFUNC_X(w->event_handlers[WE_SCROLL_GETSIZE], & _eax, &_ebx, &_ecx, &_edx, &_esi, &_edi, &_ebp); + + scroll->h_left = 0; + scroll->h_right = _ecx + 1; + scroll->v_top = 0; + scroll->v_bottom = _edx + 1; + } + + if (widget->image & 0x01) + scroll->flags |= HSCROLLBAR_VISIBLE; + if (widget->image & 0x02) + scroll->flags |= VSCROLLBAR_VISIBLE; + + widget_scroll_update_thumbs(w, widget_index); + + widget_index++; + scroll_index++; + } +} + +int window_get_scroll_data_index(rct_window *w, int widget_index) +{ + int i, result; + + result = 0; + for (i = 0; i < widget_index; i++) { + if (w->widgets[i].type == WWT_SCROLL) + result++; + } + return result; +} + +/** + * + * rct2: 0x006ED78A + * cls (cl) + * number (dx) + */ +rct_window *window_bring_to_front_by_id(rct_windowclass cls, rct_windownumber number) +{ + rct_window* w; + + w = window_find_by_id(cls, number); + if (w != NULL) { + w->flags |= WF_WHITE_BORDER_MASK; + window_invalidate(w); + w = window_bring_to_front(w); + } + + return w; +} + +/** + * + * rct2: 0x006ECDA4 + */ +rct_window *window_bring_to_front(rct_window *w) +{ + int i; + rct_window* v, t; + + if (w->flags & 0x03) + return w; + + for (v = RCT2_LAST_WINDOW; v >= RCT2_FIRST_WINDOW; v--) + if (!(v->flags & 2)) + break; + + if (v >= RCT2_FIRST_WINDOW && w != v) { + do { + t = *w; + *w = *(w + 1); + *(w + 1) = t; + w++; + } while (w != v); + + window_invalidate(w); + } + + if (w->x + w->width < 20) { + i = 20 - w->x; + w->x += i; + if (w->viewport != NULL) + w->viewport->x += i; + window_invalidate(w); + } + + return w; } \ No newline at end of file diff --git a/src/window.h b/src/window.h index db2d55871f..f9409f03b9 100644 --- a/src/window.h +++ b/src/window.h @@ -272,5 +272,9 @@ 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_init_scroll_widgets(rct_window *w); +int window_get_scroll_data_index(rct_window *w, int widget_index); + +rct_window *window_bring_to_front_by_id(rct_windowclass cls, rct_windownumber number); +rct_window *window_bring_to_front(rct_window *w); #endif \ No newline at end of file diff --git a/src/window_title_exit.c b/src/window_title_exit.c index f663179b4c..2625da4a26 100644 --- a/src/window_title_exit.c +++ b/src/window_title_exit.c @@ -42,7 +42,7 @@ void window_title_exit_open() RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) - 64, 40, 64, 0x0097BEFC, WC_TITLE_EXIT, 0x02 ); - window->widgets = 0x009A9644; + window->widgets = window_title_exit_widgets; window->enabled_widgets |= 1; window_init_scroll_widgets(window); window->flags |= 16; diff --git a/src/window_title_logo.c b/src/window_title_logo.c index 0939350ef8..3021d4513b 100644 --- a/src/window_title_logo.c +++ b/src/window_title_logo.c @@ -36,7 +36,7 @@ void window_title_logo_open() { int i, packs; rct_window *window; - + // Count number of expansion packs packs = 0; for (i = 0; i < 16; i++) @@ -45,7 +45,7 @@ void window_title_logo_open() // Create the window window = window_create(0, 0, 200, 106 + (10 * packs), 0x0097BF6C, WC_TITLE_LOGO, 0x02); - window->widgets = 0x009A9658; + window->widgets = 0x009A9658; // mouse move bug in original game, keep this address and no crash happens window_init_scroll_widgets(window); window->flags |= 16; window->colours[0] = 129; diff --git a/src/window_title_menu.c b/src/window_title_menu.c index 5f257aa470..0cf43f498a 100644 --- a/src/window_title_menu.c +++ b/src/window_title_menu.c @@ -24,6 +24,8 @@ #include "widget.h" #include "window.h" +void window_levelselect_open(); + enum { WIDX_START_NEW_GAME, WIDX_CONTINUE_SAVED_GAME, @@ -39,6 +41,37 @@ static rct_widget window_title_menu_widgets[] = { { WIDGETS_END }, }; +static uint32 window_title_menu_events[] = { + 0x0066B834, + 0x0066B6EC, + 0x0066B834, + 0x0066B70E, + 0x0066B71F, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B834, + 0x0066B730, + 0x0066B834, + 0x0066B834, + 0x0066B6E6, + 0x0066B834 +}; + /** * Creates the window containing the menu buttons on the title screen. * rct2: 0x0066B5C0 (part of 0x0066B3E8) @@ -50,9 +83,9 @@ void window_title_menu_open() window = window_create( (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) - 328) / 2, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) - 142, - 328, 82, 0x0097BE8C, WC_TITLE_MENU, 0x02 + 328, 82, window_title_menu_events, WC_TITLE_MENU, 0x02 ); - window->widgets = 0x009A9600; + window->widgets = window_title_menu_widgets; window->enabled_widgets |= (8 | 4 | 2 | 1); window_init_scroll_widgets(window); window->flags |= 16; diff --git a/src/window_title_scenarioselect.c b/src/window_title_scenarioselect.c new file mode 100644 index 0000000000..299c04a2ab --- /dev/null +++ b/src/window_title_scenarioselect.c @@ -0,0 +1,73 @@ +/***************************************************************************** +* 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 "addresses.h" +#include "strings.h" +#include "sprites.h" +#include "widget.h" +#include "window.h" + +static rct_widget window_levelselect_widgets[] = { + { WWT_FRAME, 0, 0, 609, 0, 333, -1, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 608, 1, 14, STR_SELECT_SCENARIO, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 597, 607, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_IMGBTN, 1, 0, 609, 50, 333, -1, STR_NONE }, // tab content panel + { WWT_TAB, 1, 3, 93, 17, 50, 0x200015BC, STR_NONE }, // tab 1 + { WWT_TAB, 1, 94, 184, 17, 50, 0x200015BC, STR_NONE }, // tab 2 + { WWT_TAB, 1, 185, 275, 17, 50, 0x200015BC, STR_NONE }, // tab 3 + { WWT_TAB, 1, 276, 366, 17, 50, 0x200015BC, STR_NONE }, // tab 4 + { WWT_TAB, 1, 367, 457, 17, 50, 0x200015BC, STR_NONE }, // tab 5 + { WWT_SCROLL, 1, 3, 433, 54, 329, 2, STR_NONE }, // level list + { WIDGETS_END }, +}; + +/** + * + * rct2: 0x006781B5 + */ +void window_levelselect_open() +{ + rct_window* window; + int y; + + if (window_bring_to_front_by_id(WC_LEVEL_SELECT, 0) != NULL) + return; + + // Load scenario list + RCT2_CALLPROC_EBPSAFE(0x006775A8); // scenario_load_list(); + + y = (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) / 2) - 167; + if (y < 28) + y = 28; + window = window_create((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) / 2) - 305, y, 610, 334, 0x0097FC4C, WC_LEVEL_SELECT, 0x0402); + window->widgets = window_levelselect_widgets; + + window->enabled_widgets = 0x04 | 0x10 | 0x20 | 0x40 | 0x80 | 0x100; + window_init_scroll_widgets(window); + window->colours[0] = 1; + window->colours[1] = 26; + window->colours[2] = 26; + window->var_480 = -1; + window->var_494 = -1; + + RCT2_CALLPROC_EBPSAFE(0x00677C8A); // window_levelselect_init_tabs(); + + window->var_4AC = 0; +} \ No newline at end of file