1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

add more input logic and tooltip window

This commit is contained in:
IntelOrca
2014-04-24 18:53:42 +01:00
parent 14dc250fcb
commit ea4ea99212
14 changed files with 587 additions and 30 deletions

View File

@@ -45,6 +45,7 @@
<ClInclude Include="..\src\widget.h" />
<ClInclude Include="..\src\window.h" />
<ClInclude Include="..\src\window_dropdown.h" />
<ClInclude Include="..\src\window_tooltip.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
@@ -87,6 +88,7 @@
<ClCompile Include="..\src\window_title_menu.c" />
<ClCompile Include="..\src\window_title_scenarioselect.c" />
<ClCompile Include="..\src\window_game_top_toolbar.c" />
<ClCompile Include="..\src\window_tooltip.c" />
<ClCompile Include="..\src\window_water.c" />
</ItemGroup>
<ItemGroup>

View File

@@ -111,6 +111,9 @@
<ClInclude Include="..\src\track.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\window_tooltip.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\game.c">
@@ -233,6 +236,9 @@
<ClCompile Include="..\src\track.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\window_tooltip.c">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@@ -83,6 +83,8 @@
#define RCT2_ADDRESS_CURSOR_DRAG_LAST_X 0x009DE52A
#define RCT2_ADDRESS_CURSOR_DRAG_LAST_Y 0x009DE52C
#define RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER 0x009DE52E
#define RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS 0x009DE530
#define RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS 0x009DE533
#define RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER 0x009DE534
@@ -166,6 +168,8 @@
#define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754
#define RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE 0x013CE950
#define RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS 0x013CE9A4
#define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0

View File

