mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-06 06:32:56 +01:00
add window snapping
This commit is contained in:
10
src/config.c
10
src/config.c
@@ -79,7 +79,7 @@ general_configuration_t gGeneral_config_default = {
|
||||
SCREENSHOT_FORMAT_PNG, // screenshot_format
|
||||
"", // game_path
|
||||
MEASUREMENT_FORMAT_IMPERIAL, // measurement_format
|
||||
TEMPERATURE_FORMAT_F, // temperature_format
|
||||
TEMPERATURE_FORMAT_C, // temperature_format
|
||||
CURRENCY_POUNDS, // currency_format
|
||||
0, // construction_marker_colour
|
||||
1, // edge_scrolling
|
||||
@@ -90,7 +90,8 @@ general_configuration_t gGeneral_config_default = {
|
||||
0, // fullscreen mode (default: windowed)
|
||||
-1, // window_width
|
||||
-1, // window_height
|
||||
LANGUAGE_ENGLISH_UK // language
|
||||
LANGUAGE_ENGLISH_UK, // language
|
||||
5 // window_snap_proximity
|
||||
};
|
||||
sound_configuration_t gSound_config;
|
||||
|
||||
@@ -257,6 +258,8 @@ void config_write_ini_general(FILE *fp)
|
||||
fprintf(fp, "window_height = %d\n", gGeneral_config.window_height);
|
||||
|
||||
fprintf(fp, "language = %d\n", gGeneral_config.language);
|
||||
|
||||
fprintf(fp, "window_snap_proximity = %d\n", gGeneral_config.window_snap_proximity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -543,6 +546,9 @@ static void config_general(char *setting, char *value){
|
||||
else if (strcmp(setting, "language") == 0) {
|
||||
gGeneral_config.language = atoi(value);
|
||||
}
|
||||
else if (strcmp(setting, "window_snap_proximity") == 0) {
|
||||
gGeneral_config.window_snap_proximity = clamp(0, atoi(value), 255);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -133,6 +133,7 @@ typedef struct general_configuration {
|
||||
sint16 window_width;
|
||||
sint16 window_height;
|
||||
uint16 language;
|
||||
uint8 window_snap_proximity;
|
||||
} general_configuration_t;
|
||||
|
||||
static const struct { const char *key; int value; } _currencyLookupTable[] = {
|
||||
|
||||
40
src/input.c
40
src/input.c
@@ -67,6 +67,7 @@ void game_handle_key_scroll();
|
||||
static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex);
|
||||
void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_window* w, rct_widget* widget);
|
||||
void sub_6ED990(char cursor_id);
|
||||
static void input_window_drag(rct_window *w, int lastX, int lastY, int newX, int newY);
|
||||
|
||||
#pragma region Mouse input
|
||||
|
||||
@@ -249,29 +250,23 @@ static void game_handle_input_mouse(int x, int y, int state)
|
||||
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) {
|
||||
input_window_drag(
|
||||
w,
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16),
|
||||
x,
|
||||
y
|
||||
);
|
||||
|
||||
// RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_X, sint16) = x;
|
||||
// RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, sint16) = y;
|
||||
|
||||
if (state == 2) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = INPUT_STATE_NORMAL;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TIMEOUT, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint16);
|
||||
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;
|
||||
|
||||
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_18], 0, 0, x, y, (int)w, 0, 0);
|
||||
}
|
||||
@@ -488,6 +483,11 @@ static void game_handle_input_mouse(int x, int y, int state)
|
||||
}
|
||||
}
|
||||
|
||||
static void input_window_drag(rct_window *w, int wdx, int wdy, int x, int y)
|
||||
{
|
||||
window_move_and_snap(w, x - wdx, y - wdy, gGeneral_config.window_snap_proximity);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006ED833
|
||||
@@ -696,8 +696,8 @@ static void input_leftmousedown(int x, int y, rct_window *w, int widgetIndex)
|
||||
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_LAST_X, uint16) = x - w->x;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_LAST_Y, uint16) = y - w->y;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) = windowClass;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) = windowNumber;
|
||||
break;
|
||||
|
||||
@@ -1414,6 +1414,11 @@ void window_draw_viewport(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
viewport_render(dpi, w->viewport, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height);
|
||||
}
|
||||
|
||||
void window_set_position(rct_window *w, int x, int y)
|
||||
{
|
||||
window_move_position(w, x - w->x, y - w->y);
|
||||
}
|
||||
|
||||
void window_move_position(rct_window *w, int dx, int dy)
|
||||
{
|
||||
if (dx == 0 && dy == 0)
|
||||
@@ -1827,4 +1832,164 @@ void window_update_viewport_ride_music()
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void window_snap_left(rct_window *w, int proximity)
|
||||
{
|
||||
int right, rightMost, wLeftProximity, wRightProximity, wBottom;
|
||||
rct_window *mainWindow, *w2;
|
||||
|
||||
mainWindow = window_get_main();
|
||||
|
||||
wBottom = w->y + w->height;
|
||||
wLeftProximity = w->x - (proximity * 2);
|
||||
wRightProximity = w->x + (proximity * 2);
|
||||
rightMost = MININT32;
|
||||
for (w2 = g_window_list; w2 < RCT2_NEW_WINDOW; w2++) {
|
||||
if (w2 == w || w2 == mainWindow)
|
||||
continue;
|
||||
|
||||
right = w2->x + w2->width;
|
||||
|
||||
if (wBottom < w2->y || w->y > w2->y + w2->height)
|
||||
continue;
|
||||
|
||||
if (right < wLeftProximity || right > wRightProximity)
|
||||
continue;
|
||||
|
||||
rightMost = max(rightMost, right);
|
||||
}
|
||||
|
||||
if (0 >= wLeftProximity && 0 <= wRightProximity)
|
||||
rightMost = max(rightMost, 0);
|
||||
|
||||
if (rightMost != MININT32)
|
||||
w->x = rightMost;
|
||||
}
|
||||
|
||||
void window_snap_top(rct_window *w, int proximity)
|
||||
{
|
||||
int bottom, bottomMost, wTopProximity, wBottomProximity, wRight;
|
||||
rct_window *mainWindow, *w2;
|
||||
|
||||
mainWindow = window_get_main();
|
||||
|
||||
wRight = w->x + w->width;
|
||||
wTopProximity = w->y - (proximity * 2);
|
||||
wBottomProximity = w->y + (proximity * 2);
|
||||
bottomMost = MININT32;
|
||||
for (w2 = g_window_list; w2 < RCT2_NEW_WINDOW; w2++) {
|
||||
if (w2 == w || w2 == mainWindow)
|
||||
continue;
|
||||
|
||||
bottom = w2->y + w2->height;
|
||||
|
||||
if (wRight < w2->x || w->x > w2->x + w2->width)
|
||||
continue;
|
||||
|
||||
if (bottom < wTopProximity || bottom > wBottomProximity)
|
||||
continue;
|
||||
|
||||
bottomMost = max(bottomMost, bottom);
|
||||
}
|
||||
|
||||
if (0 >= wTopProximity && 0 <= wBottomProximity)
|
||||
bottomMost = max(bottomMost, 0);
|
||||
|
||||
if (bottomMost != MININT32)
|
||||
w->y = bottomMost;
|
||||
}
|
||||
|
||||
void window_snap_right(rct_window *w, int proximity)
|
||||
{
|
||||
int leftMost, wLeftProximity, wRightProximity, wRight, wBottom, screenWidth;
|
||||
rct_window *mainWindow, *w2;
|
||||
|
||||
mainWindow = window_get_main();
|
||||
|
||||
wRight = w->x + w->width;
|
||||
wBottom = w->y + w->height;
|
||||
wLeftProximity = wRight - (proximity * 2);
|
||||
wRightProximity = wRight + (proximity * 2);
|
||||
leftMost = MAXINT32;
|
||||
for (w2 = g_window_list; w2 < RCT2_NEW_WINDOW; w2++) {
|
||||
if (w2 == w || w2 == mainWindow)
|
||||
continue;
|
||||
|
||||
if (wBottom < w2->y || w->y > w2->y + w2->height)
|
||||
continue;
|
||||
|
||||
if (w2->x < wLeftProximity || w2->x > wRightProximity)
|
||||
continue;
|
||||
|
||||
leftMost = min(leftMost, w2->x);
|
||||
}
|
||||
|
||||
screenWidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16);
|
||||
if (screenWidth >= wLeftProximity && screenWidth <= wRightProximity)
|
||||
leftMost = min(leftMost, screenWidth);
|
||||
|
||||
if (leftMost != MAXINT32)
|
||||
w->x = leftMost - w->width;
|
||||
}
|
||||
|
||||
void window_snap_bottom(rct_window *w, int proximity)
|
||||
{
|
||||
int topMost, wTopProximity, wBottomProximity, wRight, wBottom, screenHeight;
|
||||
rct_window *mainWindow, *w2;
|
||||
|
||||
mainWindow = window_get_main();
|
||||
|
||||
wRight = w->x + w->width;
|
||||
wBottom = w->y + w->height;
|
||||
wTopProximity = wBottom - (proximity * 2);
|
||||
wBottomProximity = wBottom + (proximity * 2);
|
||||
topMost = MAXINT32;
|
||||
for (w2 = g_window_list; w2 < RCT2_NEW_WINDOW; w2++) {
|
||||
if (w2 == w || w2 == mainWindow)
|
||||
continue;
|
||||
|
||||
if (wRight < w2->x || w->x > w2->x + w2->width)
|
||||
continue;
|
||||
|
||||
if (w2->y < wTopProximity || w2->y > wBottomProximity)
|
||||
continue;
|
||||
|
||||
topMost = min(topMost, w2->y);
|
||||
}
|
||||
|
||||
screenHeight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16);
|
||||
if (screenHeight >= wTopProximity && screenHeight <= wBottomProximity)
|
||||
topMost = min(topMost, screenHeight);
|
||||
|
||||
if (topMost != MAXINT32)
|
||||
w->y = topMost - w->height;
|
||||
}
|
||||
|
||||
void window_move_and_snap(rct_window *w, int newWindowX, int newWindowY, int snapProximity)
|
||||
{
|
||||
int originalX = w->x;
|
||||
int originalY = w->y;
|
||||
|
||||
newWindowY = clamp(29, newWindowY, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - 34);
|
||||
|
||||
if (snapProximity > 0) {
|
||||
w->x = newWindowX;
|
||||
w->y = newWindowY;
|
||||
|
||||
window_snap_right(w, snapProximity);
|
||||
window_snap_bottom(w, snapProximity);
|
||||
window_snap_left(w, snapProximity);
|
||||
window_snap_top(w, snapProximity);
|
||||
|
||||
if (w->x == originalX && w->y == originalY)
|
||||
return;
|
||||
|
||||
newWindowX = w->x;
|
||||
newWindowY = w->y;
|
||||
w->x = originalX;
|
||||
w->y = originalY;
|
||||
}
|
||||
|
||||
window_set_position(w, newWindowX, newWindowY);
|
||||
}
|
||||
@@ -455,6 +455,7 @@ void window_draw(rct_window *w, int left, int top, int right, int bottom);
|
||||
void window_draw_widgets(rct_window *w, rct_drawpixelinfo *dpi);
|
||||
void window_draw_viewport(rct_drawpixelinfo *dpi, rct_window *w);
|
||||
|
||||
void window_set_position(rct_window *w, int x, int y);
|
||||
void window_move_position(rct_window *w, int dx, int dy);
|
||||
void window_resize(rct_window *w, int dw, int dh);
|
||||
void window_set_resize(rct_window *w, int minWidth, int minHeight, int maxWidth, int maxHeight);
|
||||
@@ -538,6 +539,8 @@ void RCT2_CALLPROC_WE_MOUSE_DOWN(int address, int widgetIndex, rct_window*w, rct
|
||||
|
||||
void sub_6EA73F();
|
||||
|
||||
void window_move_and_snap(rct_window *w, int newWindowX, int newWindowY, int snapProximity);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define window_get_register(w) \
|
||||
__asm mov w, esi
|
||||
|
||||
Reference in New Issue
Block a user