diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 498b457a32..3f8d3d5094 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -72,6 +72,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index c26549df6e..819aa8884e 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -203,6 +203,9 @@
Windows
+
+ Windows
+
diff --git a/src/addresses.h b/src/addresses.h
index bfc7390b62..781e4a36ff 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -99,6 +99,9 @@
#define RCT2_ADDRESS_CMDLINE 0x009E2D98
+#define RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE 0x009E2E24
+#define RCT2_ADDRESS_SELECTED_TERRAIN_EDGE 0x009E2E25
+
#define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
diff --git a/src/game.c b/src/game.c
index d1c60b04bc..53bc5f8ae3 100644
--- a/src/game.c
+++ b/src/game.c
@@ -25,10 +25,6 @@
#include "peep.h"
#include "window.h"
-void window_main_open();
-void window_game_top_toolbar_open();
-void window_game_bottom_toolbar_open();
-
/**
*
* rct2: 0x0066B5C0 (part of 0x0066B3E8)
@@ -100,7 +96,7 @@ void game_update()
RCT2_GLOBAL(0x01388698, uint16)++;
// Input
- RCT2_CALLPROC_X(0x00667919, 1, 0, 0, 0, 0, 0, 0); // read_input(1)
+ RCT2_GLOBAL(0x0141F568, uint8) = RCT2_GLOBAL(0x0013CA740, uint8);
RCT2_CALLPROC_EBPSAFE(0x006EA627); // window_manager_handle_input();
RCT2_CALLPROC_EBPSAFE(0x006838BD);
diff --git a/src/map.c b/src/map.c
index 359386a5f3..a011c00d15 100644
--- a/src/map.c
+++ b/src/map.c
@@ -28,6 +28,32 @@
static void tiles_init();
+void map_element_set_terrain(rct_map_element *element, int terrain)
+{
+ // Bit 3 for terrain is stored in element.type bit 0
+ if (terrain & 8)
+ element->type |= 1;
+ else
+ element->type &= ~1;
+
+ // Bits 0, 1, 2 for terrain are stored in element.terrain bit 5, 6, 7
+ element->properties.surface.terrain &= ~0xE0;
+ element->properties.surface.terrain = (terrain & 7) << 5;
+}
+
+void map_element_set_terrain_edge(rct_map_element *element, int terrain)
+{
+ // Bit 3 for terrain is stored in element.type bit 0
+ if (terrain & 8)
+ element->type |= 128;
+ else
+ element->type &= ~128;
+
+ // Bits 0, 1, 2 for terrain are stored in element.slope bit 5, 6, 7
+ element->properties.surface.slope &= ~0xE0;
+ element->properties.surface.slope = (terrain & 7) << 5;
+}
+
/**
*
* rct2: 0x0068AB4C
@@ -43,14 +69,15 @@ void map_init()
for (i = 0; i < MAX_TILE_MAP_ELEMENT_POINTERS; i++) {
map_element = GET_MAP_ELEMENT(i);
- map_element->type = 0;
+ map_element->type = (MAP_ELEMENT_TYPE_SURFACE << 2) | 1;
map_element->flags = MAP_ELEMENT_FLAG_LAST_TILE;
map_element->base_height = 14;
map_element->clearance_height = 14;
- map_element->properties.surface.slope = 0;
- map_element->properties.surface.terrain = 0;
+ map_element->properties.surface.slope = 1 << 5;
map_element->properties.surface.grass_length = 1;
map_element->properties.surface.ownership = 0;
+
+ map_element_set_terrain(map_element, TERRAIN_GRASS);
}
RCT2_GLOBAL(0x013B0E70, sint16) = 0;
diff --git a/src/map.h b/src/map.h
index 5508f52d0a..84e9d951e8 100644
--- a/src/map.h
+++ b/src/map.h
@@ -135,7 +135,23 @@ enum {
TERRAIN_ROCK,
TERRAIN_MARTIAN,
TERRAIN_CHECKERBOARD,
- TERRAIN_DIRTGRASS
+ TERRAIN_GRASS_CLUMPS,
+ TERRAIN_ICE,
+ TERRAIN_GRID_RED,
+ TERRAIN_GRID_YELLOW,
+ TERRAIN_GRID_BLUE,
+ TERRAIN_GRID_GREEN,
+ TERRAIN_SAND_DARK,
+ TERRAIN_SAND_LIGHT,
+ TERRAIN_CHECKERBOARD_INVERTED,
+ TERRAIN_UNDERGROUND_VIEW,
+};
+
+enum {
+ TERRAIN_EDGE_ROCK,
+ TERRAIN_EDGE_WOOD_RED,
+ TERRAIN_EDGE_WOOD_BLACK,
+ TERRAIN_EDGE_ICE
};
enum {
@@ -159,6 +175,7 @@ enum {
#define MAP_ELEMENT_SLOPE_MASK 0x1F
#define MAP_ELEMENT_WATER_HEIGHT_MASK 0x1F
+#define MAP_ELEMENT_SURFACE_TERRAIN_MASK 0xE0
#define MAX_MAP_ELEMENTS 196608
#define MAX_TILE_MAP_ELEMENT_POINTERS (256 * 256)
diff --git a/src/title.c b/src/title.c
index 61dd217f80..d63b3db46c 100644
--- a/src/title.c
+++ b/src/title.c
@@ -31,12 +31,6 @@
#include "scenario.h"
#include "viewport.h"
-// External functions
-void window_main_open();
-void window_title_menu_open();
-void window_title_exit_open();
-void window_title_logo_open();
-
#pragma region Showcase script
enum {
diff --git a/src/window.c b/src/window.c
index 2c048e2747..b613e01ce6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -424,6 +424,49 @@ rct_window *window_bring_to_front(rct_window *w)
return w;
}
+/**
+ *
+ * rct2: 0x006EE6EA
+ */
+void window_push_others_below(rct_window *w1)
+{
+ int push_amount;
+ rct_window* w2;
+
+ // Enumerate through all other windows
+ for (w2 = RCT2_FIRST_WINDOW; w2 < RCT2_NEW_WINDOW; w2++) {
+ if (w1 == w2)
+ continue;
+
+ // ?
+ if (w2->flags & 3)
+ continue;
+
+ // Check if w2 intersects with w1
+ if (w2->x > (w1->x + w1->width) || w2->x + w2->width < w1->x)
+ continue;
+ if (w2->y > (w1->y + w1->height) || w2->y + w2->height < w1->y)
+ continue;
+
+ // Check if there is room to push it down
+ if (w1->y + w1->height + 80 >= RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16))
+ continue;
+
+ // Invalidate the window's current area
+ window_invalidate(w2);
+
+ push_amount = w1->y + w1->height - w2->y + 3;
+ w2->y += push_amount;
+
+ // Invalidate the window's new area
+ window_invalidate(w2);
+
+ // Update viewport position if necessary
+ if (w2->viewport != NULL)
+ w2->viewport->y += push_amount;
+ }
+}
+
/**
*
* rct2: 0x006EE2E4
diff --git a/src/window.h b/src/window.h
index be7255d3ef..9bf736cd61 100644
--- a/src/window.h
+++ b/src/window.h
@@ -251,7 +251,7 @@ enum {
WC_TITLE_MENU = 29,
WC_TITLE_EXIT = 30,
WC_RECENT_NEWS = 31,
- WC_LEVEL_SELECT = 32,
+ WC_SCENARIO_SELECT = 32,
WC_TRACK_DESIGN_LIST = 33,
WC_NEW_CAMPAIGN = 35,
WC_KEYBOARD_SHORTCUT_LIST = 36,
@@ -281,6 +281,8 @@ int window_get_scroll_data_index(rct_window *w, int widget_index);
rct_window *window_bring_to_front_by_id(rct_windowclass cls, rct_windownumber number);
rct_window *window_bring_to_front(rct_window *w);
+void window_push_others_below(rct_window *w1);
+
rct_window *window_get_main();
void window_scroll_to_location(rct_window *w, int x, int y, int z);
@@ -289,4 +291,14 @@ void window_rotate_camera(rct_window *w);
void window_draw(rct_window *w, int left, int top, int right, int bottom);
void window_draw_widgets(rct_window *w, rct_drawpixelinfo *dpi);
+// Open window functions
+void window_main_open();
+void window_game_top_toolbar_open();
+void window_game_bottom_toolbar_open();
+void window_title_menu_open();
+void window_title_exit_open();
+void window_title_logo_open();
+void window_scenarioselect_open();
+void window_land_open();
+
#endif
\ No newline at end of file
diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c
index e13bd86e7f..7a6bda2b37 100644
--- a/src/window_game_top_toolbar.c
+++ b/src/window_game_top_toolbar.c
@@ -171,7 +171,7 @@ static void window_game_top_toolbar_mouseup()
RCT2_CALLPROC_EBPSAFE(0x006EE281);
} else {
show_gridlines();
- RCT2_CALLPROC_X(0x006EE212, 12, 0, 0, 0, w, 0, 0);
+ RCT2_CALLPROC_X(0x006EE212, 12, 0, 0, WIDX_CLEAR_SCENERY, w, 0, 0);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 2;
RCT2_CALLPROC_EBPSAFE(0x0068E0A7);
@@ -182,10 +182,10 @@ static void window_game_top_toolbar_mouseup()
RCT2_CALLPROC_EBPSAFE(0x006EE281);
} else {
show_gridlines();
- RCT2_CALLPROC_X(0x006EE212, 18, 0, 0, 0, w, 0, 0);
+ RCT2_CALLPROC_X(0x006EE212, 18, 0, 0, WIDX_LAND, w, 0, 0);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
- RCT2_CALLPROC_EBPSAFE(0x00663E7D);
+ window_land_open();
}
break;
case WIDX_WATER:
@@ -193,14 +193,14 @@ static void window_game_top_toolbar_mouseup()
RCT2_CALLPROC_EBPSAFE(0x006EE281);
} else {
show_gridlines();
- RCT2_CALLPROC_X(0x006EE212, 19, 0, 0, 0, w, 0, 0);
+ RCT2_CALLPROC_X(0x006EE212, 19, 0, 0, WIDX_WATER, w, 0, 0);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
RCT2_CALLPROC_EBPSAFE(0x006E6A40);
}
break;
case WIDX_SCENERY:
- RCT2_CALLPROC_X(0x006EE212, 0, 0, 0, 0, w, 0, 0);
+ RCT2_CALLPROC_X(0x006EE212, 0, 0, 0, WIDX_SCENERY, w, 0, 0);
RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6);
RCT2_CALLPROC_EBPSAFE(0x006E0FEF);
break;
diff --git a/src/window_land.c b/src/window_land.c
new file mode 100644
index 0000000000..e37433b2ea
--- /dev/null
+++ b/src/window_land.c
@@ -0,0 +1,98 @@
+/*****************************************************************************
+ * 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 "addresses.h"
+#include "map.h"
+#include "strings.h"
+#include "sprites.h"
+#include "widget.h"
+#include "window.h"
+
+static enum WINDOW_LAND_WIDGET_IDX {
+ WIDX_BACKGROUND,
+ WIDX_TITLE,
+ WIDX_CLOSE,
+ WIDX_PREVIEW,
+ WIDX_DECREMENT,
+ WIDX_INCREMENT,
+ WIDX_FLOOR,
+ WIDX_WALL,
+};
+
+static rct_widget window_land_widgets[] = {
+ { WWT_FRAME, 0, 0, 97, 0, 125, -1, STR_NONE }, // panel / background
+ { WWT_CAPTION, 0, 1, 96, 1, 14, STR_LAND, STR_WINDOW_TITLE_TIP }, // title bar
+ { WWT_CLOSEBOX, 0, 85, 95, 2, 13, 824, STR_CLOSE_WINDOW_TIP }, // close x button
+ { WWT_IMGBTN, 0, 27, 70, 17, 48, 5503, STR_NONE }, // preview box
+ { WWT_TRNBTN, 1, 28, 43, 18, 33, 0x20000000 | SPR_LAND_TOOL_DECREASE, STR_ADJUST_SMALLER_LAND_TIP }, // decrement size
+ { WWT_TRNBTN, 1, 54, 69, 32, 47, 0x20000000 | SPR_LAND_TOOL_INCREASE, STR_ADJUST_LARGER_LAND_TIP }, // increment size
+ { WWT_FLATBTN, 1, 2, 48, 75, 110, 0xFFFFFFFF, STR_CHANGE_BASE_LAND_TIP }, // floor texture
+ { WWT_FLATBTN, 1, 49, 95, 75, 110, 0xFFFFFFFF, STR_CHANGE_VERTICAL_LAND_TIP }, // wall texture
+ { WIDGETS_END },
+};
+
+static char window_land_floor_texture_order[] = {
+ TERRAIN_SAND_DARK, TERRAIN_SAND_LIGHT, TERRAIN_DIRT, TERRAIN_GRASS_CLUMPS, TERRAIN_GRASS,
+ TERRAIN_ROCK, TERRAIN_SAND, TERRAIN_MARTIAN, TERRAIN_CHECKERBOARD, TERRAIN_ICE,
+ TERRAIN_GRID_RED, TERRAIN_GRID_YELLOW, TERRAIN_GRID_BLUE, TERRAIN_GRID_GREEN
+};
+
+static char window_land_wall_texture_order[] = {
+ TERRAIN_EDGE_ROCK, TERRAIN_EDGE_WOOD_RED,
+ TERRAIN_EDGE_WOOD_BLACK, TERRAIN_EDGE_ICE,
+ 0, 0
+};
+
+int _selectedFloorTexture;
+int _selectedWallTexture;
+
+/**
+ *
+ * rct2: 0x00663E7D
+ */
+void window_land_open()
+{
+ rct_window* window;
+
+ // Check if window is already open
+ if (window_find_by_id(WC_LAND, 0) != NULL)
+ return;
+
+ window = window_create(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) - 98, 29, 98, 126, 0x0097B904, WC_LAND, 0);
+ window->widgets = window_land_widgets;
+ window->enabled_widgets =
+ (1 << WIDX_CLOSE) |
+ (1 << WIDX_DECREMENT) |
+ (1 << WIDX_INCREMENT) |
+ (1 << WIDX_FLOOR) |
+ (1 << WIDX_WALL);
+ window_init_scroll_widgets(window);
+ window_push_others_below(window);
+
+ RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE, uint8) = 255;
+ RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_TERRAIN_EDGE, uint8) = 255;
+ _selectedFloorTexture = 0;
+ _selectedWallTexture = 0;
+ RCT2_GLOBAL(0x009E2E1C, sint32) = 0x80000000;
+ RCT2_GLOBAL(0x009E2E20, sint32) = 0x80000000;
+ window->colours[0] = 24;
+ window->colours[1] = 24;
+ window->colours[2] = 24;
+}
\ No newline at end of file
diff --git a/src/window_title_menu.c b/src/window_title_menu.c
index f803dd305c..94c10042a0 100644
--- a/src/window_title_menu.c
+++ b/src/window_title_menu.c
@@ -27,8 +27,6 @@
#include "window.h"
#include "window_dropdown.h"
-void window_scenarioselect_open();
-
enum {
WIDX_START_NEW_GAME,
WIDX_CONTINUE_SAVED_GAME,
diff --git a/src/window_title_scenarioselect.c b/src/window_title_scenarioselect.c
index 9eb5d4fa90..a0fdc9620f 100644
--- a/src/window_title_scenarioselect.c
+++ b/src/window_title_scenarioselect.c
@@ -105,7 +105,7 @@ void window_scenarioselect_open()
{
rct_window* window;
- if (window_bring_to_front_by_id(WC_LEVEL_SELECT, 0) != NULL)
+ if (window_bring_to_front_by_id(WC_SCENARIO_SELECT, 0) != NULL)
return;
// Load scenario list
@@ -117,7 +117,7 @@ void window_scenarioselect_open()
610,
334,
window_scenarioselect_events,
- WC_LEVEL_SELECT,
+ WC_SCENARIO_SELECT,
0x400 | 0x02
);
window->widgets = window_scenarioselect_widgets;