@@ -19,6 +19,7 @@
*****************************************************************************/
#include "addresses.h"
#include "audio.h"
#include "rct2.h"
#include "game.h"
#include "news_item.h"
@@ -26,6 +27,7 @@
#include "peep.h"
#include "widget.h"
#include "window.h"
#include "window_tooltip.h"
void game_handle_input();
@@ -260,15 +262,23 @@ static void game_get_next_input(int *x, int *y, int *state)
#include <windows.h>
POINT _dragPosition;
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);
/**
*
* rct2: 0x006E8655
*/
static void game_handle_input_mouse(int x, int y, int state)
{
rct_window *w;
rct_window *w, *w2;
rct_widget *widget;
int widgetIndex;
rct_windowclass windowClass;
rct_windownumber windowNumber;
// Get window and widget under cursor position
w = window_find_from_point(x, y);
@@ -277,21 +287,15 @@ static void game_handle_input_mouse(int x, int y, int state)
switch (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8)) {
case INPUT_STATE_RESET:
window_tooltip_reset(x, y);
// fall-through
case INPUT_STATE_NORMAL:
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == 0) {
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint8) = x;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint8) = x;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 1;
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint32) = 1;
}
switch (state) {
case 0:
RCT2_CALLPROC_X(0x006E9253, x, y, state, widgetIndex, w, widget, 0);
input_mouseover(x, y, w, widgetIndex);
break;
case 1:
RCT2_CALLPROC_X(0x006E95F9, x, y, state, widgetIndex, w, widget, 0);
input_leftmousedown(x, y, w, widgetIndex);
break;
case 3:
// Close tooltip
@@ -307,7 +311,7 @@ static void game_handle_input_mouse(int x, int y, int state)
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 9)
break;
w->flags &= ~(1 << 3);
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_LEFT;
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_VIEWPORT_DRAG;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y;
RCT2_GLOBAL(0x009DE530, rct_windowclass) = w->classification;
@@ -334,7 +338,7 @@ static void game_handle_input_mouse(int x, int y, int state)
case INPUT_STATE_DRAGGING:
RCT2_CALLPROC_X(0x006E8C5C, x, y, state, widgetIndex, w, widget, 0);
break;
case INPUT_STATE_VIEWPORT_LEFT:
case INPUT_STATE_VIEWPORT_DRAG:
{
int dx, dy;
@@ -411,7 +415,7 @@ static void game_handle_input_mouse(int x, int y, int state)
case INPUT_STATE_DROPDOWN_ACTIVE:
RCT2_CALLPROC_X(0x006E8DA7, x, y, state, widgetIndex, w, widget, 0);
break;
case INPUT_STATE_VIEWPORT_RIGHT:
case INPUT_STATE_VIEWPORT_LEFT:
RCT2_CALLPROC_X(0x006E87B4, x, y, state, widgetIndex, w, widget, 0);
break;
case INPUT_STATE_SCROLL_LEFT:
@@ -425,3 +429,269 @@ static void game_handle_input_mouse(int x, int y, int state)
break;
}
}
/**
*
* 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);
if (w != NULL && widgetIndex != -1 && widget->type == WWT_SCROLL) {
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = y;
esi = w;
edi = widget;
RCT2_CALLFUNC_X(0x006E9F92, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); // widget_scoll_get_part
eax &= 0xFFFF;
ebx &= 0xFFFF;
ecx &= 0xFFFF;
edx &= 0xFFFF;
if (ecx < 0)
goto showTooltip;
if (ecx == 0) {
RCT2_CALLPROC_X(w->event_handlers[WE_SCROLL_MOUSEOVER], edx, 0, eax, ebx, w, 0, 0);
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)
{
rct_window *w;
// 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;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER, rct_windowclass) = windowNumber;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX, rct_windowclass) = widgetIndex;
// 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;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, w, 0, 0);
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));
}
/**
*
* 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;
widget = &w->widgets[widgetIndex];
}
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;
window_bring_to_front(w);
if (widgetIndex == -1)
return;
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;
w = window_find_by_id(windowClass, windowNumber);
if (w == NULL)
break;
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_DOWN], x, y, 0, RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), w, 0, 0);
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;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windowclass) = windowNumber;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint16) = x;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint16) = y;
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = y;
esi = w;
edi = widget;
RCT2_CALLFUNC_X(0x006E9F92, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); // widget_scoll_get_part
eax &= 0xFFFF;
ebx &= 0xFFFF;
ecx &= 0xFFFF;
edx &= 0xFFFF;
RCT2_GLOBAL(0x009DE548, uint16) = ecx;
RCT2_GLOBAL(0x009DE54C, uint32) = edx;
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_15], RCT2_GLOBAL(0x009DE54C, uint32), ebx, ecx, edx, w, widget, 0);
switch (ecx) {
case SCROLL_PART_VIEW:
RCT2_CALLPROC_X(w->event_handlers[WE_SCROLL_MOUSEDOWN], edx / sizeof(rct_scroll), ebx, eax, ebx, w, widget, 0);
break;
case SCROLL_PART_HSCROLLBAR_LEFT:
// 0x006E9A60
RCT2_CALLPROC_X(0x006E9A60, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_HSCROLLBAR_RIGHT:
// 0x006E9ABF
RCT2_CALLPROC_X(0x006E9ABF, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_HSCROLLBAR_LEFT_TROUGH:
// 0x006E9B47
RCT2_CALLPROC_X(0x006E9B47, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH:
// 0x006E9BB7
RCT2_CALLPROC_X(0x006E9BB7, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_VSCROLLBAR_TOP:
// 0x006E9C37
RCT2_CALLPROC_X(0x006E9C37, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_VSCROLLBAR_BOTTOM:
// 0x006E9C96
RCT2_CALLPROC_X(0x006E9C96, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_VSCROLLBAR_TOP_TROUGH:
// 0x006E9D1E
RCT2_CALLPROC_X(0x006E9D1E, 0, 0, 0, 0, w, 0, 0);
break;
case SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH:
// 0x006E9D8E
RCT2_CALLPROC_X(0x006E9D8E, 0, 0, 0, 0, w, 0, 0);
break;
}
break;
default:
if (!widget_is_enabled(w, widgetIndex))
break;
if (widget_is_disabled(w, widgetIndex))
break;
sound_play_panned(4, w->x + (widget->left + widget->right) / 2);
// Set new cursor down widget
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) = windowClass;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windowclass) = windowNumber;
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, rct_windowclass) = widgetIndex;
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);
RCT2_CALLPROC_X(w->event_handlers[WE_MOUSE_DOWN], 0, 0, 0, widgetIndex, w, widget, 0);
break;
}
}

View File

@@ -89,6 +89,11 @@ void gfx_clear(rct_drawpixelinfo *dpi, int colour)
}
}
void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour)
{
gfx_fill_rect(dpi, x, y, x, y, colour);
}
/**
*
* rct2: 0x00684466

View File

@@ -49,6 +49,7 @@ typedef struct {
void gfx_load_g1();
void gfx_clear(rct_drawpixelinfo *dpi, int colour);
void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour);
void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour);
void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour);
void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si);

View File

@@ -69,15 +69,16 @@ void map_init()
for (i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++) {
map_element = GET_MAP_ELEMENT(i);
map_element->type = (MAP_ELEMENT_TYPE_SURFACE << 2) | 1;
map_element->type = (MAP_ELEMENT_TYPE_SURFACE << 2);
map_element->flags = MAP_ELEMENT_FLAG_LAST_TILE;
map_element->base_height = 14;
map_element->clearance_height = 14;
map_element->properties.surface.slope = 1 << 5;
map_element->properties.surface.slope = 0;
map_element->properties.surface.grass_length = 1;
map_element->properties.surface.ownership = 0;
map_element_set_terrain(map_element, TERRAIN_GRASS);
map_element_set_terrain_edge(map_element, TERRAIN_EDGE_ROCK);
}
RCT2_GLOBAL(0x013B0E70, sint16) = 0;

View File

@@ -776,6 +776,11 @@ static void widget_draw_image(rct_drawpixelinfo *dpi, rct_window *w, int widgetI
}
}
int widget_is_enabled(rct_window *w, int widgetIndex)
{
return w->enabled_widgets & (1LL << widgetIndex);
}
int widget_is_disabled(rct_window *w, int widgetIndex)
{
return w->disabled_widgets & (1LL << widgetIndex);

View File

@@ -57,6 +57,7 @@ typedef enum {
void widget_scroll_update_thumbs(rct_window *w, int widget_index);
void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
int widget_is_enabled(rct_window *w, int widgetIndex);
int widget_is_disabled(rct_window *w, int widgetIndex);
int widget_is_pressed(rct_window *w, int widgetIndex);
int widget_is_highlighted(rct_window *w, int widgetIndex);

View File

@@ -109,7 +109,7 @@ rct_window *window_create(int x, int y, int width, int height, uint32 *event_han
if (RCT2_NEW_WINDOW == &(RCT2_FIRST_WINDOW[12])) {
// Close least recently used window
for (w = RCT2_FIRST_WINDOW; w < RCT2_NEW_WINDOW; w++)
if (!(w->flags & (0x01 | 0x02 | 0x200)))
if (!(w->flags & (WF_0 | WF_1 | WF_9)))
break;
window_close(w);
@@ -118,16 +118,16 @@ rct_window *window_create(int x, int y, int width, int height, uint32 *event_han
w = RCT2_NEW_WINDOW;
// Flags
if (flags & 0x01) {
if (flags & WF_0) {
for (; w >= RCT2_FIRST_WINDOW + 1; w--) {
if ((w - 1)->flags & 0x02)
if ((w - 1)->flags & WF_1)
continue;
if ((w - 1)->flags & 0x01)
if ((w - 1)->flags & WF_0)
break;
}
} else if (!(flags & 0x02)) {
} else if (!(flags & WF_1)) {
for (; w >= RCT2_FIRST_WINDOW + 1; w--) {
if (!((w - 1)->flags & 0x02))
if (!((w - 1)->flags & WF_1))
break;
}
}
@@ -143,7 +143,7 @@ rct_window *window_create(int x, int y, int width, int height, uint32 *event_han
w->flags = flags;
// Play sound
if (!(flags & (0x01 | 0x02)))
if (!(flags & (WF_0 | WF_1)))
sound_play_panned(40, x + (width / 2));
w->number = 0;
@@ -296,7 +296,7 @@ rct_window *window_find_from_point(int x, int y)
if (x < w->x || x >= w->x + w->width || y < w->y || y >= w->y + w->height)
continue;
if (w->flags & 0x20) {
if (w->flags & WF_5) {
widget_index = window_find_widget_from_point(w, x, y);
if (widget_index == -1)
continue;

View File

@@ -29,8 +29,8 @@ union rct_window_event;
typedef void wndproc(struct rct_window*, union rct_window_event*);
typedef sint8 rct_windowclass;
typedef sint16 rct_windownumber;
typedef uint8 rct_windowclass;
typedef uint16 rct_windownumber;
typedef struct {
rct_windowclass classification;
@@ -75,6 +75,10 @@ typedef struct {
uint16 flags; // 0x12
} rct_viewport;
/**
* Scroll structure
* size: 0x12
*/
typedef struct {
uint16 flags; // 0x00
sint16 h_left; // 0x02
@@ -110,7 +114,7 @@ typedef struct rct_window {
rct_windownumber number; // 0x03C
uint16 flags; // 0x03E
rct_scroll scrolls[3]; // 0x040
uint8 var_076[0x400];
uint8 var_076[1024];
sint16 var_476;
sint16 pad_478;
sint16 var_47A;
@@ -182,9 +186,13 @@ typedef enum {
WF_DISABLE_VP_SCROLL = 1 << 9,
*/
WF_0 = (1 << 0),
WF_1 = (1 << 1),
WF_TRANSPARENT = (1 << 4),
WF_5 = (1 << 5),
WF_RESIZABLE = (1 << 8),
WF_10,
WF_9 = (1 << 9),
WF_10 = (1 << 10),
WF_WHITE_BORDER_ONE = (1 << 12),
WF_WHITE_BORDER_MASK = (1 << 12) | (1 << 13),
} WINDOW_FLAGS;
@@ -222,9 +230,9 @@ enum {
INPUT_STATE_NORMAL = 1,
INPUT_STATE_WIDGET_PRESSED = 2,
INPUT_STATE_DRAGGING = 3,
INPUT_STATE_VIEWPORT_LEFT = 4,
INPUT_STATE_VIEWPORT_DRAG = 4,
INPUT_STATE_DROPDOWN_ACTIVE = 5,
INPUT_STATE_VIEWPORT_RIGHT = 6,
INPUT_STATE_VIEWPORT_LEFT = 6,
INPUT_STATE_SCROLL_LEFT = 7,
INPUT_STATE_RESIZING = 8,
};
@@ -236,6 +244,7 @@ enum {
WC_TOOLTIP = 5,
WC_DROPDOWN = 6,
WC_ABOUT = 8,
WC_ERROR = 11,
WC_RIDE = 12,
WC_RIDE_CONSTRUCTION = 13,
WC_RIDE_LIST = 15,

View File

@@ -18,6 +18,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _WINDOW_DROPDOWN_H_
#define _WINDOW_DROPDOWN_H_
#include "rct2.h"
#define DROPDOWN_SEPARATOR 0
@@ -32,3 +35,5 @@ void window_dropdown_show_text(int x, int y, int extray, uint8 colour, uint8 fla
void window_dropdown_show_text_custom_width(int x, int y, int extray, uint8 colour, uint8 flags, int num_items, int width);
void window_dropdown_show_image(int x, int y, int extray, uint8 colour, uint8 flags, int numItems, int itemWidth, int itemHeight, int numColumns);
void window_dropdown_close();
#endif

217
src/window_tooltip.c Normal file
View File

@@ -0,0 +1,217 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <memory.h>
#include "addresses.h"
#include "strings.h"
#include "widget.h"
#include "window.h"
enum {
WIDX_BACKGROUND
};
static rct_widget window_tooltip_widgets[] = {
{ WWT_IMGBTN, 0, 0, 199, 0, 31, 0x0FFFFFFFF, STR_NONE },
{ WIDGETS_END },
};
static void window_tooltip_emptysub() { }
static void window_tooltip_onclose();
static void window_tooltip_update();
static void window_tooltip_paint();
static uint32 window_tooltip_events[] = {
window_tooltip_onclose,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_update,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_emptysub,
window_tooltip_paint,
window_tooltip_emptysub
};
void window_tooltip_reset(int x, int y)
{
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_X, uint8) = x;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_CURSOR_Y, uint8) = y;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 1;
RCT2_GLOBAL(0x009DE518, uint32) &= ~(1 << 4);
}
/**
*
* rct2: 0x006EA10D
*/
void window_tooltip_open(rct_window *widgetWindow, int widgetIndex, int x, int y)
{
rct_window *w;
rct_widget *widget;
int width, height;
if (widgetWindow == NULL || widgetIndex == -1)
return;
widget = &widgetWindow->widgets[widgetIndex];
RCT2_CALLPROC_X(widgetWindow->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, widgetWindow, 0, 0);
if (widget->tooltip == 0xFFFF)
return;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = widgetWindow->classification;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER, rct_windownumber) = widgetWindow->number;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = widgetIndex;
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = widgetIndex;
esi = widgetWindow;
RCT2_CALLFUNC_X(widgetWindow->event_handlers[WE_TOOLTIP], &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if ((eax & 0xFFFF) == 0xFFFF)
return;
w = window_find_by_id(WC_ERROR, 0);
if (w != NULL)
return;
RCT2_GLOBAL(0x0142006C, sint32) = -1;
format_string(0x0141ED68, widget->tooltip, 0x013CE952);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
esi = 0x0141ED68;
RCT2_CALLFUNC_X(0x006C23B1, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
ecx &= 0xFFFF;
if (ecx > 196)
ecx = 196;
esi = 0x0141ED68;
edi = ecx + 1;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
RCT2_CALLFUNC_X(0x006C21E2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
ecx &= 0xFFFF;
edi &= 0xFFFF;
RCT2_GLOBAL(0x01420044, sint16) = edi;
width = ecx + 3;
height = ((edi + 1) * 10) + 4;
window_tooltip_widgets[WIDX_BACKGROUND].right = width;
window_tooltip_widgets[WIDX_BACKGROUND].bottom = height;
memcpy(0x0141FE44, 0x0141ED68, 512);
x = clamp(0, x - (width / 2), RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) - width);
y = clamp(22, y + 26, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - height - 40);
w = window_create(x, y, width, height, window_tooltip_events, WC_TOOLTIP, WF_TRANSPARENT | WF_1);
w->widgets = window_tooltip_widgets;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) = 0;
}
/**
*
* rct2: 0x006E98C6
*/
void window_tooltip_close()
{
window_close_by_id(WC_TOOLTIP, 0);
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS, rct_windowclass) = 255;
RCT2_GLOBAL(0x0142006C, sint32) = -1;
RCT2_GLOBAL(0x009DE51E, uint8) = 0;
}
/**
*
* rct2: 0x006EA578
*/
static void window_tooltip_onclose()
{
RCT2_GLOBAL(0x009BC3B0, uint8) = 0;
}
/**
*
* rct2: 0x006EA580
*/
static void window_tooltip_update()
{
if (RCT2_GLOBAL(0x009DE51E, uint8) == 0)
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) = 0;
}
/**
*
* rct2: 0x006EA41D
*/
static void window_tooltip_paint()
{
rct_window *w;
rct_drawpixelinfo *dpi;
__asm mov w, esi
__asm mov dpi, edi
int left = w->x;
int top = w->y;
int right = w->x + w->width - 1;
int bottom = w->y + w->height - 1;
// Background
gfx_fill_rect(dpi, left + 1, top + 1, right - 1, bottom - 1, 0x0200002D);
gfx_fill_rect(dpi, left + 1, top + 1, right - 1, bottom - 1, 0x02000084);
// Sides
gfx_fill_rect(dpi, left + 0, top + 2, left + 0, bottom - 2, 0x0200002F);
gfx_fill_rect(dpi, right + 0, top + 2, right + 0, bottom - 2, 0x0200002F);
gfx_fill_rect(dpi, left + 2, bottom + 0, right - 2, bottom + 0, 0x0200002F);
gfx_fill_rect(dpi, left + 2, top + 0, right - 2, top + 0, 0x0200002F);
// Corners
gfx_draw_pixel(dpi, left + 1, top + 1, 0x0200002F);
gfx_draw_pixel(dpi, right - 1, top + 1, 0x0200002F);
gfx_draw_pixel(dpi, left + 1, bottom - 1, 0x0200002F);
gfx_draw_pixel(dpi, right - 1, bottom - 1, 0x0200002F);
// Text
RCT2_CALLPROC_X(0x006C1DB7, 0, 0, w->x + ((w->width + 1) / 2) - 1, w->y + 1, 0x0141FE44, dpi, RCT2_GLOBAL(0x01420044, uint16));
}

31
src/window_tooltip.h Normal file
View File

@@ -0,0 +1,31 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _WINDOW_TOOLTIP_H_
#define _WINDOW_TOOLTIP_H_
#include "rct2.h"
#include "window.h"
void window_tooltip_reset(int x, int y);
void window_tooltip_open(rct_window *widgetWindow, int widgetIndex, int x, int y);
void window_tooltip_close();
#endif