diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 6cff1ca042..420cec74d5 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -86,6 +86,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index ae7245d7f1..f5d490b809 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -254,6 +254,9 @@
Windows
+
+ Windows
+
diff --git a/src/gfx.c b/src/gfx.c
index 8890e67b5d..9cebbf2674 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -27,6 +27,10 @@
#include "strings.h"
#include "window.h"
+// HACK These were originally passed back through registers
+int gLastDrawStringX;
+int gLastDrawStringY;
+
uint8 _screenDirtyBlocks[5120];
static void gfx_draw_dirty_blocks(int x, int y, int columns, int rows);
@@ -486,5 +490,17 @@ void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int co
*/
void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y)
{
- RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, format, dpi, 0);
+ int eax, ebx, ecx, edx, esi, edi, ebp;
+
+ eax = colour;
+ ebx = 0;
+ ecx = x;
+ edx = y;
+ esi = format;
+ edi = dpi;
+ ebp = 0;
+ RCT2_CALLFUNC_X(0x00682702, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
+
+ gLastDrawStringX = ecx;
+ gLastDrawStringY = edx;
}
diff --git a/src/gfx.h b/src/gfx.h
index 47ef36c70a..9af771d4f8 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -46,6 +46,9 @@ typedef struct {
sint16 unused; // 0x0E
} rct_g1_element;
+extern int gLastDrawStringX;
+extern int gLastDrawStringY;
+
void gfx_load_g1();
void gfx_clear(rct_drawpixelinfo *dpi, int colour);
diff --git a/src/strings.h b/src/strings.h
index 583bc4738e..7a3c5b247d 100644
--- a/src/strings.h
+++ b/src/strings.h
@@ -197,6 +197,17 @@ enum {
STR_BUILD_FOOTPATH_TIP = 1173,
+ STR_FOOTPATHS = 1181,
+ STR_TYPE = 1182,
+ STR_DIRECTION = 1183,
+ STR_SLOPE = 1184,
+ STR_DIRECTION_TIP = 1185,
+ STR_SLOPE_DOWN_TIP = 1186,
+ STR_LEVEL_TIP = 1187,
+ STR_SLOPE_UP_TIP = 1188,
+ STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP = 1189,
+ STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP = 1190,
+
STR_CLOSED = 1194,
STR_TEST_RUN = 1195,
STR_OPEN = 1196,
@@ -212,10 +223,16 @@ enum {
STR_NUMERIC_UP = 1218,
STR_NUMERIC_DOWN = 1219,
+ STR_QUEUE_LINE_PATH_TIP = 1423,
+ STR_FOOTPATH_TIP = 1424,
+
STR_FREE = 1430,
STR_GUESTS = 1463,
+ STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP = 1655,
+ STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP = 1656,
+
STR_GUESTS_TIP = 1693,
STR_STAFF_TIP = 1694,
diff --git a/src/widget.c b/src/widget.c
index cf4c44f959..cccfc1434d 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -33,6 +33,7 @@ static void widget_text_button(rct_drawpixelinfo *dpi, rct_window *w, int widget
static void widget_text_unknown(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_text(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
@@ -94,6 +95,10 @@ void widget_scroll_update_thumbs(rct_window *w, int widget_index)
}
}
+/**
+ *
+ * rct2: 0x006EB2A8
+ */
void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
{
switch (w->widgets[widgetIndex].type) {
@@ -134,7 +139,8 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
break;
case WWT_18:
break;
- case WWT_19:
+ case WWT_GROUPBOX:
+ widget_groupbox_draw(dpi, w, widgetIndex);
break;
case WWT_CAPTION:
widget_caption_draw(dpi, w, widgetIndex);
@@ -500,6 +506,66 @@ static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetI
widget_text(dpi, w, widgetIndex);
}
+/**
+ *
+ * rct2: 0x006EB535
+ */
+static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b, textRight;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left + 5;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+ textRight = l;
+
+ // Text
+ if (widget->image != (uint32)-1) {
+ colour = w->colours[widget->colour] & 0x7F;
+ if (colour & 1)
+ colour |= 0x40;
+ gfx_draw_string_left(dpi, widget->image, 0x013CE952, colour, l, t);
+ textRight = gLastDrawStringX + 1;
+ }
+
+ // Border
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top + 4;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Get the colour
+ colour = w->colours[widget->colour] & 0x7F;
+
+ // Border left of text
+ gfx_fill_rect(dpi, l, t, l + 4, t, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
+ gfx_fill_rect(dpi, l + 1, t + 1, l + 4, t + 1, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
+
+ // Border right of text
+ gfx_fill_rect(dpi, textRight, t, r - 1, t, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
+ gfx_fill_rect(dpi, textRight, t + 1, r - 2, t + 1, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
+
+ // Border right
+ gfx_fill_rect(dpi, r - 1, t + 1, r - 1, b - 1, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
+ gfx_fill_rect(dpi, r, t, r, b, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
+
+ // Border bottom
+ gfx_fill_rect(dpi, l, b - 1, r - 2, b - 1, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
+ gfx_fill_rect(dpi, l, b, r - 1, b, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
+
+ // Border left
+ gfx_fill_rect(dpi, l, t + 1, l, b - 2, RCT2_ADDRESS(0x0141FC47, uint8)[colour * 8]);
+ gfx_fill_rect(dpi, l + 1, t + 2, l + 1, b - 2, RCT2_ADDRESS(0x0141FC4B, uint8)[colour * 8]);
+}
+
/**
*
* rct2: 0x006EB2F9
diff --git a/src/widget.h b/src/widget.h
index 96ac2e6d68..ea4eccbf11 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -43,7 +43,7 @@ typedef enum {
WWT_DROPDOWN = 16,
WWT_VIEWPORT = 17,
WWT_18,
- WWT_19,
+ WWT_GROUPBOX = 19,
WWT_CAPTION = 20,
WWT_CLOSEBOX = 21,
WWT_SCROLL = 22,
diff --git a/src/window.h b/src/window.h
index 41ec37d2e7..62f2bcf74d 100644
--- a/src/window.h
+++ b/src/window.h
@@ -324,6 +324,7 @@ void window_main_open();
void window_game_top_toolbar_open();
void window_game_bottom_toolbar_open();
void window_about_open();
+void window_footpath_open();
void window_title_menu_open();
void window_title_exit_open();
void window_title_logo_open();
diff --git a/src/window_footpath.c b/src/window_footpath.c
new file mode 100644
index 0000000000..e6c01fae36
--- /dev/null
+++ b/src/window_footpath.c
@@ -0,0 +1,210 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#include
+#include "addresses.h"
+#include "strings.h"
+#include "sprites.h"
+#include "viewport.h"
+#include "widget.h"
+#include "window.h"
+
+static enum WINDOW_FOOTPATH_WIDGET_IDX {
+ WIDX_BACKGROUND,
+ WIDX_TITLE,
+ WIDX_CLOSE,
+
+ WIDX_TYPE_GROUP,
+ WIDX_FOOTPATH_TYPE,
+ WIDX_QUEUELINE_TYPE,
+
+ WIDX_DIRECTION_GROUP,
+ WIDX_DIRECTION_NW,
+ WIDX_DIRECTION_NE,
+ WIDX_DIRECTION_SW,
+ WIDX_DIRECTION_SE,
+
+ WIDX_SLOPE_GROUP,
+ WIDX_SLOPEDOWN,
+ WIDX_LEVEL,
+ WIDX_SLOPEUP,
+ WIDX_CONSTRUCT,
+ WIDX_REMOVE,
+
+ WIDX_MODE_GROUP,
+ WIDX_CONSTRUCT_ON_LAND,
+ WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL,
+};
+
+static rct_widget window_footpath_widgets[] = {
+ { WWT_FRAME, 0, 0, 105, 0, 380, 0x0FFFFFFFF, STR_NONE },
+ { WWT_CAPTION, 0, 1, 104, 1, 14, STR_FOOTPATHS, STR_WINDOW_TITLE_TIP },
+ { WWT_CLOSEBOX, 0, 93, 103, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
+
+ // Type group
+ { WWT_GROUPBOX, 0, 3, 102, 17, 71, STR_TYPE, STR_NONE },
+ { WWT_FLATBTN, 1, 6, 52, 30, 65, 0xFFFFFFFF, STR_FOOTPATH_TIP },
+ { WWT_FLATBTN, 1, 53, 99, 30, 65, 0xFFFFFFFF, STR_QUEUE_LINE_PATH_TIP },
+
+ // Direction group
+ { WWT_GROUPBOX, 0, 3, 102, 75, 151, STR_DIRECTION, STR_NONE },
+ { WWT_FLATBTN, 1, 53, 97, 87, 115, 5635, STR_DIRECTION_TIP },
+ { WWT_FLATBTN, 1, 53, 97, 116, 144, 5636, STR_DIRECTION_TIP },
+ { WWT_FLATBTN, 1, 8, 52, 116, 144, 5637, STR_DIRECTION_TIP },
+ { WWT_FLATBTN, 1, 8, 52, 87, 115, 5638, STR_DIRECTION_TIP },
+
+ // Slope group
+ { WWT_GROUPBOX, 0, 3, 102, 155, 195, STR_SLOPE, STR_NONE },
+ { WWT_FLATBTN, 1, 17, 40, 167, 190, 5145, STR_SLOPE_DOWN_TIP },
+ { WWT_FLATBTN, 1, 41, 64, 167, 190, 5146, STR_LEVEL_TIP },
+ { WWT_FLATBTN, 1, 65, 88, 167, 190, 5147, STR_SLOPE_UP_TIP },
+ { WWT_FLATBTN, 1, 8, 97, 202, 291, 0xFFFFFFFF, STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP },
+ { WWT_FLATBTN, 1, 30, 75, 295, 318, 5162, STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP },
+
+ // Mode group
+ { WWT_GROUPBOX, 0, 3, 102, 321, 374, 0xFFFFFFFF, STR_NONE },
+ { WWT_FLATBTN, 1, 13, 48, 332, 367, 5639, STR_CONSTRUCT_FOOTPATH_ON_LAND_TIP },
+ { WWT_FLATBTN, 1, 57, 92, 332, 367, 5640, STR_CONSTRUCT_BRIDGE_OR_TUNNEL_FOOTPATH_TIP },
+ { WIDGETS_END },
+};
+
+static void window_footpath_emptysub() { }
+static void window_footpath_mouseup();
+static void window_footpath_paint();
+
+static uint32 window_footpath_events[] = {
+ window_footpath_emptysub,
+ window_footpath_mouseup,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_emptysub,
+ window_footpath_paint,
+ window_footpath_emptysub
+};
+
+/**
+ *
+ * rct2: 0x006A7C43
+ */
+void window_footpath_open()
+{
+ rct_window* window;
+
+ // Check if window is already open
+ window = window_bring_to_front_by_id(WC_FOOTPATH, 0);
+ if (window != NULL)
+ return;
+
+ window = window_create(
+ 0,
+ 29,
+ 106,
+ 381,
+ window_footpath_events,
+ WC_FOOTPATH,
+ 0
+ );
+ window->widgets = window_footpath_widgets;
+ window->enabled_widgets =
+ (1 << WIDX_CLOSE) |
+ (1 << WIDX_FOOTPATH_TYPE) |
+ (1 << WIDX_QUEUELINE_TYPE) |
+ (1 << WIDX_DIRECTION_NW) |
+ (1 << WIDX_DIRECTION_NE) |
+ (1 << WIDX_DIRECTION_SW) |
+ (1 << WIDX_DIRECTION_SE) |
+ (1 << WIDX_SLOPEDOWN) |
+ (1 << WIDX_LEVEL) |
+ (1 << WIDX_SLOPEUP) |
+ (1 << WIDX_CONSTRUCT) |
+ (1 << WIDX_REMOVE) |
+ (1 << WIDX_CONSTRUCT_ON_LAND) |
+ (1 << WIDX_CONSTRUCT_BRIDGE_OR_TUNNEL);
+
+ window_init_scroll_widgets(window);
+ RCT2_CALLPROC_EBPSAFE(0x006EE65A);
+ show_gridlines();
+ window->colours[0] = 24;
+ window->colours[1] = 24;
+ window->colours[2] = 24;
+
+ RCT2_CALLPROC_EBPSAFE(0x006EE281);
+ RCT2_GLOBAL(0x00F3EF99, uint8) = 0;
+ RCT2_CALLPROC_X(0x006EE212, 17, 0, 0, 18, window, 0, 0);
+ RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
+ RCT2_GLOBAL(0x00F3EF9F, uint8) = 0;
+ RCT2_CALLPROC_EBPSAFE(0x006A855C);
+}
+
+/**
+ *
+ * rct2: 0x006A7E92
+ */
+static void window_footpath_mouseup()
+{
+ short widgetIndex;
+ rct_window *w;
+
+ __asm mov widgetIndex, dx
+ __asm mov w, esi
+
+ switch (widgetIndex) {
+ case WIDX_CLOSE:
+ window_close(w);
+ break;
+ }
+}
+
+/**
+ *
+ * rct2: 0x006A7D8B
+ */
+static void window_footpath_paint()
+{
+ int x, y;
+ rct_window *w;
+ rct_drawpixelinfo *dpi;
+
+ __asm mov w, esi
+ __asm mov dpi, edi
+
+ window_draw_widgets(w, dpi);
+}
\ No newline at end of file
diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c
index 959fe03d5b..a0527fba7c 100644
--- a/src/window_game_top_toolbar.c
+++ b/src/window_game_top_toolbar.c
@@ -212,11 +212,11 @@ static void window_game_top_toolbar_mouseup()
RCT2_CALLPROC_EBPSAFE(0x006E0FEF);
break;
case WIDX_PATH:
- if (window_find_by_id(20, 0) == NULL) {
- RCT2_CALLPROC_EBPSAFE(0x00006A7C43);
+ if (window_find_by_id(WC_FOOTPATH, 0) == NULL) {
+ window_footpath_open();
} else {
RCT2_CALLPROC_EBPSAFE(0x006EE281);
- window_close_by_id(0x80 | 20, 0);
+ window_close_by_id(0x80 | WC_FOOTPATH, 0);
}
break;
case WIDX_CONSTRUCT_RIDE: