From 17e9ea1fc41f036974c6f25f7763264565f5787e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 12 Oct 2014 02:55:42 +0100 Subject: [PATCH] implement the viewport window --- data/language/english_uk.txt | 2 +- projects/openrct2.vcxproj | 1 + projects/openrct2.vcxproj.filters | 8 +- src/interface/window.h | 4 +- src/windows/game_top_toolbar.c | 4 +- src/windows/viewport.c | 254 ++++++++++++++++++++++++++++++ 6 files changed, 266 insertions(+), 7 deletions(-) create mode 100644 src/windows/viewport.c diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index a6b4cc889a..e46a2ee596 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2782,8 +2782,8 @@ STR_2775 :Fullscreen (desktop) STR_2776 :Language STR_2777 :{MOVE_X}{SMALLFONT}{STRING} STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING} +STR_2779 :Viewport #{COMMA16} # End of new strings -STR_2779 :??? STR_2780 :??? STR_2781 :{STRINGID}:{MOVE_X}{195}{STRINGID}{STRINGID} STR_2782 :SHIFT + diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 41b6e1cb2f..f16f2b5e5d 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -135,6 +135,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 8e61b709f5..67184363c4 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -381,16 +381,12 @@ - Source\Drawing - - Libraries\libspeex - @@ -422,6 +418,10 @@ Source\World + + + Source\Windows + diff --git a/src/interface/window.h b/src/interface/window.h index 1242215e0d..ed58a6d0c3 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -390,7 +390,8 @@ enum { WC_CLEAR_SCENERY = 50, WC_MANAGE_TRACK_DESIGN = 89, WC_CHEATS = 110, - WC_RESEARCH = 111 + WC_RESEARCH = 111, + WC_VIEWPORT = 112 } WINDOW_CLASS; enum PROMPT_MODE { @@ -499,6 +500,7 @@ void window_scenery_open(); void window_music_credits_open(); void window_publisher_credits_open(); void window_track_manage_open(); +void window_viewport_open(); void window_guest_list_init_vars_a(); void window_guest_list_init_vars_b(); diff --git a/src/windows/game_top_toolbar.c b/src/windows/game_top_toolbar.c index 17d294f7a9..58afb123f2 100644 --- a/src/windows/game_top_toolbar.c +++ b/src/windows/game_top_toolbar.c @@ -205,7 +205,9 @@ static void window_game_top_toolbar_mouseup() // button in the game. Use "git update-index --skip-worktree // src/window_game_top_toolbar" to avoid committing these changes to // version control. - window_cheats_open(); + // window_cheats_open(); + + window_viewport_open(); break; case WIDX_ZOOM_OUT: diff --git a/src/windows/viewport.c b/src/windows/viewport.c new file mode 100644 index 0000000000..bcb04d729f --- /dev/null +++ b/src/windows/viewport.c @@ -0,0 +1,254 @@ +/***************************************************************************** + * 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 "../audio/audio.h" +#include "../game.h" +#include "../world/map.h" +#include "../localisation/localisation.h" +#include "../sprites.h" +#include "../interface/viewport.h" +#include "../interface/widget.h" +#include "../interface/window.h" +#include "dropdown.h" + +#define INITIAL_WIDTH 500 +#define INITIAL_HEIGHT 350 + +enum { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_PAGE_BACKGROUND, + WIDX_VIEWPORT, + WIDX_ZOOM_IN, + WIDX_ZOOM_OUT +}; + +static rct_widget window_viewport_widgets[] = { + { WWT_FRAME, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE }, // panel / background + { WWT_CAPTION, 0, 1, 0, 1, 14, 2779, STR_WINDOW_TITLE_TIP }, // title bar + { WWT_CLOSEBOX, 0, 0, 0, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button + { WWT_RESIZE, 1, 0, 0, 14, 0, 0xFFFFFFFF, STR_NONE }, // resize + { WWT_VIEWPORT, 0, 3, 0, 17, 0, 0xFFFFFFFF, STR_NONE }, // viewport + + { WWT_FLATBTN, 0, 0, 0, 17, 40, 0xFFFFFFFF, STR_ZOOM_IN_TIP }, // zoom in + { WWT_FLATBTN, 0, 0, 0, 41, 64, 0xFFFFFFFF, STR_ZOOM_OUT_TIP }, // zoom out + { WIDGETS_END }, +}; + +static void window_viewport_empty(){} +static void window_viewport_mouseup(); +static void window_viewport_resize(); +static void window_viewport_update(rct_window *w); +static void window_viewport_invalidate(); +static void window_viewport_paint(); + +void* window_viewport_events[] = { + window_viewport_empty, + window_viewport_mouseup, + window_viewport_resize, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_update, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_empty, + window_viewport_invalidate, + window_viewport_paint, + window_viewport_empty +}; + +static int _viewportNumber = 1; + +/** + * Creates a custom viewport window. + */ +void window_viewport_open() +{ + rct_window *w, *mainWindow; + rct_viewport *mainViewport; + int x, y, rotation; + + w = window_create_auto_pos( + INITIAL_WIDTH, INITIAL_HEIGHT, + (uint32*)window_viewport_events, + WC_VIEWPORT, + WF_RESIZABLE + ); + w->widgets = window_viewport_widgets; + w->enabled_widgets = + (1 << WIDX_CLOSE) | + (1 << WIDX_ZOOM_IN) | + (1 << WIDX_ZOOM_OUT); + w->number = _viewportNumber++; + w->colours[0] = 24; + w->colours[1] = 24; + w->colours[2] = 24; + + rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, sint32); + + // Create viewport + viewport_create(w, w->x, w->y, w->width, w->height, 0, 128 * 32, 128 * 32, 0, 1, -1); + mainWindow = window_get_main(); + if (mainWindow != NULL) { + mainViewport = mainWindow->viewport; + x = mainViewport->view_x + (mainViewport->view_width / 2); + y = mainViewport->view_y + (mainViewport->view_height / 2); + w->saved_view_x = x - (w->viewport->view_width / 2); + w->saved_view_y = y - (w->viewport->view_height / 2); + } + + w->viewport->flags |= VIEWPORT_FLAG_SOUND_ON; +} + +static void window_viewport_anchor_border_widgets(rct_window *w) +{ + 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; +} + +static void window_viewport_mouseup() +{ + short widgetIndex; + rct_window *w; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_ZOOM_IN: + if (w->viewport != NULL && w->viewport->zoom > 0) { + w->viewport->zoom--; + window_invalidate(w); + } + break; + case WIDX_ZOOM_OUT: + if (w->viewport != NULL && w->viewport->zoom < 3) { + w->viewport->zoom++; + window_invalidate(w); + } + break; + } +} + +static void window_viewport_resize() +{ + rct_window *w; + + window_get_register(w); + + w->flags |= WF_RESIZABLE; + window_set_resize(w, 200, 200, 2000, 2000); +} + +static void window_viewport_update(rct_window *w) +{ + rct_window *mainWindow; + + mainWindow = window_get_main(); + if (mainWindow == NULL) + return; + + if (w->viewport->flags != mainWindow->viewport->flags) { + w->viewport->flags = mainWindow->viewport->flags; + window_invalidate(w); + } + + // Not sure how to invalidate part of the viewport that has changed, this will have to do for now + widget_invalidate(WC_VIEWPORT, w->number, WIDX_VIEWPORT); +} + +static void window_viewport_invalidate() +{ + rct_window *w; + rct_widget *viewportWidget; + rct_viewport *viewport; + int i; + + window_get_register(w); + + viewportWidget = &window_viewport_widgets[WIDX_VIEWPORT]; + viewport = w->viewport; + + // Anchor widgets + window_viewport_anchor_border_widgets(w); + viewportWidget->right = w->width - 26; + viewportWidget->bottom = w->height - 3; + for (i = WIDX_ZOOM_IN; i <= WIDX_ZOOM_OUT; i++) { + window_viewport_widgets[i].left = w->width - 25; + window_viewport_widgets[i].right = w->width - 2; + } + + // Set title + RCT2_GLOBAL(0x013CE952 + 0, uint32) = w->number; + + // Set disabled widgets + w->disabled_widgets = 0; + if (viewport->zoom == 0) + w->disabled_widgets |= 1 << WIDX_ZOOM_IN; + if (viewport->zoom >= 3) + w->disabled_widgets |= 1 << WIDX_ZOOM_OUT; + + viewport->x = w->x + viewportWidget->left; + viewport->y = w->y + viewportWidget->top; + viewport->width = viewportWidget->right - viewportWidget->left; + viewport->height = viewportWidget->bottom - viewportWidget->top; + viewport->view_width = viewport->width << viewport->zoom; + viewport->view_height = viewport->height << viewport->zoom; +} + +static void window_viewport_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + + // Draw viewport + if (w->viewport != NULL) + window_draw_viewport(dpi, w); +} \ No newline at end of file