2014-04-02 01:31:55 +02:00
|
|
|
/*****************************************************************************
|
2014-05-09 09:47:20 +02:00
|
|
|
* Copyright (c) 2014 Ted John, Peter Hill
|
2014-04-02 01:31:55 +02:00
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "addresses.h"
|
2014-04-24 19:53:42 +02:00
|
|
|
#include "audio.h"
|
2014-04-27 23:46:18 +02:00
|
|
|
#include "climate.h"
|
2014-04-24 22:29:57 +02:00
|
|
|
#include "config.h"
|
2014-04-02 01:31:55 +02:00
|
|
|
#include "rct2.h"
|
|
|
|
#include "game.h"
|
2014-05-08 00:45:16 +02:00
|
|
|
#include "finance.h"
|
2014-04-08 01:05:05 +02:00
|
|
|
#include "news_item.h"
|
2014-05-04 17:21:15 +02:00
|
|
|
#include "object.h"
|
2014-04-18 04:04:46 +02:00
|
|
|
#include "osinterface.h"
|
2014-04-03 01:22:33 +02:00
|
|
|
#include "peep.h"
|
2014-05-04 17:21:15 +02:00
|
|
|
#include "sawyercoding.h"
|
2014-05-01 19:15:02 +02:00
|
|
|
#include "scenario.h"
|
2014-04-25 19:25:34 +02:00
|
|
|
#include "screenshot.h"
|
2014-06-21 14:31:28 +02:00
|
|
|
#include "sprite.h"
|
2014-05-19 21:04:28 +02:00
|
|
|
#include "string_ids.h"
|
2014-05-02 23:21:08 +02:00
|
|
|
#include "title.h"
|
2014-04-26 02:16:32 +02:00
|
|
|
#include "tutorial.h"
|
2014-05-25 19:40:11 +02:00
|
|
|
#include "vehicle.h"
|
2014-05-04 17:21:15 +02:00
|
|
|
#include "viewport.h"
|
2014-04-14 15:32:05 +02:00
|
|
|
#include "widget.h"
|
2014-04-02 05:56:26 +02:00
|
|
|
#include "window.h"
|
2014-04-25 19:25:34 +02:00
|
|
|
#include "window_error.h"
|
2014-04-24 19:53:42 +02:00
|
|
|
#include "window_tooltip.h"
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2014-07-16 04:41:12 +02:00
|
|
|
|
2014-05-25 04:02:48 +02:00
|
|
|
int _gameSpeed = 1;
|
2014-08-10 14:31:41 +02:00
|
|
|
int previousPeepSpriteIndex = 0;
|
2014-05-25 04:02:48 +02:00
|
|
|
|
2014-04-14 04:09:51 +02:00
|
|
|
void game_handle_input();
|
2014-04-25 19:25:34 +02:00
|
|
|
void game_handle_keyboard_input();
|
2014-04-14 04:09:51 +02:00
|
|
|
|
2014-07-26 11:30:55 +02:00
|
|
|
void process_mouse_over(int x, int y);
|
|
|
|
|
2014-08-06 04:42:32 +02:00
|
|
|
typedef void(*draw_rain_func)(int left, int top, int width, int height);
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684114
|
|
|
|
*/
|
|
|
|
void draw_light_rain(int left, int top, int width, int height){
|
|
|
|
int edi = -RCT2_GLOBAL(0x00F663AC, int) + 8;
|
|
|
|
int esi = (RCT2_GLOBAL(0x00F663AC, int) * 3) + 7;
|
|
|
|
esi = -esi;
|
|
|
|
|
|
|
|
edi += left;
|
|
|
|
esi += top;
|
|
|
|
|
2014-08-08 18:19:08 +02:00
|
|
|
gfx_draw_rain(left, top, width, height, edi, esi);
|
2014-08-06 04:42:32 +02:00
|
|
|
|
|
|
|
edi = -RCT2_GLOBAL(0x00F663AC, int) + 0x18;
|
|
|
|
esi = (RCT2_GLOBAL(0x00F663AC, int) * 4) + 0x0D;
|
|
|
|
esi = -esi;
|
|
|
|
|
|
|
|
edi += left;
|
|
|
|
esi += top;
|
2014-08-08 18:19:08 +02:00
|
|
|
gfx_draw_rain(left, top, width, height, edi, esi);
|
2014-08-06 04:42:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0068416D
|
|
|
|
*/
|
|
|
|
void draw_heavy_rain(int left, int top, int width, int height){
|
|
|
|
int edi = -RCT2_GLOBAL(0x00F663AC, int);
|
|
|
|
int esi = RCT2_GLOBAL(0x00F663AC, int) * 5;
|
|
|
|
esi = -esi;
|
|
|
|
|
|
|
|
edi += left;
|
|
|
|
esi += top;
|
|
|
|
|
2014-08-08 18:19:08 +02:00
|
|
|
gfx_draw_rain(left, top, width, height, edi, esi);
|
2014-08-06 04:42:32 +02:00
|
|
|
|
|
|
|
edi = -RCT2_GLOBAL(0x00F663AC, int) + 0x10;
|
|
|
|
esi = (RCT2_GLOBAL(0x00F663AC, int) * 6) + 5;
|
|
|
|
esi = -esi;
|
|
|
|
|
|
|
|
edi += left;
|
|
|
|
esi += top;
|
|
|
|
|
2014-08-08 18:19:08 +02:00
|
|
|
gfx_draw_rain(left, top, width, height, edi, esi);
|
2014-08-06 04:42:32 +02:00
|
|
|
|
|
|
|
edi = -RCT2_GLOBAL(0x00F663AC, int) + 8;
|
|
|
|
esi = (RCT2_GLOBAL(0x00F663AC, int) * 3) + 7;
|
|
|
|
esi = -esi;
|
|
|
|
|
|
|
|
edi += left;
|
|
|
|
esi += top;
|
|
|
|
|
2014-08-08 18:19:08 +02:00
|
|
|
gfx_draw_rain(left, top, width, height, edi, esi);
|
2014-08-06 04:42:32 +02:00
|
|
|
|
|
|
|
edi = -RCT2_GLOBAL(0x00F663AC, int) + 0x18;
|
|
|
|
esi = (RCT2_GLOBAL(0x00F663AC, int) * 4) + 0x0D;
|
|
|
|
esi = -esi;
|
|
|
|
|
|
|
|
edi += left;
|
|
|
|
esi += top;
|
|
|
|
|
2014-08-08 18:19:08 +02:00
|
|
|
gfx_draw_rain(left, top, width, height, edi, esi);
|
2014-08-06 04:42:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x009AC058
|
|
|
|
*/
|
|
|
|
const draw_rain_func draw_rain_function[] = {
|
|
|
|
NULL,
|
|
|
|
&draw_light_rain, // Light rain
|
|
|
|
&draw_heavy_rain // Heavy rain
|
|
|
|
};
|
|
|
|
|
2014-08-07 14:00:49 +02:00
|
|
|
|
2014-08-07 23:37:24 +02:00
|
|
|
|
2014-08-07 14:00:49 +02:00
|
|
|
|
2014-07-26 11:30:55 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006ED801
|
|
|
|
*/
|
2014-07-27 15:34:08 +02:00
|
|
|
void sub_0x6ED801(int x, int y){
|
2014-07-26 11:30:55 +02:00
|
|
|
if (RCT2_GLOBAL(0x9DE518, uint32) & (1 << 3)){
|
|
|
|
rct_window* w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, uint16));
|
|
|
|
if (w == NULL){
|
|
|
|
tool_cancel();
|
|
|
|
}
|
|
|
|
else{
|
2014-07-27 17:29:07 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_UPDATE], x, y, 0, RCT2_GLOBAL(0x9DE546, uint16), (int)w, 0, 0);
|
2014-07-26 11:30:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-28 22:27:14 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006ED990
|
|
|
|
*/
|
2014-07-27 17:29:07 +02:00
|
|
|
void sub_0x6ED990(char cursor_id){
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_RESIZING)
|
|
|
|
{
|
|
|
|
cursor_id = CURSOR_DIAGONAL_ARROWS; //resize icon
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cursor_id == RCT2_GLOBAL(RCT2_ADDRESS_CURENT_CURSOR, uint8))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURENT_CURSOR, uint8) = cursor_id;
|
|
|
|
RCT2_GLOBAL(0x14241BC, uint32) = 2;
|
|
|
|
osinterface_set_cursor(cursor_id);
|
|
|
|
RCT2_GLOBAL(0x14241BC, uint32) = 0;
|
|
|
|
}
|
|
|
|
|
2014-07-26 11:30:55 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006ED833
|
|
|
|
*/
|
|
|
|
void process_mouse_over(int x, int y)
|
|
|
|
{
|
|
|
|
rct_window* window;
|
|
|
|
rct_window* subWindow;
|
|
|
|
|
|
|
|
int widgetId;
|
|
|
|
int cursorId;
|
|
|
|
int eax, ebx, ecx, edx, esi, edi, ebp;
|
|
|
|
|
2014-07-28 22:27:14 +02:00
|
|
|
cursorId = CURSOR_ARROW;
|
2014-07-26 11:30:55 +02:00
|
|
|
RCT2_GLOBAL(0x9A9808, sint16) = -1;
|
|
|
|
window = window_find_from_point(x, y);
|
2014-07-28 19:15:02 +02:00
|
|
|
|
2014-07-28 22:27:14 +02:00
|
|
|
if (window != NULL)
|
2014-07-26 11:30:55 +02:00
|
|
|
{
|
2014-07-28 22:27:14 +02:00
|
|
|
widgetId = window_find_widget_from_point(window, x, y);
|
|
|
|
RCT2_GLOBAL(0x1420046, sint16) = (widgetId & 0xFFFF);
|
2014-07-29 19:05:52 +02:00
|
|
|
if (widgetId != -1)
|
2014-07-28 19:15:02 +02:00
|
|
|
{
|
2014-07-26 11:30:55 +02:00
|
|
|
|
2014-07-28 22:27:14 +02:00
|
|
|
switch (window->widgets[widgetId].type){
|
|
|
|
case WWT_VIEWPORT:
|
|
|
|
if ((RCT2_GLOBAL(0x9DE518, int) & 0x8) == 0)
|
|
|
|
{
|
|
|
|
edx = cursorId;
|
|
|
|
eax = x;
|
|
|
|
ebx = y;
|
|
|
|
//Find out if there is a clickable item under pointer
|
|
|
|
RCT2_CALLFUNC_X(0X6ED9D0, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
|
|
|
|
if ((ebx & 0xFF) == 2 || (ebx & 0xFF) == 8 || (ebx & 0xFF) == 3)
|
|
|
|
{
|
|
|
|
sub_0x6ED990(CURSOR_HAND_POINT);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cursorId = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8);
|
|
|
|
subWindow = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber));
|
|
|
|
ebp = (int)subWindow;
|
|
|
|
if (subWindow == NULL)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ebx = ebx & 0xFFFFFF00;
|
|
|
|
edi = cursorId;
|
2014-07-31 00:11:01 +02:00
|
|
|
esi = (int) subWindow;
|
2014-07-28 22:27:14 +02:00
|
|
|
RCT2_CALLFUNC_X(subWindow->event_handlers[WE_UNKNOWN_0E], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
cursorId = edi;
|
|
|
|
if ((ebx & 0xFF) != 0)
|
|
|
|
{
|
|
|
|
sub_0x6ED990(cursorId);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WWT_FRAME:
|
|
|
|
case WWT_RESIZE:
|
|
|
|
if (!(window->flags & 0x100))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (window->min_width == window->max_width && window->min_height == window->max_height)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (x < window->x + window->width - 0x13)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (y < window->y + window->height - 0x13)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cursorId = CURSOR_DIAGONAL_ARROWS;
|
|
|
|
break;
|
|
|
|
case WWT_SCROLL:
|
|
|
|
RCT2_GLOBAL(0x9DE558, uint16) = x;
|
|
|
|
RCT2_GLOBAL(0x9DE55A, uint16) = y;
|
|
|
|
int output_x, output_y, output_scroll_area, scroll_id;
|
|
|
|
widget_scroll_get_part(window, window->widgets, x, y, &output_x, &output_y, &output_scroll_area, &scroll_id);
|
|
|
|
cursorId = scroll_id;
|
|
|
|
if (output_scroll_area != SCROLL_PART_VIEW)
|
|
|
|
{
|
|
|
|
cursorId = CURSOR_ARROW;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//Fall through to default
|
|
|
|
default:
|
|
|
|
ecx = x;
|
|
|
|
edx = y;
|
|
|
|
eax = widgetId;
|
|
|
|
ebx = 0xFFFFFFFF;
|
|
|
|
edi = (int)&window->widgets[widgetId];
|
|
|
|
|
|
|
|
RCT2_CALLFUNC_X(window->event_handlers[WE_UNKNOWN_17], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
if (ebx == 0xFFFFFFFF)
|
|
|
|
{
|
|
|
|
cursorId = CURSOR_ARROW;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cursorId = ebx;
|
|
|
|
break;
|
|
|
|
}
|
2014-07-26 11:30:55 +02:00
|
|
|
}
|
|
|
|
}
|
2014-07-28 22:27:14 +02:00
|
|
|
RCT2_CALLPROC_X(0x6EDE88, x, y, ecx, cursorId, esi, edi, ebp);
|
2014-07-28 19:15:02 +02:00
|
|
|
//itemUnderCursor(&eax, &ebx, &ecx, &edx);
|
|
|
|
|
2014-07-28 22:27:14 +02:00
|
|
|
sub_0x6ED990(cursorId);
|
2014-07-28 19:15:02 +02:00
|
|
|
return;
|
2014-07-26 11:30:55 +02:00
|
|
|
}
|
|
|
|
|
2014-04-11 03:42:39 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0066B5C0 (part of 0x0066B3E8)
|
|
|
|
*/
|
|
|
|
void game_create_windows()
|
|
|
|
{
|
|
|
|
window_main_open();
|
2014-04-11 04:58:17 +02:00
|
|
|
window_game_top_toolbar_open();
|
|
|
|
window_game_bottom_toolbar_open();
|
2014-04-11 03:42:39 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x0066B905);
|
|
|
|
}
|
|
|
|
|
2014-05-28 19:11:33 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006838BD
|
|
|
|
*/
|
|
|
|
void update_water_animation()
|
|
|
|
{
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006838BD);
|
|
|
|
}
|
|
|
|
|
2014-07-18 05:29:39 +02:00
|
|
|
/**
|
|
|
|
*
|
2014-07-20 08:46:29 +02:00
|
|
|
* rct2: 0x00684383
|
2014-07-18 05:29:39 +02:00
|
|
|
*/
|
2014-07-20 08:46:29 +02:00
|
|
|
void call_draw_rain_func(rct_window* w, short left, short right, short top, short bottom, uint32 draw_rain_func)
|
2014-07-18 05:29:39 +02:00
|
|
|
{
|
2014-07-29 16:25:13 +02:00
|
|
|
rct_viewport* vp = w->viewport;
|
2014-07-20 08:46:29 +02:00
|
|
|
if (vp == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
left = max(left, vp->x);
|
|
|
|
right = min(right, vp->width);
|
|
|
|
|
|
|
|
top = max(top, vp->y);
|
|
|
|
bottom = min(bottom, vp->height);
|
|
|
|
|
|
|
|
if (left >= right || top >= bottom) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int width = right - left;
|
|
|
|
int height = bottom - top;
|
|
|
|
|
2014-08-06 04:42:32 +02:00
|
|
|
draw_rain_function[draw_rain_func](left, top, width, height);
|
2014-07-20 08:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006842AF
|
|
|
|
* From 0x00684383 on: split into call_draw_rain_func
|
|
|
|
*/
|
|
|
|
void draw_rain_window(rct_window* original_w, short left, short right, short top, short bottom, uint32 draw_rain_func)
|
|
|
|
{
|
|
|
|
rct_window* newWindow = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*);
|
|
|
|
|
|
|
|
rct_window* w = original_w + 1; // Start from second window
|
|
|
|
for (; ; w++) {
|
|
|
|
if (w >= newWindow) {
|
|
|
|
// Loop ended, draw rain for original_w
|
2014-07-23 19:07:38 +02:00
|
|
|
call_draw_rain_func(original_w, left, right, top, bottom, draw_rain_func);
|
|
|
|
return;
|
2014-07-20 08:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (right <= w->x || bottom <= w->y) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RCT_WINDOW_RIGHT(w) <= left || RCT_WINDOW_BOTTOM(w) <= top) {
|
|
|
|
continue;
|
|
|
|
}
|
2014-07-18 05:29:39 +02:00
|
|
|
|
2014-07-20 08:46:29 +02:00
|
|
|
if (left >= w->x) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
draw_rain_window(original_w, left, w->x, top, bottom, draw_rain_func);
|
|
|
|
|
|
|
|
left = w->x;
|
2014-07-23 19:07:38 +02:00
|
|
|
draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
|
|
|
|
return;
|
2014-07-20 08:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sint16 w_right = RCT_WINDOW_RIGHT(w);
|
|
|
|
if (right > w_right) {
|
|
|
|
draw_rain_window(original_w, left, w_right, top, bottom, draw_rain_func);
|
|
|
|
|
|
|
|
left = w_right;
|
2014-07-23 19:07:38 +02:00
|
|
|
draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
|
|
|
|
return;
|
2014-07-20 08:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (top < w->y) {
|
|
|
|
draw_rain_window(original_w, left, right, top, w->y, draw_rain_func);
|
|
|
|
|
|
|
|
top = w->y;
|
2014-07-23 19:07:38 +02:00
|
|
|
draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
|
|
|
|
return;
|
2014-07-20 08:46:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sint16 w_bottom = RCT_WINDOW_BOTTOM(w);
|
|
|
|
if (bottom > w_bottom) {
|
|
|
|
draw_rain_window(original_w, left, right, top, w_bottom, draw_rain_func);
|
|
|
|
|
|
|
|
top = w_bottom;
|
2014-07-23 19:07:38 +02:00
|
|
|
draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
|
|
|
|
return;
|
2014-07-20 08:46:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684266
|
|
|
|
*/
|
|
|
|
void draw_rain_animation(uint32 draw_rain_func)
|
|
|
|
{
|
2014-07-18 05:29:39 +02:00
|
|
|
rct_drawpixelinfo *screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
|
2014-07-19 01:36:06 +02:00
|
|
|
short left = screenDPI->x;
|
|
|
|
short right = left + screenDPI->width;
|
|
|
|
short top = screenDPI->y;
|
|
|
|
short bottom = top + screenDPI->height;
|
2014-07-18 05:29:39 +02:00
|
|
|
|
|
|
|
rct_window* newWindow = (RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*));
|
|
|
|
|
2014-07-19 01:36:06 +02:00
|
|
|
for (rct_window* w = g_window_list; w < newWindow; w++) {
|
2014-07-20 08:46:29 +02:00
|
|
|
draw_rain_window(w, left, right, top, bottom, draw_rain_func);
|
2014-07-18 05:29:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-28 19:11:33 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684218
|
|
|
|
*/
|
|
|
|
void update_rain_animation()
|
|
|
|
{
|
|
|
|
if (RCT2_GLOBAL(0x009ABDF2, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Draw picked-up peep
|
2014-07-18 22:03:33 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) != 0xFFFFFFFF) {
|
2014-05-28 19:11:33 +02:00
|
|
|
gfx_draw_sprite(
|
|
|
|
(rct_drawpixelinfo*)RCT2_ADDRESS_SCREEN_DPI,
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32),
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16),
|
2014-08-08 20:16:57 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16), 0
|
2014-05-28 19:11:33 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get rain draw function and draw rain
|
2014-08-06 04:42:32 +02:00
|
|
|
uint32 draw_rain_func = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8);
|
|
|
|
if (draw_rain_func > 0 && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1))
|
2014-07-20 08:46:29 +02:00
|
|
|
draw_rain_animation(draw_rain_func);
|
2014-05-28 19:11:33 +02:00
|
|
|
}
|
|
|
|
|
2014-04-02 01:31:55 +02:00
|
|
|
void game_update()
|
|
|
|
{
|
|
|
|
int eax, tmp;
|
|
|
|
|
2014-05-28 19:11:33 +02:00
|
|
|
// Handles picked-up peep and rain redraw
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006843DC);
|
|
|
|
|
2014-04-02 01:31:55 +02:00
|
|
|
// 0x006E3AEC // screen_game_process_mouse_input();
|
2014-04-18 04:04:46 +02:00
|
|
|
// RCT2_CALLPROC_EBPSAFE(0x006E3AEC); // screen_game_process_keyboard_input();
|
2014-04-25 19:25:34 +02:00
|
|
|
screenshot_check();
|
|
|
|
game_handle_keyboard_input();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
// do game logic
|
|
|
|
eax = RCT2_GLOBAL(0x009DE588, uint16) / 31;
|
|
|
|
if (eax == 0)
|
|
|
|
eax = 1;
|
|
|
|
if (eax > 4)
|
|
|
|
eax = 4;
|
|
|
|
|
2014-05-25 04:02:48 +02:00
|
|
|
if (_gameSpeed > 1)
|
|
|
|
eax = 1 << (_gameSpeed - 1);
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x009DEA6E, uint8) == 0) {
|
|
|
|
for (; eax > 0; eax--) {
|
|
|
|
game_logic_update();
|
2014-04-18 17:26:45 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006BD0F8); // play title screen music
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
if (rctmem->dword_009E2D74 == 1) {
|
|
|
|
rctmem->dword_009E2D74 = 0;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if (rctmem->input_state != INPUT_STATE_WIDGET_RESET && rctmem->input_state != INPUT_STATE_WIDGET_NORMAL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
tmp = rctmem->dword_009DE518 & 0x80;
|
|
|
|
rctmem->dword_009DE518 &= ~0x80;
|
|
|
|
if (tmp)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) &= ~0x80;
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) &= ~0x8000;
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) &= ~0x02;
|
|
|
|
tmp = RCT2_GLOBAL(0x009AC861, uint16) & 0x01;
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) &= ~0x01;
|
|
|
|
if (!tmp)
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) |= 0x02;
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) &= ~0x08;
|
|
|
|
tmp = RCT2_GLOBAL(0x009AC861, uint16) & 0x04;
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) &= ~0x04;
|
|
|
|
if (!tmp)
|
|
|
|
RCT2_GLOBAL(0x009AC861, uint16) |= 0x04;
|
|
|
|
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006EE77A);
|
|
|
|
|
2014-04-08 18:52:39 +02:00
|
|
|
window_update_all();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
RCT2_GLOBAL(0x01388698, uint16)++;
|
|
|
|
|
|
|
|
// Input
|
2014-04-13 23:23:56 +02:00
|
|
|
RCT2_GLOBAL(0x0141F568, uint8) = RCT2_GLOBAL(0x0013CA740, uint8);
|
2014-04-14 04:09:51 +02:00
|
|
|
game_handle_input();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2014-05-28 19:11:33 +02:00
|
|
|
update_water_animation();
|
|
|
|
update_rain_animation();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x009AAC73, uint8) != 255) {
|
|
|
|
RCT2_GLOBAL(0x009AAC73, uint8)++;
|
2014-04-24 22:29:57 +02:00
|
|
|
if (RCT2_GLOBAL(0x009AAC73, uint8) == 255)
|
|
|
|
config_save();
|
2014-04-02 01:31:55 +02:00
|
|
|
}
|
|
|
|
}
|
2014-04-11 03:42:39 +02:00
|
|
|
|
2014-04-02 01:31:55 +02:00
|
|
|
void game_logic_update()
|
|
|
|
{
|
2014-04-25 19:25:34 +02:00
|
|
|
short stringId, _dx;
|
2014-04-02 01:31:55 +02:00
|
|
|
|
2014-04-28 22:00:54 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, sint32)++;
|
2014-04-02 01:31:55 +02:00
|
|
|
RCT2_GLOBAL(0x00F663AC, sint32)++;
|
|
|
|
RCT2_GLOBAL(0x009DEA66, sint16)++;
|
|
|
|
if (RCT2_GLOBAL(0x009DEA66, sint16) == 0)
|
|
|
|
RCT2_GLOBAL(0x009DEA66, sint16)--;
|
|
|
|
|
2014-05-04 19:51:36 +02:00
|
|
|
sub_68B089();
|
2014-05-01 19:15:02 +02:00
|
|
|
scenario_update();
|
2014-04-29 13:18:50 +02:00
|
|
|
climate_update();
|
2014-04-02 01:31:55 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006646E1);
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006A876D);
|
2014-04-03 01:22:33 +02:00
|
|
|
peep_update_all();
|
2014-05-25 19:40:11 +02:00
|
|
|
vehicle_update_all();
|
2014-04-09 12:16:35 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x00672AA4); // update text effects
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006ABE4C); // update rides
|
2014-05-25 14:59:31 +02:00
|
|
|
park_update();
|
2014-04-02 01:31:55 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x00684C7A);
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006B5A2A);
|
2014-04-09 12:16:35 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006B6456); // update ride measurements
|
2014-04-02 01:31:55 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x0068AFAD);
|
2014-05-25 04:02:48 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006BBC6B); // vehicle and scream sounds
|
2014-05-25 02:08:08 +02:00
|
|
|
peep_update_crowd_noise();
|
2014-05-28 23:53:28 +02:00
|
|
|
climate_update_sound();
|
2014-04-08 01:05:05 +02:00
|
|
|
news_item_update_current();
|
2014-05-25 04:02:48 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x0067009A); // scenario editor opening of windows for a phase
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
// Update windows
|
2014-04-08 18:52:39 +02:00
|
|
|
window_dispatch_update_all();
|
2014-04-02 01:31:55 +02:00
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x009AC31B, uint8) != 0) {
|
2014-04-25 19:25:34 +02:00
|
|
|
stringId = STR_UNABLE_TO_LOAD_FILE;
|
2014-04-02 01:31:55 +02:00
|
|
|
_dx = RCT2_GLOBAL(0x009AC31C, uint16);
|
|
|
|
if (RCT2_GLOBAL(0x009AC31B, uint8) != 254) {
|
2014-04-25 19:25:34 +02:00
|
|
|
stringId = RCT2_GLOBAL(0x009AC31C, uint16);
|
2014-04-02 01:31:55 +02:00
|
|
|
_dx = 0xFFFF;
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x009AC31B, uint8) = 0;
|
|
|
|
|
2014-04-25 19:25:34 +02:00
|
|
|
window_error_open(stringId, _dx);
|
2014-04-02 01:31:55 +02:00
|
|
|
}
|
2014-04-14 04:09:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void game_handle_input_mouse();
|
2014-04-14 15:32:05 +02:00
|
|
|
static void game_get_next_input(int *x, int *y, int *state);
|
2014-04-14 04:09:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006EA627
|
|
|
|
*/
|
|
|
|
void game_handle_input()
|
|
|
|
{
|
|
|
|
rct_window *w;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x009DEA64, uint16) & 2) {
|
|
|
|
RCT2_GLOBAL(0x009DEA64, uint16) &= ~2;
|
2014-08-06 21:06:51 +02:00
|
|
|
game_do_command(0, 1, 0, 0, GAME_COMMAND_LOAD_OR_QUIT, 2, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x009ABDF2, uint8) != 0) {
|
2014-07-10 22:22:32 +02:00
|
|
|
for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++)
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_07], 0, 0, 0, 0, (int)w, 0, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006EA73F);
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006E8346); // update_cursor_position
|
|
|
|
|
|
|
|
{
|
2014-05-12 03:18:08 +02:00
|
|
|
// int eax, ebx, ecx, edx, esi, edi, ebp;
|
|
|
|
int eax, ebx, ecx;
|
2014-04-14 04:09:51 +02:00
|
|
|
|
|
|
|
for (;;) {
|
2014-04-14 15:32:05 +02:00
|
|
|
game_get_next_input(&eax, &ebx, &ecx);
|
2014-04-14 04:09:51 +02:00
|
|
|
if (ecx == 0)
|
|
|
|
break;
|
|
|
|
|
2014-04-14 15:32:05 +02:00
|
|
|
game_handle_input_mouse(eax, ebx, ecx & 0xFF);
|
|
|
|
// RCT2_CALLPROC_X(0x006E8655, eax, ebx, ecx, 0, 0, 0, 0); // window_process_mouse_input
|
2014-04-14 04:09:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 5)) {
|
2014-04-14 15:32:05 +02:00
|
|
|
game_handle_input_mouse(eax, ebx, ecx);
|
|
|
|
// RCT2_CALLPROC_X(0x006E8655, eax, ebx, 0, 0, 0, 0, 0); // window_process_mouse_input
|
2014-04-14 04:09:51 +02:00
|
|
|
} else if (eax != 0x80000000) {
|
|
|
|
eax = clamp(0, eax, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) - 1);
|
|
|
|
ebx = clamp(0, ebx, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16) - 1);
|
|
|
|
|
2014-04-14 15:32:05 +02:00
|
|
|
game_handle_input_mouse(eax, ebx, ecx);
|
|
|
|
// RCT2_CALLPROC_X(0x006E8655, eax, ebx, 0, 0, 0, 0, 0); // window_process_mouse_input
|
2014-07-26 11:30:55 +02:00
|
|
|
process_mouse_over(eax, ebx);
|
|
|
|
//RCT2_CALLPROC_X(0x006ED833, eax, ebx, 0, 0, 0, 0, 0);
|
2014-07-27 15:34:08 +02:00
|
|
|
sub_0x6ED801(eax, ebx);
|
2014-07-26 11:30:55 +02:00
|
|
|
//RCT2_CALLPROC_EBPSAFE(0x006ED801);
|
2014-04-14 04:09:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-10 22:22:32 +02:00
|
|
|
for (w = g_window_list; w < RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); w++)
|
2014-05-19 19:47:14 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_08], 0, 0, 0, 0,(int) w, 0, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
}
|
|
|
|
|
2014-04-14 15:32:05 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E83C7
|
|
|
|
*/
|
|
|
|
static void game_get_next_input(int *x, int *y, int *state)
|
|
|
|
{
|
|
|
|
int eax, ebx, ecx, edx, esi, edi, ebp;
|
2014-04-18 04:04:46 +02:00
|
|
|
RCT2_CALLFUNC_X(0x00407074, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
if (eax == 0) {
|
|
|
|
*x = gCursorState.x;
|
|
|
|
*y = gCursorState.y;
|
|
|
|
*state = 0;
|
|
|
|
return;
|
|
|
|
}
|
2014-04-14 15:32:05 +02:00
|
|
|
|
2014-04-18 04:04:46 +02:00
|
|
|
*x = RCT2_GLOBAL(eax + 0, sint32);
|
|
|
|
*y = RCT2_GLOBAL(eax + 4, sint32);
|
|
|
|
*state = RCT2_GLOBAL(eax + 8, sint32);
|
2014-04-14 15:32:05 +02:00
|
|
|
|
2014-04-18 04:04:46 +02:00
|
|
|
//int eax, ebx, ecx, edx, esi, edi, ebp;
|
|
|
|
//RCT2_CALLFUNC_X(0x006E83C7, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
//*x = eax & 0xFFFF;
|
|
|
|
//*y = ebx & 0xFFFF;
|
|
|
|
//*state = ecx & 0xFF;
|
|
|
|
//return;
|
2014-04-14 15:32:05 +02:00
|
|
|
|
2014-04-18 04:04:46 +02:00
|
|
|
//int on_tutorial = RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8);
|
|
|
|
//if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 5)) {
|
|
|
|
// if (on_tutorial == 1) {
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
// RCT2_CALLPROC_EBPSAFE(0x00407074);
|
|
|
|
// }
|
|
|
|
// if (on_tutorial == 2) {
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//} else {
|
|
|
|
|
|
|
|
//}
|
2014-04-14 15:32:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
POINT _dragPosition;
|
|
|
|
|
2014-04-24 19:53:42 +02:00
|
|
|
static void input_mouseover(int x, int y, rct_window *w, int widgetIndex);
|
|
|
|
static void input_mouseover_widget_check(rct_windowclass windowClass, rct_windownumber windowNumber, int widgetIndex);
|
|
|
|
static void input_mouseover_widget_flatbutton_invalidate();
|
|
|
|
static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex);
|
|
|
|
|
2014-07-19 13:04:32 +02:00
|
|
|
/**
|
|
|
|
* rct2: 0x006E876D
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void invalidate_scroll(){
|
|
|
|
int window_no = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, uint16);
|
|
|
|
int window_cls = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
|
|
|
|
rct_window* wind = window_find_by_id(window_cls, window_no);
|
|
|
|
if (wind == NULL) return;
|
|
|
|
|
|
|
|
int scroll_id = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
|
|
|
//Reset to basic scroll
|
|
|
|
wind->scrolls[scroll_id / sizeof(rct_scroll)].flags &= 0xFF11;
|
|
|
|
|
|
|
|
window_invalidate_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, uint16));
|
|
|
|
}
|
|
|
|
|
2014-04-14 04:09:51 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E8655
|
|
|
|
*/
|
|
|
|
static void game_handle_input_mouse(int x, int y, int state)
|
|
|
|
{
|
2014-05-12 02:45:45 +02:00
|
|
|
rct_window *w;
|
2014-04-14 15:32:05 +02:00
|
|
|
rct_widget *widget;
|
|
|
|
int widgetIndex;
|
2014-04-14 04:09:51 +02:00
|
|
|
|
2014-04-14 15:32:05 +02:00
|
|
|
// Get window and widget under cursor position
|
2014-04-14 04:09:51 +02:00
|
|
|
w = window_find_from_point(x, y);
|
2014-04-14 15:32:05 +02:00
|
|
|
widgetIndex = w == NULL ? -1 : window_find_widget_from_point(w, x, y);
|
|
|
|
widget = widgetIndex == -1 ? 0 : &w->widgets[widgetIndex];
|
2014-04-14 04:09:51 +02:00
|
|
|
|
|
|
|
switch (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8)) {
|
|
|
|
case INPUT_STATE_RESET:
|
2014-04-24 19:53:42 +02:00
|
|
|
window_tooltip_reset(x, y);
|
|
|
|
// fall-through
|
2014-04-14 04:09:51 +02:00
|
|
|
case INPUT_STATE_NORMAL:
|
2014-04-14 15:32:05 +02:00
|
|
|
switch (state) {
|
|
|
|
case 0:
|
2014-04-24 19:53:42 +02:00
|
|
|
input_mouseover(x, y, w, widgetIndex);
|
2014-04-14 15:32:05 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
2014-04-24 19:53:42 +02:00
|
|
|
input_leftmousedown(x, y, w, widgetIndex);
|
2014-04-14 15:32:05 +02:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
// Close tooltip
|
|
|
|
window_close_by_id(5, 0);
|
|
|
|
|
|
|
|
if (w != NULL)
|
2014-04-28 03:35:23 +02:00
|
|
|
w = window_bring_to_front(w);
|
2014-04-14 15:32:05 +02:00
|
|
|
|
|
|
|
if (widgetIndex == -1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (widget->type == WWT_VIEWPORT) {
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 9)
|
|
|
|
break;
|
|
|
|
w->flags &= ~(1 << 3);
|
2014-04-24 19:53:42 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_DRAG;
|
2014-04-14 15:32:05 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y;
|
2014-04-28 22:00:54 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = w->classification;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = w->number;
|
2014-04-14 15:32:05 +02:00
|
|
|
RCT2_GLOBAL(0x009DE540, sint16) = 0;
|
|
|
|
// hide cursor
|
|
|
|
// RCT2_CALLPROC_X(0x00407045, 0, 0, 0, 0, 0, 0, 0);
|
|
|
|
// RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 5);
|
|
|
|
|
|
|
|
GetCursorPos(&_dragPosition);
|
|
|
|
ShowCursor(FALSE);
|
|
|
|
|
|
|
|
} else if (widget->type == WWT_SCROLL) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
|
|
|
case INPUT_STATE_WIDGET_PRESSED:
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E8DA7, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
|
|
|
case INPUT_STATE_DRAGGING:
|
2014-04-25 04:02:06 +02:00
|
|
|
// RCT2_CALLPROC_X(0x006E8C5C, x, y, state, widgetIndex, w, widget, 0);
|
|
|
|
|
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber));
|
|
|
|
if (w == NULL) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 0) {
|
|
|
|
y = clamp(29, y, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 34);
|
|
|
|
window_move_position(
|
|
|
|
w,
|
|
|
|
x - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16),
|
|
|
|
y - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16)
|
|
|
|
);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y;
|
|
|
|
} else if (state == 2) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_NORMAL;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint16);
|
2014-04-25 04:02:06 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
y = clamp(29, y, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 34);
|
|
|
|
window_move_position(
|
|
|
|
w,
|
|
|
|
x - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16),
|
|
|
|
y - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16)
|
|
|
|
);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y;
|
|
|
|
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_18], 0, 0, x, y, (int)w, 0, 0);
|
2014-04-25 04:02:06 +02:00
|
|
|
}
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
2014-04-24 19:53:42 +02:00
|
|
|
case INPUT_STATE_VIEWPORT_DRAG:
|
2014-04-14 15:32:05 +02:00
|
|
|
{
|
|
|
|
int dx, dy;
|
|
|
|
|
|
|
|
dx = x - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16);
|
|
|
|
dy = y - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16);
|
2014-04-28 22:00:54 +02:00
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber));
|
2014-04-14 15:32:05 +02:00
|
|
|
if (state == 0) {
|
|
|
|
rct_viewport *viewport = w->viewport;
|
|
|
|
RCT2_GLOBAL(0x009DE540, sint16) += RCT2_GLOBAL(0x009DE588, sint16);
|
|
|
|
if (viewport == NULL) {
|
|
|
|
ShowCursor(TRUE);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
|
|
|
} else if (dx != 0 || dy != 0) {
|
|
|
|
if (!(w->flags & (1 << 2))) {
|
|
|
|
RCT2_GLOBAL(0x009DE540, sint16) = 1000;
|
|
|
|
dx <<= viewport->zoom + 1;
|
|
|
|
dy <<= viewport->zoom + 1;
|
2014-05-04 12:56:35 +02:00
|
|
|
w->saved_view_x += dx;
|
|
|
|
w->saved_view_y += dy;
|
2014-04-14 15:32:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (state == 4) {
|
|
|
|
ShowCursor(TRUE);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
|
|
|
if (RCT2_GLOBAL(0x009DE540, sint16) < 500) {
|
|
|
|
// Right click
|
2014-04-14 21:26:29 +02:00
|
|
|
{
|
|
|
|
int eax, ebx, ecx, edx, esi, edi, ebp;
|
|
|
|
eax = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16);
|
|
|
|
ebx = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16);
|
|
|
|
RCT2_CALLFUNC_X(0x006EDE88, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
switch (ebx & 0xFF) {
|
|
|
|
case 2:
|
|
|
|
if (*((uint8*)edx) == 0)
|
2014-08-17 12:57:50 +02:00
|
|
|
RCT2_CALLPROC_X(0x006B4857, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 3:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006CC056, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 5:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E08D2, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 6:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006A614A, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 7:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006A61AB, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 8:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x00666C0E, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 9:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E57A9, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 10:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006B88DC, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
case 12:
|
2014-04-20 04:31:54 +02:00
|
|
|
RCT2_CALLPROC_X(0x006BA233, eax, 0, ecx, edx, 0, 0, 0);
|
2014-04-14 21:26:29 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-04-14 15:32:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-14 21:26:29 +02:00
|
|
|
//
|
|
|
|
//
|
2014-04-14 15:32:05 +02:00
|
|
|
SetCursorPos(_dragPosition.x, _dragPosition.y);
|
|
|
|
// RCT2_CALLPROC_X(0x006E89C6, x - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16), y - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16), state, widgetIndex, w, widget, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
2014-04-14 15:32:05 +02:00
|
|
|
}
|
2014-04-14 04:09:51 +02:00
|
|
|
case INPUT_STATE_DROPDOWN_ACTIVE:
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E8DA7, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
2014-04-24 19:53:42 +02:00
|
|
|
case INPUT_STATE_VIEWPORT_LEFT:
|
2014-08-16 15:40:07 +02:00
|
|
|
//RCT2_CALLPROC_X(0x006E87B4, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
2014-08-15 17:52:18 +02:00
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber));
|
|
|
|
if (!w){
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 0){
|
|
|
|
if (!w->viewport){
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) ||
|
|
|
|
w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) ||
|
|
|
|
!(RCT2_GLOBAL(0x9DE518, uint32)&(1 << 3)))break;
|
|
|
|
|
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber));
|
|
|
|
|
|
|
|
if (!w)break;
|
|
|
|
|
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DRAG], x, y, 0, (int)RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), (int)w, 0, 0);
|
|
|
|
}
|
|
|
|
else if (state == 2){
|
2014-08-16 15:40:07 +02:00
|
|
|
|
2014-08-16 15:38:45 +02:00
|
|
|
RCT2_GLOBAL(0x9DE51D, uint8) = 0;
|
|
|
|
if (RCT2_GLOBAL(0x9DE52E, rct_windownumber) != w->number)break;
|
|
|
|
if ((RCT2_GLOBAL(0x9DE518, uint32)&(1 << 3))){
|
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber));
|
|
|
|
if (!w)break;
|
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_UP], x, y, 0, (int)RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), (int)w, 0, 0);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if ((RCT2_GLOBAL(0x9DE518, uint32)&(1 << 4)))break;
|
|
|
|
rct_sprite* spr;
|
|
|
|
int eax = x, ebx = y, ecx = state, esi = (int)w, edi = (int)widget, ebp = 0;
|
|
|
|
RCT2_CALLFUNC_X(0X6ED9D0, &eax, &ebx, &ecx, (int*)&spr, &esi, &edi, &ebp);
|
|
|
|
if ((ebx & 0xFF) == 2){
|
|
|
|
|
|
|
|
if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_VEHICLE){
|
|
|
|
//Open ride window
|
|
|
|
RCT2_CALLPROC_X(0x6ACAC2, eax, ebx, ecx, (int)spr, esi, edi, ebp);
|
|
|
|
}
|
|
|
|
else if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_PEEP){
|
|
|
|
window_peep_open(&spr->peep);
|
|
|
|
}
|
|
|
|
else if (spr->unknown.sprite_identifier == SPRITE_IDENTIFIER_FLOATING_TEXT){
|
|
|
|
//Unknown for now
|
|
|
|
RCT2_CALLPROC_X(0x6E88D7, eax, ebx, ecx, (int)spr, esi, edi, ebp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ((ebx & 0xFF) == 3){
|
2014-08-19 13:48:00 +02:00
|
|
|
rct_map_element* map_element = (rct_map_element*)spr;
|
|
|
|
|
|
|
|
if (!((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_ENTRANCE)){
|
2014-08-19 21:41:46 +02:00
|
|
|
eax = RCT2_ADDRESS(0x0099BA64, uint8)[16 * map_element->properties.track.type];
|
|
|
|
if (!(eax & 0x10)){//If not station track
|
|
|
|
//Open ride window in overview mode.
|
2014-08-19 13:48:00 +02:00
|
|
|
RCT2_CALLPROC_X(0x6ACC28, map_element->properties.track.ride_index, ebx, ecx, (int)map_element, esi, edi, ebp);
|
2014-08-16 15:38:45 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-08-19 21:41:46 +02:00
|
|
|
//Open ride window in station view
|
2014-08-19 13:48:00 +02:00
|
|
|
RCT2_CALLPROC_X(0x6ACCCE, map_element->properties.track.ride_index, (map_element->properties.track.sequence & 0x70) >> 4, ecx, (int)map_element, esi, edi, ebp);
|
2014-08-16 15:38:45 +02:00
|
|
|
}
|
|
|
|
else if ((ebx & 0xFF) == 8){
|
|
|
|
window_park_entrance_open();
|
|
|
|
}
|
|
|
|
}
|
2014-08-15 17:52:18 +02:00
|
|
|
}
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
2014-07-19 13:04:32 +02:00
|
|
|
case INPUT_STATE_SCROLL_LEFT://0x006E8676
|
|
|
|
//RCT2_CALLPROC_X(0x006E8676, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
2014-07-13 13:13:13 +02:00
|
|
|
if (state == 0){
|
2014-07-14 20:00:25 +02:00
|
|
|
if (widgetIndex != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint32)){
|
2014-07-19 13:04:32 +02:00
|
|
|
invalidate_scroll();
|
|
|
|
return;
|
2014-07-08 22:58:07 +02:00
|
|
|
}
|
2014-07-14 20:00:25 +02:00
|
|
|
if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8)){
|
2014-07-19 13:04:32 +02:00
|
|
|
invalidate_scroll();
|
|
|
|
return;
|
2014-07-08 22:58:07 +02:00
|
|
|
}
|
2014-07-14 20:00:25 +02:00
|
|
|
if (w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, uint16)){
|
2014-07-19 13:04:32 +02:00
|
|
|
invalidate_scroll();
|
|
|
|
return;
|
2014-07-08 22:58:07 +02:00
|
|
|
}
|
|
|
|
|
2014-07-18 16:48:43 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_HSCROLLBAR_THUMB){
|
2014-07-14 20:00:25 +02:00
|
|
|
int temp_x = x;
|
2014-07-18 16:48:43 +02:00
|
|
|
x -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = temp_x;
|
2014-07-19 12:55:34 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E98F2, x, temp_x, state, w->number, (int)w, (int)widget, x);
|
|
|
|
return;
|
2014-07-08 22:58:07 +02:00
|
|
|
}
|
|
|
|
|
2014-07-18 16:48:43 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) == SCROLL_PART_VSCROLLBAR_THUMB){
|
2014-07-19 12:55:34 +02:00
|
|
|
int temp_y = y;
|
2014-07-18 16:48:43 +02:00
|
|
|
y -= RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = temp_y;
|
2014-07-19 12:55:34 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E99A9, temp_y, y, state, w->number, (int)w, (int)widget, y);
|
|
|
|
return;
|
2014-07-08 22:58:07 +02:00
|
|
|
}
|
2014-07-19 13:04:32 +02:00
|
|
|
int scroll_part, scroll_id;
|
|
|
|
widget_scroll_get_part(w, widget, x, y, &x, &y, &scroll_part, &scroll_id);
|
2014-07-18 16:48:43 +02:00
|
|
|
|
|
|
|
if (scroll_part != RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16)){
|
2014-07-19 13:04:32 +02:00
|
|
|
invalidate_scroll();
|
|
|
|
return;
|
2014-07-13 13:13:13 +02:00
|
|
|
}
|
|
|
|
|
2014-07-18 16:48:43 +02:00
|
|
|
switch (scroll_part){
|
|
|
|
case SCROLL_PART_VIEW:
|
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DRAG], w->number / 18, y, x, y, (int)w, (int)widget, (int)w->event_handlers);
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
2014-07-18 16:48:43 +02:00
|
|
|
case SCROLL_PART_HSCROLLBAR_LEFT:
|
|
|
|
RCT2_CALLPROC_X(0x006E9A60, x, y, scroll_part, w->number, (int)w, (int)widget, 0);
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
2014-07-18 16:48:43 +02:00
|
|
|
case SCROLL_PART_HSCROLLBAR_RIGHT:
|
|
|
|
RCT2_CALLPROC_X(0x006E9ABF, x, y, scroll_part, w->number, (int)w, (int)widget, 0);
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
2014-07-18 16:48:43 +02:00
|
|
|
case SCROLL_PART_HSCROLLBAR_LEFT_TROUGH:
|
|
|
|
case SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH:
|
2014-07-14 20:00:25 +02:00
|
|
|
return;
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
2014-07-18 16:53:46 +02:00
|
|
|
case SCROLL_PART_HSCROLLBAR_THUMB:
|
2014-07-18 16:48:43 +02:00
|
|
|
case SCROLL_PART_VSCROLLBAR_TOP:
|
|
|
|
RCT2_CALLPROC_X(0x006E9C37, x, y, scroll_part, w->number, (int)w, (int)widget, 0);
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
2014-07-18 16:48:43 +02:00
|
|
|
case SCROLL_PART_VSCROLLBAR_BOTTOM:
|
|
|
|
RCT2_CALLPROC_X(0x006E9C96, x, y, scroll_part, w->number, (int)w, (int)widget, 0);
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
2014-07-18 16:48:43 +02:00
|
|
|
case SCROLL_PART_VSCROLLBAR_TOP_TROUGH:
|
|
|
|
case SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH:
|
2014-07-14 20:00:25 +02:00
|
|
|
return;
|
2014-07-13 13:13:13 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}else if (state==2){
|
2014-07-19 13:04:32 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
|
|
|
invalidate_scroll();
|
|
|
|
return;
|
2014-07-08 22:58:07 +02:00
|
|
|
}
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
|
|
|
case INPUT_STATE_RESIZING:
|
2014-04-25 04:02:06 +02:00
|
|
|
// RCT2_CALLPROC_X(0x006E8B46, x, y, state, widgetIndex, w, widget, 0);
|
|
|
|
|
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber));
|
|
|
|
if (w == NULL) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESET;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state != 0 && state != 2)
|
|
|
|
break;
|
|
|
|
if (state == 2) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_NORMAL;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint16);
|
2014-04-25 04:02:06 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y < RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 2) {
|
|
|
|
window_resize(
|
|
|
|
w,
|
|
|
|
x - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16),
|
|
|
|
y - RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y;
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
|
|
|
case 9:
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(0x006E8ACB, x, y, state, widgetIndex, (int)w, (int)widget, 0);
|
2014-04-14 04:09:51 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-04-21 11:27:48 +02:00
|
|
|
}
|
2014-04-24 19:53:42 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E9253
|
|
|
|
*/
|
|
|
|
static void input_mouseover(int x, int y, rct_window *w, int widgetIndex)
|
|
|
|
{
|
|
|
|
// RCT2_CALLPROC_X(0x006E9253, x, y, state, widgetIndex, w, widget, 0);
|
|
|
|
|
|
|
|
rct_windowclass windowClass = 255;
|
|
|
|
rct_windownumber windowNumber = 0;
|
|
|
|
rct_widget *widget;
|
|
|
|
|
|
|
|
if (w != NULL) {
|
|
|
|
windowClass = w->classification;
|
|
|
|
windowNumber = w->number;
|
|
|
|
widget = &w->widgets[widgetIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
input_mouseover_widget_check(windowClass, windowNumber, widgetIndex);
|
|
|
|
|
2014-06-13 22:40:15 +02:00
|
|
|
if (w != NULL && widgetIndex != -1 && widget->type == WWT_SCROLL)
|
|
|
|
{
|
|
|
|
int eax, ebx, ecx, edx;
|
|
|
|
widget_scroll_get_part(w, widget, x, y, &eax, &ebx, &ecx, &edx);
|
|
|
|
|
2014-04-24 19:53:42 +02:00
|
|
|
if (ecx < 0)
|
|
|
|
goto showTooltip;
|
|
|
|
if (ecx == 0) {
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_SCROLL_MOUSEOVER], edx, 0, eax, ebx, (int)w, 0, 0);
|
2014-04-24 19:53:42 +02:00
|
|
|
goto showTooltip;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
showTooltip:
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) == 255) {
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) < 500 ||
|
|
|
|
(RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, sint16) == x &&
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, sint16) == y)
|
|
|
|
) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = RCT2_GLOBAL(0x009DE588, uint16);
|
|
|
|
|
|
|
|
int bp = 2000;
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) <= 1000)
|
|
|
|
bp = 0;
|
|
|
|
if (bp > RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16))
|
|
|
|
return;
|
|
|
|
|
|
|
|
window_tooltip_open(w, widgetIndex, x, y);
|
|
|
|
// RCT2_CALLPROC_X(0x006EA10D, x, y, 0, widgetIndex, w, widget, 0); // window_tooltip_open();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) != w->classification ||
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) != w->number ||
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) != widgetIndex
|
|
|
|
) {
|
|
|
|
window_tooltip_close();
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) += RCT2_GLOBAL(0x009DE588, uint16);
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) < 8000)
|
|
|
|
return;
|
|
|
|
window_close_by_id(WC_TOOLTIP, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, sint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, sint16) = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E9269
|
|
|
|
*/
|
|
|
|
static void input_mouseover_widget_check(rct_windowclass windowClass, rct_windownumber windowNumber, int widgetIndex)
|
|
|
|
{
|
2014-07-15 18:56:42 +02:00
|
|
|
if (widgetIndex == -1) return; //Prevents invalid widgets being clicked source of bug is elsewhere
|
2014-04-24 19:53:42 +02:00
|
|
|
// Check if widget cursor was over has changed
|
|
|
|
if (windowClass != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass) ||
|
|
|
|
windowNumber != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windownumber) ||
|
|
|
|
widgetIndex != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, rct_windownumber)
|
|
|
|
) {
|
|
|
|
// Invalidate last widget cursor was on if widget is a flat button
|
|
|
|
input_mouseover_widget_flatbutton_invalidate();
|
|
|
|
|
|
|
|
// Set new cursor over widget
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass) = windowClass;
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, uint16) = widgetIndex;
|
2014-04-24 19:53:42 +02:00
|
|
|
|
|
|
|
// Invalidate new widget cursor is on if widget is a flat button
|
|
|
|
if (windowClass != 255)
|
|
|
|
input_mouseover_widget_flatbutton_invalidate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void input_mouseover_widget_flatbutton_invalidate()
|
|
|
|
{
|
|
|
|
rct_window *w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windownumber));
|
|
|
|
if (w == NULL)
|
|
|
|
return;
|
|
|
|
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
|
2014-04-24 19:53:42 +02:00
|
|
|
if (w->widgets[RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, rct_windownumber)].type == WWT_FLATBTN)
|
|
|
|
widget_invalidate(RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windownumber), RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, rct_windownumber));
|
|
|
|
}
|
|
|
|
|
2014-05-28 23:22:09 +02:00
|
|
|
static void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_window*w, rct_widget* widget )
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
__asm {
|
|
|
|
push address
|
|
|
|
push widget
|
|
|
|
push w
|
|
|
|
push widgetIndex
|
|
|
|
mov edi, widget
|
|
|
|
mov edx, widgetIndex
|
|
|
|
mov esi, w
|
|
|
|
call[esp + 12]
|
|
|
|
add esp, 16
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
__asm__("\
|
|
|
|
push %[address]\n\
|
2014-05-29 01:19:09 +02:00
|
|
|
mov edi, %[widget] \n\
|
2014-05-28 23:22:09 +02:00
|
|
|
mov eax, %[w] \n\
|
2014-05-29 01:19:09 +02:00
|
|
|
mov edx, %[widgetIndex] \n\
|
2014-05-28 23:22:09 +02:00
|
|
|
push edi \n\
|
2014-05-29 01:19:09 +02:00
|
|
|
push eax \n\
|
|
|
|
push edx \n\
|
2014-05-28 23:22:09 +02:00
|
|
|
mov esi, %[w] \n\
|
|
|
|
call [esp+12] \n\
|
|
|
|
add esp, 16 \n\
|
2014-05-29 01:19:09 +02:00
|
|
|
" :[address] "+m" (address), [w] "+m" (w), [widget] "+m" (widget), [widgetIndex] "+m" (widgetIndex): : "eax", "esi", "edx", "edi"
|
|
|
|
);
|
2014-05-28 23:22:09 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-07-11 14:41:42 +02:00
|
|
|
/**
|
|
|
|
* Horizontal scrollbar's "left" button held down, scroll it to the left
|
|
|
|
* rct2: 0x006E9A60
|
|
|
|
*/
|
|
|
|
static void input_hscrollbar_leftbutton(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 left;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 14:41:42 +02:00
|
|
|
|
|
|
|
left = scroll->h_left;
|
|
|
|
left -= 3;
|
|
|
|
if (left < 0)
|
|
|
|
left = 0;
|
|
|
|
scroll->h_left = left;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Horizontal scrollbar's "right" button held down, scroll it to the right
|
|
|
|
* rct2: 0x006E9ABF
|
|
|
|
*/
|
|
|
|
static void input_hscrollbar_rightbutton(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 left, widgetWidth;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 14:41:42 +02:00
|
|
|
|
|
|
|
left = scroll->h_left;
|
|
|
|
left += 3;
|
|
|
|
|
|
|
|
widgetWidth = widget->right - widget->left - 1;
|
2014-07-27 16:39:20 +02:00
|
|
|
if (scroll->flags & VSCROLLBAR_VISIBLE)
|
2014-07-11 14:41:42 +02:00
|
|
|
widgetWidth -= 11;
|
|
|
|
widgetWidth *= -1;
|
|
|
|
widgetWidth += scroll->h_right;
|
2014-07-11 21:22:26 +02:00
|
|
|
if (widgetWidth < 0)
|
2014-07-11 14:41:42 +02:00
|
|
|
widgetWidth = 0;
|
2014-07-11 21:22:26 +02:00
|
|
|
if (left > widgetWidth)
|
2014-07-11 14:41:42 +02:00
|
|
|
left = widgetWidth;
|
|
|
|
|
|
|
|
scroll->h_left = left;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
2014-07-11 21:21:17 +02:00
|
|
|
/**
|
|
|
|
* Horizontal scrollbar's left trough was clicked
|
|
|
|
* rct2: 0x006E9B47
|
|
|
|
*/
|
|
|
|
static void input_hscrollbar_left_trough(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 left, widgetWidth;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 21:21:17 +02:00
|
|
|
|
|
|
|
left = scroll->h_left;
|
|
|
|
|
|
|
|
widgetWidth = widget->right - widget->left - 1;
|
2014-07-27 16:39:20 +02:00
|
|
|
if (scroll->flags & VSCROLLBAR_VISIBLE)
|
2014-07-11 21:21:17 +02:00
|
|
|
widgetWidth -= 11;
|
|
|
|
left -= widgetWidth;
|
|
|
|
if (left < 0)
|
|
|
|
left = 0;
|
|
|
|
scroll->h_left = left;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
2014-07-11 21:36:11 +02:00
|
|
|
/**
|
|
|
|
* Horizontal scrollbar's right trough was clicked
|
|
|
|
* rct2: 0x006E9BB7
|
|
|
|
*/
|
|
|
|
static void input_hscrollbar_right_trough(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 left, widgetWidth;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 21:36:11 +02:00
|
|
|
|
|
|
|
left = scroll->h_left;
|
|
|
|
|
|
|
|
widgetWidth = widget->right - widget->left - 1;
|
2014-07-27 16:39:20 +02:00
|
|
|
if (scroll->flags & VSCROLLBAR_VISIBLE)
|
2014-07-11 21:36:11 +02:00
|
|
|
widgetWidth -= 11;
|
|
|
|
left += widgetWidth;
|
|
|
|
widgetWidth *= -1;
|
|
|
|
widgetWidth += scroll->h_right;
|
|
|
|
if (widgetWidth < 0)
|
|
|
|
widgetWidth = 0;
|
|
|
|
if (left > widgetWidth)
|
|
|
|
left = widgetWidth;
|
|
|
|
|
|
|
|
scroll->h_left = left;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
2014-07-11 14:41:42 +02:00
|
|
|
/**
|
|
|
|
* Vertical scrollbar's "top" button held down, scroll it upwards
|
|
|
|
* rct2: 0x006E9C37
|
|
|
|
*/
|
|
|
|
static void input_vscrollbar_topbutton(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 top;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 14:41:42 +02:00
|
|
|
|
|
|
|
top = scroll->v_top;
|
|
|
|
top -= 3;
|
|
|
|
if (top < 0)
|
|
|
|
top = 0;
|
|
|
|
scroll->v_top = top;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Vertical scrollbar's "bottom" button held down, scroll it downwards
|
|
|
|
* rct2: 0x006E9C96
|
|
|
|
*/
|
|
|
|
static void input_vscrollbar_bottombutton(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 top, widgetHeight;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 14:41:42 +02:00
|
|
|
|
|
|
|
top = scroll->v_top;
|
|
|
|
top += 3;
|
|
|
|
|
|
|
|
widgetHeight = widget->bottom - widget->top - 1;
|
2014-07-27 16:39:20 +02:00
|
|
|
if (scroll->flags & HSCROLLBAR_VISIBLE)
|
2014-07-11 14:41:42 +02:00
|
|
|
widgetHeight -= 11;
|
|
|
|
widgetHeight *= -1;
|
|
|
|
widgetHeight += scroll->v_bottom;
|
2014-07-11 21:22:26 +02:00
|
|
|
if (widgetHeight < 0)
|
2014-07-11 14:41:42 +02:00
|
|
|
widgetHeight = 0;
|
2014-07-11 21:22:26 +02:00
|
|
|
if (top > widgetHeight)
|
2014-07-11 14:41:42 +02:00
|
|
|
top = widgetHeight;
|
|
|
|
|
|
|
|
scroll->v_top = top;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
2014-07-11 21:39:54 +02:00
|
|
|
/**
|
|
|
|
* Vertical scrollbar's top trough was clicked
|
|
|
|
* rct2: 0x006E9D1E
|
|
|
|
*/
|
|
|
|
static void input_vscrollbar_top_trough(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 top, widgetHeight;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 21:39:54 +02:00
|
|
|
|
|
|
|
top = scroll->v_top;
|
|
|
|
|
|
|
|
widgetHeight = widget->bottom - widget->top - 1;
|
2014-07-27 16:39:20 +02:00
|
|
|
if (scroll->flags & HSCROLLBAR_VISIBLE)
|
2014-07-11 21:39:54 +02:00
|
|
|
widgetHeight -= 11;
|
|
|
|
top -= widgetHeight;
|
|
|
|
if (top < 0)
|
|
|
|
top = 0;
|
|
|
|
scroll->v_top = top;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
2014-07-11 21:43:51 +02:00
|
|
|
/**
|
|
|
|
* Vertical scrollbar's bottom trough was clicked
|
|
|
|
* rct2: 0x006E9D8E
|
|
|
|
*/
|
|
|
|
static void input_vscrollbar_bottom_trough(rct_window* w)
|
|
|
|
{
|
|
|
|
rct_windowclass windowClass;
|
|
|
|
rct_windownumber windowNumber;
|
|
|
|
rct_window* w2;
|
|
|
|
rct_widget* widget;
|
|
|
|
rct_scroll* scroll;
|
|
|
|
uint16 widgetIndex;
|
|
|
|
sint16 top, widgetHeight;
|
|
|
|
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass);
|
|
|
|
windowNumber = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber);
|
|
|
|
w2 = window_find_by_id(windowClass, windowNumber);
|
|
|
|
|
|
|
|
if (w2 == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16);
|
|
|
|
|
|
|
|
widget = &w->widgets[widgetIndex];
|
2014-07-18 16:48:43 +02:00
|
|
|
scroll = w->scrolls + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32);
|
2014-07-11 21:43:51 +02:00
|
|
|
|
|
|
|
top = scroll->v_top;
|
|
|
|
|
|
|
|
widgetHeight = widget->bottom - widget->top - 1;
|
2014-07-27 16:39:20 +02:00
|
|
|
if (scroll->flags & HSCROLLBAR_VISIBLE)
|
2014-07-11 21:43:51 +02:00
|
|
|
widgetHeight -= 11;
|
|
|
|
top += widgetHeight;
|
|
|
|
widgetHeight *= -1;
|
|
|
|
widgetHeight += scroll->v_bottom;
|
|
|
|
if (widgetHeight < 0)
|
|
|
|
widgetHeight = 0;
|
|
|
|
if (top > widgetHeight)
|
|
|
|
top = widgetHeight;
|
|
|
|
|
|
|
|
scroll->v_top = top;
|
|
|
|
|
|
|
|
widget_scroll_update_thumbs(w, widgetIndex);
|
|
|
|
|
|
|
|
widgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint8);
|
|
|
|
windowClass = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, uint8);
|
|
|
|
windowClass |= 0x80;
|
|
|
|
|
|
|
|
window_invalidate_by_id(widgetIndex, windowClass);
|
|
|
|
}
|
|
|
|
|
2014-04-24 19:53:42 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E95F9
|
|
|
|
*/
|
|
|
|
static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex)
|
|
|
|
{
|
|
|
|
// RCT2_CALLPROC_X(0x006E95F9, x, y, state, widgetIndex, w, widget, 0);
|
|
|
|
|
|
|
|
rct_windowclass windowClass = 255;
|
|
|
|
rct_windownumber windowNumber = 0;
|
|
|
|
rct_widget *widget;
|
|
|
|
|
|
|
|
if (w != NULL) {
|
|
|
|
windowClass = w->classification;
|
|
|
|
windowNumber = w->number;
|
|
|
|
}
|
|
|
|
|
|
|
|
window_close_by_id(WC_ERROR, 0);
|
|
|
|
window_close_by_id(WC_TOOLTIP, 0);
|
|
|
|
|
|
|
|
w = window_find_by_id(windowClass, windowNumber);
|
|
|
|
if (w == NULL)
|
|
|
|
return;
|
|
|
|
|
2014-04-28 03:35:23 +02:00
|
|
|
w = window_bring_to_front(w);
|
2014-04-24 19:53:42 +02:00
|
|
|
if (widgetIndex == -1)
|
|
|
|
return;
|
|
|
|
|
2014-05-23 12:28:35 +02:00
|
|
|
widget = &w->widgets[widgetIndex];
|
|
|
|
|
2014-04-24 19:53:42 +02:00
|
|
|
switch (widget->type) {
|
|
|
|
case WWT_FRAME:
|
|
|
|
case WWT_RESIZE:
|
|
|
|
if (!(w->flags & WF_RESIZABLE))
|
|
|
|
break;
|
|
|
|
if (w->min_width == w->max_width && w->min_height == w->max_height)
|
|
|
|
break;
|
|
|
|
if (x < w->x + w->width - 19 || y < w->y + w->height - 19)
|
|
|
|
break;
|
|
|
|
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_RESIZING;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, uint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, uint16) = y;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = windowClass;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
|
|
|
break;
|
|
|
|
case WWT_VIEWPORT:
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_LEFT;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, uint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, uint16) = y;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = windowClass;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
|
|
|
if (!(RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)))
|
|
|
|
break;
|
|
|
|
|
2014-04-25 04:02:06 +02:00
|
|
|
w = window_find_by_id(RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass), RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber));
|
2014-04-24 19:53:42 +02:00
|
|
|
if (w == NULL)
|
|
|
|
break;
|
|
|
|
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DOWN], x, y, 0, RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), (int)w, 0, 0);
|
2014-04-24 19:53:42 +02:00
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 4);
|
|
|
|
break;
|
|
|
|
case WWT_CAPTION:
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_DRAGGING;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, uint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, uint16) = y;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = windowClass;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
|
|
|
break;
|
|
|
|
case WWT_SCROLL:
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_SCROLL_LEFT;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = windowClass;
|
2014-04-28 03:35:23 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
2014-04-24 19:53:42 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = x;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = y;
|
|
|
|
|
2014-06-13 22:40:15 +02:00
|
|
|
int eax, ebx, ecx, edx;
|
2014-07-11 14:41:42 +02:00
|
|
|
edx = 0; // safety
|
2014-06-13 22:40:15 +02:00
|
|
|
widget_scroll_get_part(w, widget, x, y, &eax, &ebx, &ecx, &edx);
|
2014-04-24 19:53:42 +02:00
|
|
|
|
2014-07-18 16:48:43 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_AREA, uint16) = ecx;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32) = edx * 12;//We do this because scroll id is not all decompiled
|
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_15], RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SCROLL_ID, uint32), ebx, ecx, edx, (int)w, (int)widget, 0);
|
2014-04-24 19:53:42 +02:00
|
|
|
switch (ecx) {
|
|
|
|
case SCROLL_PART_VIEW:
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(w->event_handlers[WE_SCROLL_MOUSEDOWN], edx / sizeof(rct_scroll), ebx, eax, ebx, (int)w, (int)widget, 0);
|
2014-04-24 19:53:42 +02:00
|
|
|
break;
|
2014-07-11 21:49:01 +02:00
|
|
|
case SCROLL_PART_HSCROLLBAR_LEFT: input_hscrollbar_leftbutton(w); break;
|
|
|
|
case SCROLL_PART_HSCROLLBAR_RIGHT: input_hscrollbar_rightbutton(w); break;
|
|
|
|
case SCROLL_PART_HSCROLLBAR_LEFT_TROUGH: input_hscrollbar_left_trough(w); break;
|
|
|
|
case SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH: input_hscrollbar_right_trough(w); break;
|
|
|
|
case SCROLL_PART_VSCROLLBAR_TOP: input_vscrollbar_topbutton(w); break;
|
|
|
|
case SCROLL_PART_VSCROLLBAR_BOTTOM: input_vscrollbar_bottombutton(w); break;
|
|
|
|
case SCROLL_PART_VSCROLLBAR_TOP_TROUGH: input_vscrollbar_top_trough(w); break;
|
|
|
|
case SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH: input_vscrollbar_bottom_trough(w); break;
|
2014-04-24 19:53:42 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2014-05-24 21:17:23 +02:00
|
|
|
// comment check as it disables the rotate station/building button in construction window
|
|
|
|
// if (!widget_is_enabled(w, widgetIndex))
|
|
|
|
// break;
|
2014-04-24 19:53:42 +02:00
|
|
|
if (widget_is_disabled(w, widgetIndex))
|
|
|
|
break;
|
|
|
|
|
2014-05-25 23:08:36 +02:00
|
|
|
sound_play_panned(SOUND_CLICK_1, w->x + (widget->left + widget->right) / 2);
|
2014-04-24 19:53:42 +02:00
|
|
|
|
|
|
|
// Set new cursor down widget
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = windowClass;
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint16) = widgetIndex;
|
2014-04-24 19:53:42 +02:00
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 0);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_WIDGET_PRESSED;
|
|
|
|
RCT2_GLOBAL(0x009DE528, uint16) = 1;
|
|
|
|
|
|
|
|
widget_invalidate(windowClass, windowNumber, widgetIndex);
|
2014-05-28 23:22:09 +02:00
|
|
|
RCT2_CALLPROC_WE_MOUSE_DOWN(w->event_handlers[WE_MOUSE_DOWN], widgetIndex, w, widget);
|
2014-04-24 19:53:42 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-04-25 19:25:34 +02:00
|
|
|
}
|
|
|
|
|
2014-04-26 02:16:32 +02:00
|
|
|
void game_handle_edge_scroll()
|
|
|
|
{
|
|
|
|
rct_window *mainWindow;
|
|
|
|
int scrollX, scrollY;
|
|
|
|
|
|
|
|
mainWindow = window_get_main();
|
|
|
|
if (mainWindow == NULL)
|
|
|
|
return;
|
|
|
|
if ((mainWindow->flags & WF_2) || (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 9))
|
|
|
|
return;
|
|
|
|
if (mainWindow->viewport == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
scrollX = 0;
|
|
|
|
scrollY = 0;
|
|
|
|
|
|
|
|
// Scroll left / right
|
|
|
|
if (gCursorState.x == 0)
|
|
|
|
scrollX = -1;
|
|
|
|
else if (gCursorState.x == RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) - 1)
|
|
|
|
scrollX = 1;
|
|
|
|
|
|
|
|
// Scroll up / down
|
|
|
|
if (gCursorState.y == 0)
|
|
|
|
scrollY = -1;
|
|
|
|
else if (gCursorState.y == RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 1)
|
|
|
|
scrollY = 1;
|
|
|
|
|
|
|
|
// Scroll viewport
|
|
|
|
if (scrollX != 0) {
|
2014-05-04 12:56:35 +02:00
|
|
|
mainWindow->saved_view_x += scrollX * (12 << mainWindow->viewport->zoom);
|
2014-04-26 02:16:32 +02:00
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 7);
|
|
|
|
}
|
|
|
|
if (scrollY != 0) {
|
2014-05-04 12:56:35 +02:00
|
|
|
mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom);
|
2014-04-26 02:16:32 +02:00
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <SDL_keycode.h>
|
|
|
|
|
|
|
|
void game_handle_key_scroll()
|
|
|
|
{
|
|
|
|
rct_window *mainWindow;
|
|
|
|
int scrollX, scrollY;
|
|
|
|
|
|
|
|
mainWindow = window_get_main();
|
|
|
|
if (mainWindow == NULL)
|
|
|
|
return;
|
|
|
|
if ((mainWindow->flags & WF_2) || (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 9))
|
|
|
|
return;
|
|
|
|
if (mainWindow->viewport == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
scrollX = 0;
|
|
|
|
scrollY = 0;
|
|
|
|
|
|
|
|
// Scroll left / right
|
|
|
|
if (gKeysState[SDL_SCANCODE_LEFT])
|
|
|
|
scrollX = -1;
|
|
|
|
else if (gKeysState[SDL_SCANCODE_RIGHT])
|
|
|
|
scrollX = 1;
|
|
|
|
|
|
|
|
// Scroll up / down
|
|
|
|
if (gKeysState[SDL_SCANCODE_UP])
|
|
|
|
scrollY = -1;
|
|
|
|
else if (gKeysState[SDL_SCANCODE_DOWN])
|
|
|
|
scrollY = 1;
|
|
|
|
|
|
|
|
// Scroll viewport
|
|
|
|
if (scrollX != 0) {
|
2014-05-04 12:56:35 +02:00
|
|
|
mainWindow->saved_view_x += scrollX * (12 << mainWindow->viewport->zoom);
|
2014-04-26 02:16:32 +02:00
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 7);
|
|
|
|
}
|
|
|
|
if (scrollY != 0) {
|
2014-05-04 12:56:35 +02:00
|
|
|
mainWindow->saved_view_y += scrollY * (12 << mainWindow->viewport->zoom);
|
2014-04-26 02:16:32 +02:00
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00406CD2
|
|
|
|
*/
|
|
|
|
int get_next_key()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 221; i++) {
|
2014-04-28 16:06:07 +02:00
|
|
|
if (gKeysPressed[i]) {
|
|
|
|
gKeysPressed[i] = 0;
|
2014-04-26 02:16:32 +02:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-05-10 00:05:50 +02:00
|
|
|
void handle_shortcut_command(int shortcutIndex)
|
|
|
|
{
|
|
|
|
rct_window *window;
|
2014-05-09 09:47:20 +02:00
|
|
|
|
2014-05-10 00:05:50 +02:00
|
|
|
switch (shortcutIndex) {
|
|
|
|
case SHORTCUT_CLOSE_TOP_MOST_WINDOW:
|
2014-05-09 09:47:20 +02:00
|
|
|
window_close_top();
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_CLOSE_ALL_FLOATING_WINDOWS:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2))
|
2014-05-09 09:47:20 +02:00
|
|
|
window_close_all();
|
2014-05-12 02:45:45 +02:00
|
|
|
else if (RCT2_GLOBAL(0x0141F570, uint8) == 1)
|
2014-05-09 09:47:20 +02:00
|
|
|
window_close_top();
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_CANCEL_CONSTRUCTION_MODE:
|
2014-05-09 09:47:20 +02:00
|
|
|
window = window_find_by_id(WC_ERROR, 0);
|
2014-05-10 00:05:50 +02:00
|
|
|
if (window != NULL)
|
2014-05-09 09:47:20 +02:00
|
|
|
window_close(window);
|
2014-05-10 00:05:50 +02:00
|
|
|
else if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3))
|
2014-05-09 09:47:20 +02:00
|
|
|
tool_cancel();
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_PAUSE_GAME:
|
2014-05-09 09:47:20 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 10)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 0, WE_MOUSE_UP);
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_ZOOM_VIEW_OUT:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 8)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 2, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_ZOOM_VIEW_IN:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 8)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 3, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_ROTATE_VIEW:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 8)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 4, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_ROTATE_CONSTRUCTION_OBJECT:
|
2014-05-09 09:47:20 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006E4182);
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_UNDERGROUND_VIEW_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_UNDERGROUND_INSIDE;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_REMOVE_BASE_LAND_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_HIDE_BASE;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_REMOVE_VERTICAL_LAND_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_HIDE_VERTICAL;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SEE_THROUGH_RIDES_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_RIDES;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SEE_THROUGH_SCENERY_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_SEETHROUGH_SCENERY;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_INVISIBLE_SUPPORTS_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_INVISIBLE_SUPPORTS;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_INVISIBLE_PEOPLE_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_INVISIBLE_PEEPS;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_HEIGHT_MARKS_ON_LAND_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_LAND_HEIGHTS;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_HEIGHT_MARKS_ON_RIDE_TRACKS_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_TRACK_HEIGHTS;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_HEIGHT_MARKS_ON_PATHS_TOGGLE:
|
2014-08-19 22:29:36 +02:00
|
|
|
window = window_get_main();
|
|
|
|
if (window != NULL) {
|
|
|
|
window->viewport->flags ^= VIEWPORT_FLAG_PATH_HEIGHTS;
|
|
|
|
window_invalidate(window);
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_ADJUST_LAND:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 7, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_ADJUST_WATER:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 8, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_BUILD_SCENERY:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 9, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_BUILD_PATHS:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 10, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_BUILD_NEW_RIDE:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 11, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_FINANCIAL_INFORMATION:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C))
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800))
|
2014-05-26 00:17:55 +02:00
|
|
|
window_finances_open();
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_RESEARCH_INFORMATION:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) {
|
|
|
|
// Open new ride window
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006B3CFF);
|
|
|
|
window = window_find_by_id(WC_CONSTRUCT_RIDE, 0);
|
|
|
|
if (window != NULL)
|
2014-05-29 18:22:32 +02:00
|
|
|
RCT2_CALLPROC_WE_MOUSE_DOWN(window->event_handlers[WE_MOUSE_DOWN], 10, window, NULL);
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_RIDES_LIST:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
2014-05-09 09:47:20 +02:00
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 12, WE_MOUSE_UP);
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_PARK_INFORMATION:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
2014-05-09 09:47:20 +02:00
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 13, WE_MOUSE_UP);
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_GUEST_LIST:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
2014-05-09 09:47:20 +02:00
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 15, WE_MOUSE_UP);
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_STAFF_LIST:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) {
|
2014-05-09 09:47:20 +02:00
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 14, WE_MOUSE_UP);
|
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_RECENT_MESSAGES:
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E))
|
|
|
|
window_news_open();
|
|
|
|
break;
|
|
|
|
case SHORTCUT_SHOW_MAP:
|
2014-05-12 02:45:45 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) || RCT2_GLOBAL(0x0141F570, uint8) == 1) {
|
2014-05-10 00:05:50 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C)) {
|
|
|
|
window = window_find_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (window != NULL) {
|
|
|
|
window_invalidate(window);
|
|
|
|
window_event_helper(window, 6, WE_MOUSE_UP);
|
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_SCREENSHOT:
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006E4034); // set screenshot countdown to 2
|
|
|
|
break;
|
2014-05-25 04:02:48 +02:00
|
|
|
|
|
|
|
// New
|
|
|
|
case SHORTCUT_REDUCE_GAME_SPEED:
|
2014-07-21 14:05:43 +02:00
|
|
|
game_reduce_game_speed();
|
2014-05-25 04:02:48 +02:00
|
|
|
break;
|
|
|
|
case SHORTCUT_INCREASE_GAME_SPEED:
|
2014-07-21 14:05:43 +02:00
|
|
|
game_increase_game_speed();
|
2014-05-25 04:02:48 +02:00
|
|
|
break;
|
2014-04-26 02:16:32 +02:00
|
|
|
}
|
2014-05-10 00:05:50 +02:00
|
|
|
}
|
2014-07-21 14:05:43 +02:00
|
|
|
|
|
|
|
void game_increase_game_speed()
|
|
|
|
{
|
|
|
|
_gameSpeed = min(8, _gameSpeed + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void game_reduce_game_speed()
|
2014-07-16 04:41:12 +02:00
|
|
|
{
|
2014-07-21 14:05:43 +02:00
|
|
|
_gameSpeed = max(1, _gameSpeed - 1);
|
2014-07-16 04:41:12 +02:00
|
|
|
}
|
2014-05-09 09:47:20 +02:00
|
|
|
|
2014-05-10 00:05:50 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E3E68
|
|
|
|
*/
|
|
|
|
void handle_shortcut(int key)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < SHORTCUT_COUNT; i++) {
|
|
|
|
if (key == gShortcutKeys[i]) {
|
|
|
|
handle_shortcut_command(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-04-26 02:16:32 +02:00
|
|
|
}
|
2014-04-25 19:25:34 +02:00
|
|
|
|
2014-04-26 02:16:32 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E3E91
|
|
|
|
*/
|
|
|
|
void set_shortcut(int key)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
// Unmap shortcut that already uses this key
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
|
|
if (key == gShortcutKeys[i]) {
|
|
|
|
gShortcutKeys[i] = 0xFFFF;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Map shortcut to this key
|
|
|
|
gShortcutKeys[RCT2_GLOBAL(0x009DE511, uint8)] = key;
|
|
|
|
window_close_by_id(WC_CHANGE_KEYBOARD_SHORTCUT, 0);
|
|
|
|
window_invalidate_by_id(WC_KEYBOARD_SHORTCUT_LIST, 0);
|
|
|
|
config_save();
|
|
|
|
}
|
2014-04-25 19:25:34 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E3B43
|
|
|
|
*/
|
|
|
|
void game_handle_keyboard_input()
|
|
|
|
{
|
2014-04-26 02:16:32 +02:00
|
|
|
rct_window *w;
|
2014-05-12 02:45:45 +02:00
|
|
|
int key;
|
2014-04-26 02:16:32 +02:00
|
|
|
|
|
|
|
// Handle mouse scrolling
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0)
|
2014-04-28 22:00:54 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) != 0)
|
2014-04-26 02:16:32 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == 1)
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 3))
|
|
|
|
game_handle_edge_scroll();
|
|
|
|
|
|
|
|
// Handle modifier keys and key scrolling
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = 0;
|
|
|
|
if (RCT2_GLOBAL(0x009E2B64, uint32) != 1) {
|
|
|
|
if (gKeysState[SDL_SCANCODE_LSHIFT] || gKeysState[SDL_SCANCODE_RSHIFT])
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) |= 1;
|
|
|
|
if (gKeysState[SDL_SCANCODE_LCTRL] || gKeysState[SDL_SCANCODE_RCTRL])
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) |= 2;
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0)
|
|
|
|
game_handle_key_scroll();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Handle key input
|
|
|
|
while ((key = get_next_key()) != 0) {
|
2014-05-04 15:10:32 +02:00
|
|
|
if (key == 255)
|
2014-04-26 02:16:32 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
key |= RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) << 8;
|
|
|
|
|
|
|
|
w = window_find_by_id(WC_CHANGE_KEYBOARD_SHORTCUT, 0);
|
|
|
|
if (w != NULL)
|
|
|
|
set_shortcut(key);
|
|
|
|
else if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 1)
|
|
|
|
tutorial_stop();
|
|
|
|
else
|
|
|
|
handle_shortcut(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Tutorial and the modifier key
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) == 1) {
|
|
|
|
int eax, ebx, ecx, edx, esi, edi, ebp;
|
|
|
|
RCT2_CALLFUNC_X(0x0066EEB4, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
eax &= 0xFF;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) = eax;
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 4) {
|
|
|
|
window_tooltip_close();
|
|
|
|
if ((w = window_get_main()) != NULL) {
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(0x006EA2AA, 0, 0, 0, 0, (int)w, RCT2_GLOBAL(0x009DEA72, uint16), 0);
|
2014-04-26 02:16:32 +02:00
|
|
|
RCT2_GLOBAL(0x009DEA72, uint16)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8) & 4)) {
|
|
|
|
window_tooltip_close();
|
|
|
|
if ((w = window_get_main()) != NULL) {
|
2014-05-12 02:45:45 +02:00
|
|
|
RCT2_CALLPROC_X(0x006EA2AA, 0, 0, 0, 0, (int)w, RCT2_GLOBAL(0x009DEA72, uint16), 0);
|
2014-04-26 02:16:32 +02:00
|
|
|
RCT2_GLOBAL(0x009DEA72, uint16)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write tutorial input
|
|
|
|
RCT2_CALLPROC_X(0x0066EEE1, RCT2_GLOBAL(RCT2_ADDRESS_PLACE_OBJECT_MODIFIER, uint8), 0, 0, 0, 0, 0, 0);
|
|
|
|
}
|
2014-05-02 03:12:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2014-07-14 20:46:45 +02:00
|
|
|
* rct2: 0x0069C62C
|
2014-05-02 03:12:14 +02:00
|
|
|
*
|
|
|
|
* @param cost (ebp)
|
|
|
|
*/
|
|
|
|
static int game_check_affordability(int cost)
|
|
|
|
{
|
2014-07-14 20:46:45 +02:00
|
|
|
if (cost <= 0)return cost;
|
|
|
|
if (RCT2_GLOBAL(0x141F568, uint8) & 0xF0)return cost;
|
|
|
|
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32)&(1 << 8))){
|
|
|
|
if (cost <= (sint32)(DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32))))return cost;
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x13CE952, uint32) = cost;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 827;
|
|
|
|
return 0x80000000;
|
2014-05-02 03:12:14 +02:00
|
|
|
}
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
static uint32 game_do_command_table[58];
|
2014-08-10 14:31:41 +02:00
|
|
|
typedef void (GAME_COMMAND_POINTER)(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
|
|
|
static GAME_COMMAND_POINTER* new_game_command_table[58];
|
2014-05-02 23:21:08 +02:00
|
|
|
|
2014-05-02 03:12:14 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006677F2
|
|
|
|
*
|
|
|
|
* @param flags (ebx)
|
|
|
|
* @param command (esi)
|
|
|
|
*/
|
|
|
|
int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp)
|
|
|
|
{
|
2014-08-09 15:47:58 +02:00
|
|
|
return game_do_command_p(esi, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
|
2014-08-05 19:15:28 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006677F2 with pointers as arguments
|
|
|
|
*
|
|
|
|
* @param flags (ebx)
|
|
|
|
* @param command (esi)
|
|
|
|
*/
|
2014-08-06 21:06:51 +02:00
|
|
|
int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
2014-08-05 19:15:28 +02:00
|
|
|
{
|
|
|
|
int cost, flags, insufficientFunds;
|
|
|
|
int original_ebx, original_edx, original_esi, original_edi, original_ebp;
|
|
|
|
|
2014-08-06 21:06:51 +02:00
|
|
|
*esi = command;
|
2014-08-05 19:15:28 +02:00
|
|
|
original_ebx = *ebx;
|
|
|
|
original_edx = *edx;
|
|
|
|
original_esi = *esi;
|
|
|
|
original_edi = *edi;
|
|
|
|
original_ebp = *ebp;
|
|
|
|
|
|
|
|
flags = *ebx;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0xFFFF;
|
|
|
|
|
|
|
|
// Increment nest count
|
|
|
|
RCT2_GLOBAL(0x009A8C28, uint8)++;
|
|
|
|
|
|
|
|
*ebx &= ~1;
|
2014-08-11 22:50:13 +02:00
|
|
|
|
2014-08-05 19:15:28 +02:00
|
|
|
// Primary command
|
2014-08-10 14:31:41 +02:00
|
|
|
if (game_do_command_table[command] == 0) {
|
|
|
|
new_game_command_table[command](eax, ebx, ecx, edx, esi, edi, ebp);
|
|
|
|
} else {
|
|
|
|
RCT2_CALLFUNC_X(game_do_command_table[command], eax, ebx, ecx, edx, esi, edi, ebp);
|
|
|
|
}
|
2014-08-05 19:15:28 +02:00
|
|
|
cost = *ebx;
|
|
|
|
|
|
|
|
if (cost != 0x80000000) {
|
|
|
|
// Check funds
|
|
|
|
insufficientFunds = 0;
|
|
|
|
if (RCT2_GLOBAL(0x009A8C28, uint8) == 1 && !(flags & 4) && !(flags & 0x20) && cost != 0)
|
|
|
|
insufficientFunds = game_check_affordability(cost);
|
|
|
|
|
|
|
|
if (insufficientFunds != 0x80000000) {
|
|
|
|
*ebx = original_ebx;
|
|
|
|
*edx = original_edx;
|
|
|
|
*esi = original_esi;
|
|
|
|
*edi = original_edi;
|
|
|
|
*ebp = original_ebp;
|
|
|
|
|
|
|
|
if (!(flags & 1)) {
|
|
|
|
// Decrement nest count
|
|
|
|
RCT2_GLOBAL(0x009A8C28, uint8)--;
|
|
|
|
return cost;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Secondary command
|
2014-08-10 14:31:41 +02:00
|
|
|
if (game_do_command_table[command] == 0) {
|
|
|
|
new_game_command_table[command](eax, ebx, ecx, edx, esi, edi, ebp);
|
|
|
|
} else {
|
|
|
|
RCT2_CALLFUNC_X(game_do_command_table[command], eax, ebx, ecx, edx, esi, edi, ebp);
|
|
|
|
}
|
2014-08-05 19:15:28 +02:00
|
|
|
*edx = *ebx;
|
|
|
|
|
|
|
|
if (*edx != 0x80000000 && *edx < cost)
|
|
|
|
cost = *edx;
|
|
|
|
|
|
|
|
// Decrement nest count
|
|
|
|
RCT2_GLOBAL(0x009A8C28, uint8)--;
|
|
|
|
if (RCT2_GLOBAL(0x009A8C28, uint8) != 0)
|
|
|
|
return cost;
|
|
|
|
|
|
|
|
//
|
|
|
|
if (!(flags & 0x20)) {
|
|
|
|
// Update money balance
|
|
|
|
finance_payment(cost, RCT2_GLOBAL(0x0141F56C, uint8));
|
|
|
|
RCT2_CALLPROC_X(0x0069C674, 0, cost, 0, 0, 0, 0, 0);
|
|
|
|
if (RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8)) {
|
|
|
|
// Create a +/- money text effect
|
|
|
|
if (cost != 0)
|
|
|
|
RCT2_CALLPROC_X(0x0069C5D0, 0, cost, 0, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return cost;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error occured
|
|
|
|
|
|
|
|
// Decrement nest count
|
|
|
|
RCT2_GLOBAL(0x009A8C28, uint8)--;
|
|
|
|
|
|
|
|
// Show error window
|
|
|
|
if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & 1) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & 8))
|
|
|
|
window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16));
|
|
|
|
|
|
|
|
return 0x80000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-03 10:00:49 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00667C15
|
|
|
|
*/
|
2014-07-31 00:11:01 +02:00
|
|
|
void game_pause_toggle()
|
2014-05-03 10:00:49 +02:00
|
|
|
{
|
2014-05-12 02:45:45 +02:00
|
|
|
char input_bl;
|
2014-05-03 10:00:49 +02:00
|
|
|
|
2014-05-19 22:53:14 +02:00
|
|
|
#ifdef _MSC_VER
|
2014-05-03 10:00:49 +02:00
|
|
|
__asm mov input_bl, bl
|
2014-05-19 22:53:14 +02:00
|
|
|
#else
|
|
|
|
__asm__ ( "mov %[input_bl], bl " : [input_bl] "+m" (input_bl) );
|
|
|
|
#endif
|
|
|
|
|
2014-05-03 10:00:49 +02:00
|
|
|
|
|
|
|
if (input_bl & 1) {
|
|
|
|
RCT2_GLOBAL(0x009DEA6E, uint32) ^= 1;
|
|
|
|
window_invalidate_by_id(WC_TOP_TOOLBAR, 0);
|
|
|
|
if (RCT2_GLOBAL(0x009DEA6E, uint32) & 1)
|
2014-05-06 23:04:09 +02:00
|
|
|
pause_sounds();
|
2014-05-03 10:00:49 +02:00
|
|
|
else
|
2014-05-06 23:04:09 +02:00
|
|
|
unpause_sounds();
|
2014-05-03 10:00:49 +02:00
|
|
|
}
|
|
|
|
|
2014-05-19 22:53:14 +02:00
|
|
|
#ifdef _MSC_VER
|
2014-05-03 10:00:49 +02:00
|
|
|
__asm mov ebx, 0
|
2014-05-19 22:53:14 +02:00
|
|
|
#else
|
|
|
|
__asm__ ( "mov ebx, 0 " );
|
|
|
|
#endif
|
|
|
|
|
2014-05-03 10:00:49 +02:00
|
|
|
}
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0066DB5F
|
|
|
|
*/
|
|
|
|
static void game_load_or_quit()
|
|
|
|
{
|
|
|
|
char input_bl, input_dl;
|
|
|
|
short input_di;
|
|
|
|
|
2014-05-19 22:53:14 +02:00
|
|
|
#ifdef _MSC_VER
|
2014-05-02 23:21:08 +02:00
|
|
|
__asm mov input_bl, bl
|
2014-05-19 22:53:14 +02:00
|
|
|
#else
|
|
|
|
__asm__ ( "mov %[input_bl], bl " : [input_bl] "+m" (input_bl) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2014-05-02 23:21:08 +02:00
|
|
|
__asm mov input_dl, dl
|
2014-05-19 22:53:14 +02:00
|
|
|
#else
|
|
|
|
__asm__ ( "mov %[input_dl], dl " : [input_dl] "+m" (input_dl) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2014-05-02 23:21:08 +02:00
|
|
|
__asm mov input_di, di
|
2014-05-19 22:53:14 +02:00
|
|
|
#else
|
|
|
|
__asm__ ( "mov %[input_di], di " : [input_di] "+m" (input_di) );
|
|
|
|
#endif
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
if (!(input_bl & 1))
|
2014-05-12 03:18:08 +02:00
|
|
|
return; // 0;
|
2014-05-23 11:30:19 +02:00
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
switch (input_dl) {
|
|
|
|
case 0:
|
2014-05-23 11:30:19 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = input_di;
|
2014-05-02 23:21:08 +02:00
|
|
|
window_save_prompt_open();
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
window_close_by_id(WC_SAVE_PROMPT, 0);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
game_load_or_quit_no_save_prompt();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-05-19 22:53:14 +02:00
|
|
|
#ifdef _MSC_VER
|
2014-05-02 23:21:08 +02:00
|
|
|
__asm mov ebx, 0
|
2014-05-19 22:53:14 +02:00
|
|
|
#else
|
|
|
|
__asm__ ( "mov ebx, 0 " );
|
|
|
|
#endif
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
|
2014-08-10 14:31:41 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0069ED0B
|
|
|
|
*/
|
|
|
|
static void sub_69ED0B(rct_peep* sprite, int cl)
|
|
|
|
{
|
|
|
|
if (sprite->var_08 == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int ebx = sprite->var_08;
|
|
|
|
int ax = sprite->next;
|
|
|
|
|
|
|
|
if (sprite->previous != 0xFFFF) {
|
|
|
|
g_sprite_list[sprite->previous].peep.next = ax;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
RCT2_ADDRESS(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)[ebx] = ax;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprite->previous = 0xFFFF;
|
|
|
|
sprite->var_08 = cl;
|
|
|
|
|
|
|
|
// set next sprite to the delimiter
|
|
|
|
int tmp_ax = RCT2_ADDRESS(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)[cl];
|
|
|
|
RCT2_ADDRESS(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)[cl] = sprite->sprite_index;
|
|
|
|
sprite->next = tmp_ax;
|
|
|
|
|
|
|
|
if (tmp_ax != 0xFFFF) {
|
|
|
|
g_sprite_list[tmp_ax].peep.previous = ax;
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT2_ADDRESS(0x013573C8, uint16)[ebx]--;
|
|
|
|
RCT2_ADDRESS(0x013573C8, uint16)[cl]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0069EC6B
|
|
|
|
* bl
|
|
|
|
* return: new peep sprite (esi)
|
|
|
|
*/
|
|
|
|
static rct_peep* create_peep_sprite(short bl)
|
|
|
|
{
|
|
|
|
int ecx = 0;
|
|
|
|
rct_peep* newSprite;
|
|
|
|
|
|
|
|
if (!(bl & 2)) {
|
|
|
|
if (RCT2_GLOBAL(0x013573C8, short) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
*newSprite = g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)].peep;
|
|
|
|
ecx = 10;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (0x12C - RCT2_GLOBAL(0x0013573CE, short) >= RCT2_GLOBAL(0x013573C8, short))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
*newSprite = g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)].peep;
|
|
|
|
ecx = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub_69ED0B(newSprite, ecx);
|
|
|
|
|
|
|
|
newSprite->x = 0x8000;
|
|
|
|
newSprite->y = 0x8000;
|
|
|
|
newSprite->z = 0;
|
|
|
|
newSprite->var_02 = previousPeepSpriteIndex;
|
|
|
|
previousPeepSpriteIndex = newSprite->sprite_index;
|
|
|
|
newSprite->name_string_idx = 0;
|
|
|
|
newSprite->var_14 = 10;
|
|
|
|
newSprite->var_09 = 0x14;
|
|
|
|
newSprite->var_15 = 10;
|
|
|
|
newSprite->var_0C = 10;
|
|
|
|
newSprite->var_16 = 0x8000;
|
|
|
|
|
|
|
|
return newSprite;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_6C42AC(uint16 name_string_idx)
|
|
|
|
{
|
|
|
|
if (name_string_idx < 0x8000 || name_string_idx >= 0x9000)
|
|
|
|
return;
|
|
|
|
|
|
|
|
RCT2_ADDRESS(0x0095AFB8, uint32)[(name_string_idx + 0x3FF) * 20] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sub_69EDB6(rct_peep* peep) {
|
|
|
|
sub_69ED0B(peep, 0);
|
|
|
|
sub_6C42AC(peep->name_string_idx);
|
|
|
|
peep->sprite_identifier = 0;
|
|
|
|
|
|
|
|
int x = peep->x;
|
|
|
|
if (x == 0x8000)
|
|
|
|
x = 0x10000;
|
|
|
|
x &= 0x1FE0;
|
|
|
|
|
|
|
|
uint32* edi = RCT2_ADDRESS(0xF1EF60, uint32)[(x << 3) | (peep->y >> 5)];
|
|
|
|
|
|
|
|
rct_peep* peepSprite = NULL;
|
|
|
|
while (peepSprite != peep) {
|
|
|
|
peepSprite = g_sprite_list + (*edi << 8);
|
|
|
|
*edi = peepSprite->var_02;
|
|
|
|
}
|
|
|
|
peepSprite->sprite_identifier = peep->var_02;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0069E9D3
|
|
|
|
*/
|
|
|
|
static void sub_69E9D3(rct_peep* peep, int ax) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006EC473
|
|
|
|
*/
|
|
|
|
static void sub_6EC473(rct_peep* peep) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00699115
|
|
|
|
*/
|
|
|
|
static void sub_699115(rct_peep* peep) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006BEFA1
|
|
|
|
*/
|
|
|
|
static void game_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|
|
|
int* esi, int* edi, int* ebp)
|
|
|
|
{
|
2014-08-11 22:50:13 +02:00
|
|
|
//RCT2_CALLFUNC_X(0x006BEFA1, eax, ebx, ecx, edx, esi, edi, ebp);
|
|
|
|
//return;
|
|
|
|
|
|
|
|
|
|
|
|
uint8 _bl = *ebx & 0xFF, tabIndex = (*ebx & 0xFF00) >> 8;
|
|
|
|
uint16 _ax = *eax & 0xFFFF, _cx = *ecx & 0xFFFF, _dx = *edx & 0xFFFF;
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
RCT2_GLOBAL(0x0141F56C, uint8) = 0x28;
|
|
|
|
RCT2_GLOBAL(0x009DEA5E, uint16) = _ax;
|
|
|
|
RCT2_GLOBAL(0x009DEA60, uint16) = _cx;
|
|
|
|
RCT2_GLOBAL(0x009DEA62, uint16) = _dx;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x13573C8, uint16) < 0x190) {
|
|
|
|
*ebx = 0x80000000;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 0xC8; i++) {
|
|
|
|
if (!(RCT2_ADDRESS(0x013CA672, uint8)[i] & 1))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 0xC8) {
|
|
|
|
*ebx = 0x80000000;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_STAFF_IN_GAME;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int newStaffId = i;
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
int _eax, _ebx, _ecx = _cx, _edx, _esi, _edi, _ebp;
|
2014-08-10 14:31:41 +02:00
|
|
|
_esi = 0;
|
|
|
|
_ebx = _bl;
|
2014-08-11 22:50:13 +02:00
|
|
|
RCT2_CALLFUNC_X(0x0069EC6B, &_eax, &_bl, &_ecx, &_edx, &_esi, &_edi, &_ebp);
|
2014-08-10 14:31:41 +02:00
|
|
|
rct_peep* newPeep = (rct_peep*)_esi;
|
|
|
|
|
|
|
|
//if ((newPeep = create_peep_sprite(_bl)) == NULL)
|
|
|
|
if (_esi == 0)
|
|
|
|
{
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
__asm mov ebx, 0x80000000
|
|
|
|
#else
|
|
|
|
__asm__("mov ebx, 0x80000000 ");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
if (_bl == 0) {
|
|
|
|
RCT2_CALLPROC_X(0x0069EDB6, 0, 0, _ecx, 0, (int)newPeep, 0, 0);
|
2014-08-10 14:31:41 +02:00
|
|
|
} else {
|
2014-08-11 22:50:13 +02:00
|
|
|
RCT2_CALLPROC_X(0x0069ED0B, 0, 0, 4, 0, (int)newPeep, 0, 0);
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
newPeep->sprite_identifier = 1;
|
|
|
|
newPeep->var_09 = 0x0F;
|
|
|
|
newPeep->var_15 = 5;
|
|
|
|
newPeep->var_14 = 8;
|
2014-08-19 09:46:04 +02:00
|
|
|
newPeep->sprite_direction = 0;
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
_eax = _ax;
|
|
|
|
_edx = _dx;
|
2014-08-11 22:50:13 +02:00
|
|
|
_ecx = *ecx;
|
|
|
|
// ax (cmp ax, 8000h)
|
|
|
|
// esi (peep)
|
|
|
|
// cx (shr cx, 5)
|
|
|
|
RCT2_CALLPROC_X(0x0069E9D3, _eax, 0, _ecx, *edx, (int)newPeep, 0, 0);
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
newPeep->state = PEEP_STATE_PICKED;
|
2014-08-11 22:50:13 +02:00
|
|
|
if (newPeep->x != -32768) {
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->state = 0;
|
|
|
|
}
|
2014-08-11 22:50:13 +02:00
|
|
|
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->var_45 = 0;
|
|
|
|
newPeep->var_71 = 0xFF;
|
|
|
|
newPeep->var_6D = 0;
|
|
|
|
newPeep->var_70 = 0;
|
|
|
|
newPeep->var_E0 = 0;
|
|
|
|
newPeep->var_6E = 0;
|
|
|
|
newPeep->var_C4 = 0;
|
2014-08-11 22:50:13 +02:00
|
|
|
newPeep->type = PEEP_TYPE_STAFF;
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->var_2A = 0;
|
|
|
|
newPeep->flags = 0;
|
|
|
|
newPeep->paid_to_enter = 0;
|
|
|
|
newPeep->paid_on_rides = 0;
|
|
|
|
newPeep->paid_on_food = 0;
|
|
|
|
newPeep->paid_on_souvenirs = 0;
|
|
|
|
|
|
|
|
newPeep->var_C6 = 0;
|
2014-08-11 22:50:13 +02:00
|
|
|
/*if (tabIndex == 0) {
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->var_C6 = 7;
|
2014-08-11 22:50:13 +02:00
|
|
|
} else if (tabIndex == 1) {
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->var_C6 = 3;
|
2014-08-11 22:50:13 +02:00
|
|
|
}*/
|
|
|
|
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->staff_type = 0xFF;
|
|
|
|
|
|
|
|
uint16 idSearchSpriteIndex;
|
|
|
|
rct_peep* idSearchPeep;
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
// We search for the first available id for a given staff type
|
|
|
|
int newStaffIndex = 0;
|
|
|
|
for (;;) {
|
|
|
|
int found = 0;
|
|
|
|
newStaffIndex++;
|
|
|
|
|
2014-08-10 14:31:41 +02:00
|
|
|
FOR_ALL_STAFF(idSearchSpriteIndex, idSearchPeep) {
|
2014-08-11 22:50:13 +02:00
|
|
|
if (idSearchPeep->staff_type != tabIndex) {
|
|
|
|
continue;
|
|
|
|
}
|
2014-08-10 14:31:41 +02:00
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
if (idSearchPeep->id == newStaffIndex) {
|
|
|
|
found = 1;
|
2014-08-10 14:31:41 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
if (found == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
newPeep->id = newStaffIndex;
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->staff_type = tabIndex;
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
_eax = RCT2_ADDRESS(0x009929FC, uint8)[tabIndex];
|
|
|
|
newPeep->name_string_idx = tabIndex + 0x300;
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->sprite_type = _eax;
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
_edx = RCT2_ADDRESS(0x0098270C, uint32)[_eax * 2];
|
2014-08-10 14:31:41 +02:00
|
|
|
newPeep->var_14 = *((int*)_edx);
|
|
|
|
newPeep->var_09 = *((int*)(_edx + 1));
|
|
|
|
newPeep->var_15 = *((int*)(_edx + 2));
|
|
|
|
|
|
|
|
//sub_69E9D3(newPeep);
|
2014-08-11 22:50:13 +02:00
|
|
|
RCT2_CALLPROC_X(0x0069E9D3, newPeep->x, 0, newPeep->y, newPeep->z, (int)newPeep, 0, 0);
|
2014-08-10 14:31:41 +02:00
|
|
|
//sub_6EC473(newPeep);
|
2014-08-11 22:50:13 +02:00
|
|
|
RCT2_CALLPROC_X(0x006EC473, *eax, 0, 0, 0, (int)newPeep, 0, 0);
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
newPeep->var_AD = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint8);
|
|
|
|
newPeep->var_CC = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
uint8 colour = RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[tabIndex];
|
|
|
|
newPeep->tshirt_colour = colour;
|
|
|
|
newPeep->trousers_colour = colour;
|
|
|
|
|
2014-08-11 22:50:13 +02:00
|
|
|
_eax = (uint32)ebp & 0xFFFFFF3F;
|
|
|
|
_ebp = (*ebp << 25) | (*ebp >> 6);
|
|
|
|
|
|
|
|
newPeep->energy = 0x60;
|
|
|
|
newPeep->energy_growth_rate = 0x60;
|
|
|
|
newPeep->var_E2 = 0;
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
//sub_699115(newPeep);
|
2014-08-11 22:50:13 +02:00
|
|
|
RCT2_CALLPROC_X(0x00699115, _eax, 0, 0, 0, (int)newPeep, 0, _ebp);
|
2014-08-10 14:31:41 +02:00
|
|
|
|
|
|
|
newPeep->var_C5 = newStaffId;
|
|
|
|
|
|
|
|
RCT2_ADDRESS(0x013CA672, uint8)[newStaffId] = 1;
|
|
|
|
|
|
|
|
for (int edi = 0; edi < 0x80; edi++) {
|
|
|
|
int addr = 0x013B0E72 + (newStaffId << 9) + edi * 4;
|
|
|
|
RCT2_ADDRESS(addr, uint32) = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*ebx = 0;
|
|
|
|
*edi = newPeep->sprite_index;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-06 21:06:51 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00669E55
|
|
|
|
*/
|
|
|
|
static void game_update_staff_colour()
|
|
|
|
{
|
|
|
|
byte tabIndex, colour, _bl;
|
|
|
|
int spriteIndex;
|
|
|
|
rct_peep *peep;
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
__asm mov _bl, bl
|
|
|
|
#else
|
|
|
|
__asm__("mov %[_bl], bl " : [_bl] "+m" (_bl));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
__asm mov tabIndex, bh
|
|
|
|
#else
|
|
|
|
__asm__("mov %[tabIndex], bh " : [tabIndex] "+m" (tabIndex));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
__asm mov colour, dh
|
|
|
|
#else
|
|
|
|
__asm__("mov %[colour], bh " : [colour] "+m" (colour));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (_bl & 1) {
|
|
|
|
RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[tabIndex] = colour;
|
|
|
|
|
|
|
|
FOR_ALL_PEEPS(spriteIndex, peep) {
|
|
|
|
if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == tabIndex) {
|
|
|
|
peep->tshirt_colour = colour;
|
|
|
|
peep->trousers_colour = colour;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
__asm mov ebx, 0
|
|
|
|
#else
|
|
|
|
__asm__("mov ebx, 0 ");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00674F40
|
|
|
|
*/
|
|
|
|
static int open_landscape_file_dialog()
|
|
|
|
{
|
2014-05-12 03:18:08 +02:00
|
|
|
int result;
|
2014-07-18 22:03:33 +02:00
|
|
|
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, STR_LOAD_LANDSCAPE_DIALOG_TITLE, 0);
|
2014-05-12 02:45:45 +02:00
|
|
|
strcpy((char*)0x0141EF68, (char*)RCT2_ADDRESS_LANDSCAPES_PATH);
|
|
|
|
format_string((char*)0x0141EE68, STR_RCT2_LANDSCAPE_FILE, 0);
|
2014-05-06 23:04:09 +02:00
|
|
|
pause_sounds();
|
2014-07-18 22:03:33 +02:00
|
|
|
result = osinterface_open_common_file_dialog(1, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, (char*)0x0141EF68, "*.SV6;*.SV4;*.SC6", (char*)0x0141EE68);
|
2014-05-06 23:04:09 +02:00
|
|
|
unpause_sounds();
|
2014-05-03 11:27:48 +02:00
|
|
|
// window_proc
|
2014-05-12 03:18:08 +02:00
|
|
|
return result;
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00674EB6
|
|
|
|
*/
|
|
|
|
static int open_load_game_dialog()
|
|
|
|
{
|
2014-05-07 23:11:23 +02:00
|
|
|
int result;
|
2014-07-18 22:03:33 +02:00
|
|
|
format_string((char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, STR_LOAD_GAME_DIALOG_TITLE, 0);
|
2014-05-12 02:45:45 +02:00
|
|
|
strcpy((char*)0x0141EF68, (char*)RCT2_ADDRESS_SAVED_GAMES_PATH);
|
|
|
|
format_string((char*)0x0141EE68, STR_RCT2_SAVED_GAME, 0);
|
2014-05-06 23:04:09 +02:00
|
|
|
pause_sounds();
|
2014-07-18 22:03:33 +02:00
|
|
|
result = osinterface_open_common_file_dialog(1, (char*)RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, (char*)0x0141EF68, "*.SV6", (char*)0x0141EE68);
|
2014-05-06 23:04:09 +02:00
|
|
|
unpause_sounds();
|
2014-05-03 11:27:48 +02:00
|
|
|
// window_proc
|
2014-05-07 23:11:23 +02:00
|
|
|
return result;
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0066DC0F
|
|
|
|
*/
|
|
|
|
static void load_landscape()
|
|
|
|
{
|
|
|
|
if (open_landscape_file_dialog() == 0) {
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
} else {
|
2014-05-03 03:33:01 +02:00
|
|
|
// Set default filename
|
2014-05-12 02:45:45 +02:00
|
|
|
char *esi = (char*)0x0141EF67;
|
2014-05-03 03:33:01 +02:00
|
|
|
while (1) {
|
|
|
|
esi++;
|
|
|
|
if (*esi == '.')
|
|
|
|
break;
|
|
|
|
if (*esi != 0)
|
|
|
|
continue;
|
|
|
|
strcpy(esi, ".SC6");
|
|
|
|
break;
|
|
|
|
}
|
2014-05-13 23:37:45 +02:00
|
|
|
strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*)0x0141EF68);
|
2014-05-02 23:21:08 +02:00
|
|
|
|
2014-05-03 03:33:01 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006758C0); // landscape_load
|
2014-05-02 23:21:08 +02:00
|
|
|
if (1) {
|
|
|
|
gfx_invalidate_screen();
|
2014-05-03 21:39:34 +02:00
|
|
|
rct2_endupdate();
|
2014-05-02 23:21:08 +02:00
|
|
|
} else {
|
|
|
|
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
|
2014-05-03 21:39:34 +02:00
|
|
|
rct2_endupdate();
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-04 17:21:15 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00675E1B
|
|
|
|
*/
|
|
|
|
int game_load_save()
|
|
|
|
{
|
|
|
|
rct_window *mainWindow;
|
2014-05-24 23:14:42 +02:00
|
|
|
FILE *file;
|
2014-05-04 17:21:15 +02:00
|
|
|
char *path;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
path = (char*)0x0141EF68;
|
2014-05-24 23:14:42 +02:00
|
|
|
file = fopen(path, "rb");
|
|
|
|
if (file == NULL) {
|
2014-05-04 17:21:15 +02:00
|
|
|
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-05-24 23:14:42 +02:00
|
|
|
if (!sawyercoding_validate_checksum(file)) {
|
|
|
|
fclose(file);
|
2014-05-04 18:34:13 +02:00
|
|
|
RCT2_GLOBAL(0x009AC31B, uint8) = 255;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_FILE_CONTAINS_INVALID_DATA;
|
|
|
|
return 0;
|
|
|
|
}
|
2014-05-04 17:21:15 +02:00
|
|
|
|
2014-05-12 02:45:45 +02:00
|
|
|
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
|
|
|
|
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
2014-05-04 17:21:15 +02:00
|
|
|
|
|
|
|
// Read first chunk
|
2014-05-24 23:14:42 +02:00
|
|
|
sawyercoding_read_chunk(file, (uint8*)s6Header);
|
2014-05-04 17:21:15 +02:00
|
|
|
if (s6Header->type == S6_TYPE_SAVEDGAME) {
|
|
|
|
// Read packed objects
|
|
|
|
if (s6Header->num_packed_objects > 0) {
|
|
|
|
j = 0;
|
|
|
|
for (i = 0; i < s6Header->num_packed_objects; i++)
|
|
|
|
j += object_load_packed();
|
|
|
|
if (j > 0)
|
2014-05-24 02:34:17 +02:00
|
|
|
object_list_load();
|
2014-05-04 17:21:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-24 23:14:42 +02:00
|
|
|
object_read_and_load_entries(file);
|
2014-05-04 17:21:15 +02:00
|
|
|
|
|
|
|
// Read flags (16 bytes)
|
2014-05-24 23:14:42 +02:00
|
|
|
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_CURRENT_MONTH_YEAR);
|
2014-05-04 17:21:15 +02:00
|
|
|
|
|
|
|
// Read map elements
|
2014-05-12 02:45:45 +02:00
|
|
|
memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, MAX_MAP_ELEMENTS * sizeof(rct_map_element));
|
2014-05-24 23:14:42 +02:00
|
|
|
sawyercoding_read_chunk(file, (uint8*)RCT2_ADDRESS_MAP_ELEMENTS);
|
2014-05-04 17:21:15 +02:00
|
|
|
|
|
|
|
// Read game data, including sprites
|
2014-05-24 23:14:42 +02:00
|
|
|
sawyercoding_read_chunk(file, (uint8*)0x010E63B8);
|
2014-05-04 17:21:15 +02:00
|
|
|
|
2014-05-24 23:14:42 +02:00
|
|
|
fclose(file);
|
2014-05-04 17:21:15 +02:00
|
|
|
|
|
|
|
// Check expansion pack
|
|
|
|
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
|
|
|
|
|
|
|
|
// The rest is the same as in scenario load and play
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
|
|
|
|
map_update_tile_pointers();
|
2014-06-21 14:31:28 +02:00
|
|
|
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
|
2014-05-04 17:21:15 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
|
|
|
|
viewport_init_all();
|
|
|
|
game_create_windows();
|
|
|
|
mainWindow = window_get_main();
|
|
|
|
|
2014-07-23 19:07:38 +02:00
|
|
|
mainWindow->viewport_target_sprite = -1;
|
2014-05-04 17:21:15 +02:00
|
|
|
mainWindow->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
|
|
|
|
mainWindow->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
|
|
|
|
uint8 _cl = (RCT2_GLOBAL(0x0138869E, sint16) & 0xFF) - mainWindow->viewport->zoom;
|
|
|
|
mainWindow->viewport->zoom = RCT2_GLOBAL(0x0138869E, sint16) & 0xFF;
|
|
|
|
*((char*)(&RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, sint32))) = RCT2_GLOBAL(0x0138869E, sint16) >> 8;
|
|
|
|
if (_cl != 0) {
|
|
|
|
if (_cl < 0) {
|
|
|
|
_cl = -_cl;
|
|
|
|
mainWindow->viewport->view_width >>= _cl;
|
|
|
|
mainWindow->viewport->view_height >>= _cl;
|
|
|
|
} else {
|
|
|
|
mainWindow->viewport->view_width <<= _cl;
|
|
|
|
mainWindow->viewport->view_height <<= _cl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mainWindow->saved_view_x -= mainWindow->viewport->view_width >> 1;
|
|
|
|
mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1;
|
|
|
|
window_invalidate(mainWindow);
|
|
|
|
|
2014-06-21 16:50:13 +02:00
|
|
|
sub_0x0069E9A7();
|
2014-05-04 17:21:15 +02:00
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
|
2014-05-10 00:11:51 +02:00
|
|
|
window_new_ride_init_vars();
|
2014-05-04 17:21:15 +02:00
|
|
|
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
|
|
|
|
if (RCT2_GLOBAL(0x0013587C4, uint32) == 0) // this check is not in scenario play
|
2014-05-17 17:04:19 +02:00
|
|
|
sub_69E869();
|
2014-05-04 17:21:15 +02:00
|
|
|
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006837E3); // (palette related)
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-06-21 16:50:13 +02:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* rct2: 0x0069E9A7
|
|
|
|
*/
|
|
|
|
void sub_0x0069E9A7(){
|
|
|
|
//RCT2_CALLPROC_EBPSAFE(0x0069E9A7);
|
|
|
|
//return;
|
2014-06-29 15:51:18 +02:00
|
|
|
for (rct_sprite* spr = g_sprite_list; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; ++spr){
|
2014-06-21 16:50:13 +02:00
|
|
|
if (spr->unknown.sprite_identifier != 0xFF){
|
|
|
|
RCT2_CALLPROC_X(0x0069E9D3, spr->unknown.x, 0, spr->unknown.y, spr->unknown.z, (int)spr, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0066DBB7
|
|
|
|
*/
|
|
|
|
static void load_game()
|
|
|
|
{
|
|
|
|
if (open_load_game_dialog() == 0) {
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
} else {
|
2014-05-03 03:33:01 +02:00
|
|
|
// Set default filename
|
2014-05-12 02:45:45 +02:00
|
|
|
char *esi = (char*)0x0141EF67;
|
2014-05-03 03:33:01 +02:00
|
|
|
while (1) {
|
|
|
|
esi++;
|
|
|
|
if (*esi == '.')
|
|
|
|
break;
|
|
|
|
if (*esi != 0)
|
|
|
|
continue;
|
|
|
|
strcpy(esi, ".SV6");
|
|
|
|
break;
|
|
|
|
}
|
2014-05-13 23:37:45 +02:00
|
|
|
strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*)0x0141EF68);
|
2014-05-02 23:21:08 +02:00
|
|
|
|
2014-05-04 17:21:15 +02:00
|
|
|
if (game_load_save()) {
|
2014-05-02 23:21:08 +02:00
|
|
|
gfx_invalidate_screen();
|
2014-05-03 21:39:34 +02:00
|
|
|
rct2_endupdate();
|
2014-05-02 23:21:08 +02:00
|
|
|
} else {
|
|
|
|
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
|
2014-05-03 21:39:34 +02:00
|
|
|
rct2_endupdate();
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-27 23:33:16 +02:00
|
|
|
char save_game()
|
|
|
|
{
|
|
|
|
int eax, ebx, ecx, edx, esi, edi, ebp;
|
|
|
|
RCT2_CALLFUNC_X(0x006750E9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
|
|
|
if (eax == 0) {
|
|
|
|
// user pressed "cancel"
|
|
|
|
gfx_invalidate_screen();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *src = (char*)0x0141EF67;
|
|
|
|
do {
|
|
|
|
src++;
|
|
|
|
} while (*src != '.' && *src != '\0');
|
|
|
|
strcpy(src, ".SV6");
|
|
|
|
strcpy((char*) RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*) 0x0141EF68);
|
|
|
|
|
|
|
|
eax = 0;
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 8)
|
|
|
|
eax |= 1;
|
|
|
|
RCT2_CALLPROC_X(0x006754F5, eax, 0, 0, 0, 0, 0, 0);
|
|
|
|
// check success?
|
|
|
|
|
2014-08-07 23:25:51 +02:00
|
|
|
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
2014-05-27 23:33:16 +02:00
|
|
|
gfx_invalidate_screen();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-05-02 23:21:08 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E3879
|
|
|
|
*/
|
2014-07-16 22:39:39 +02:00
|
|
|
void rct2_exit()
|
2014-05-02 23:21:08 +02:00
|
|
|
{
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x006E3879);
|
2014-07-17 18:59:49 +02:00
|
|
|
//Post quit message does not work in 0x6e3879 as its windows only.
|
2014-05-02 23:21:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0066DB79
|
|
|
|
*/
|
|
|
|
void game_load_or_quit_no_save_prompt()
|
|
|
|
{
|
2014-05-23 11:30:19 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) < 1) {
|
2014-08-06 21:06:51 +02:00
|
|
|
game_do_command(0, 1, 0, 1, GAME_COMMAND_LOAD_OR_QUIT, 0, 0);
|
2014-05-02 23:38:16 +02:00
|
|
|
tool_cancel();
|
2014-05-02 23:21:08 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
|
|
|
|
load_landscape();
|
|
|
|
else
|
|
|
|
load_game();
|
2014-05-23 11:30:19 +02:00
|
|
|
} else if (RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) == 1) {
|
2014-08-06 21:06:51 +02:00
|
|
|
game_do_command(0, 1, 0, 1, GAME_COMMAND_LOAD_OR_QUIT, 0, 0);
|
2014-05-02 23:21:08 +02:00
|
|
|
if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 5)) {
|
|
|
|
RCT2_CALLPROC_EBPSAFE(0x0040705E);
|
|
|
|
RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 5);
|
|
|
|
}
|
|
|
|
title_load();
|
2014-05-03 21:39:34 +02:00
|
|
|
rct2_endupdate();
|
2014-05-02 23:21:08 +02:00
|
|
|
} else {
|
|
|
|
rct2_exit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma region Game command function table
|
|
|
|
|
|
|
|
static uint32 game_do_command_table[58] = {
|
|
|
|
0x006B2FC5,
|
|
|
|
0x0066397F,
|
2014-05-12 02:45:45 +02:00
|
|
|
(uint32)game_pause_toggle,
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006C511D,
|
|
|
|
0x006C5B69,
|
2014-05-12 02:45:45 +02:00
|
|
|
(uint32)game_load_or_quit,
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006B3F0F,
|
|
|
|
0x006B49D9,
|
|
|
|
0x006B4EA6,
|
|
|
|
0x006B52D4,
|
2014-08-06 21:06:51 +02:00
|
|
|
0x006B578B, // 10
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006B5559,
|
|
|
|
0x006660A8,
|
|
|
|
0x0066640B,
|
|
|
|
0x006E0E01,
|
|
|
|
0x006E08F4,
|
|
|
|
0x006E650F,
|
|
|
|
0x006A61DE,
|
|
|
|
0x006A68AE,
|
|
|
|
0x006A67C0,
|
2014-08-06 21:06:51 +02:00
|
|
|
0x00663CCD, // 20
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006B53E9,
|
|
|
|
0x00698D6C,
|
|
|
|
0x0068C542,
|
|
|
|
0x0068C6D1,
|
|
|
|
0x0068BC01,
|
|
|
|
0x006E66A0,
|
|
|
|
0x006E6878,
|
|
|
|
0x006C5AE9,
|
2014-08-11 22:50:13 +02:00
|
|
|
0, //0x006BEFA1, // 0,
|
2014-08-06 21:06:51 +02:00
|
|
|
0x006C09D1, // 30
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006C0B83,
|
|
|
|
0x006C0BB5,
|
|
|
|
0x00669C6D,
|
|
|
|
0x00669D4A,
|
|
|
|
0x006649BD,
|
|
|
|
0x006666E7,
|
|
|
|
0x00666A63,
|
|
|
|
0x006CD8CE,
|
|
|
|
0x00669E30,
|
2014-08-06 21:06:51 +02:00
|
|
|
(uint32)game_update_staff_colour, // 40
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006E519A,
|
|
|
|
0x006E5597,
|
|
|
|
0x006B893C,
|
|
|
|
0x006B8E1B,
|
|
|
|
0x0069DFB3,
|
|
|
|
0x00684A7F,
|
|
|
|
0x006D13FE,
|
|
|
|
0x0069E73C,
|
|
|
|
0x006CDEE4,
|
2014-08-06 21:06:51 +02:00
|
|
|
0x006B9E6D, // 50
|
2014-05-02 23:21:08 +02:00
|
|
|
0x006BA058,
|
|
|
|
0x006E0F26,
|
|
|
|
0x006E56B5,
|
|
|
|
0x006B909A,
|
|
|
|
0x006BA16A,
|
|
|
|
0x006648E3,
|
|
|
|
0x0068DF91
|
|
|
|
};
|
|
|
|
|
2014-08-10 14:31:41 +02:00
|
|
|
game_command_emptysub(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {}
|
|
|
|
|
|
|
|
static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_hire_new_staff_member, //game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub, //(uint32)game_update_staff_colour, // 40
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub,
|
|
|
|
game_command_emptysub
|
|
|
|
};
|
|
|
|
|
2014-05-01 19:15:02 +02:00
|
|
|
#pragma endregion
|