diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index b480d80723..38e1118dbe 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -41,6 +41,7 @@
+
@@ -94,6 +95,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index 5f0581eca7..b1610b9290 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -174,6 +174,9 @@
Header Files
+
+ Header Files
+
@@ -425,6 +428,9 @@
Windows
+
+ Source Files
+
diff --git a/src/addresses.h b/src/addresses.h
index 00f77551f9..56dd5fa803 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -285,6 +285,9 @@
#define RCT2_ADDRESS_SECURITY_COLOUR 0x01357BCF
#define RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES 0x01357CF2
+#define RCT2_ADDRESS_RESEARH_PROGRESS_STAGE 0x01357CF3
+
+#define RCT2_ADDRESS_RESEARH_PROGRESS 0x013580E4
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY 0x013580E7
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH 0x013580E8
diff --git a/src/game.c b/src/game.c
index 8348b053cd..34d32ddfa2 100644
--- a/src/game.c
+++ b/src/game.c
@@ -31,6 +31,7 @@
#include "park.h"
#include "peep.h"
#include "rct2.h"
+#include "research.h"
#include "ride.h"
#include "sawyercoding.h"
#include "scenario.h"
@@ -494,7 +495,7 @@ void game_logic_update()
RCT2_CALLPROC_EBPSAFE(0x00672AA4); // update text effects
RCT2_CALLPROC_EBPSAFE(0x006ABE4C); // update rides
park_update();
- RCT2_CALLPROC_EBPSAFE(0x00684C7A); // update research
+ research_update();
RCT2_CALLPROC_EBPSAFE(0x006B5A2A); // update ride ratings
ride_measurements_update();
RCT2_CALLPROC_EBPSAFE(0x0068AFAD);
diff --git a/src/research.c b/src/research.c
new file mode 100644
index 0000000000..f927673fb2
--- /dev/null
+++ b/src/research.c
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * 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 "research.h"
+#include "rct2.h"
+#include "window.h"
+
+const int _researchRate[] = { 0, 160, 250, 400 };
+
+/**
+ *
+ * rct2: 0x00684C7A
+ */
+void research_update()
+{
+ int editorScreenFlags, researchLevel, currentResearchProgress;
+
+ editorScreenFlags = SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & editorScreenFlags)
+ return;
+
+ if (RCT2_GLOBAL(0x00F663AC, uint32) & 0x1F)
+ return;
+
+ researchLevel = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RESEARCH_LEVEL, uint8);
+
+ currentResearchProgress = RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16);
+ currentResearchProgress += _researchRate[researchLevel];
+ if (currentResearchProgress <= 0xFFFF) {
+ RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = currentResearchProgress;
+ } else {
+ switch (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8)) {
+ case RESEARCH_STAGE_INITIAL_RESEARCH:
+ RCT2_CALLPROC_EBPSAFE(0x00684BE5);
+ RCT2_CALLPROC_EBPSAFE(0x00684D2A);
+ break;
+ case RESEARCH_STAGE_DESIGNING:
+ RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = RESEARCH_STAGE_COMPLETING_DESIGN;
+ RCT2_CALLPROC_EBPSAFE(0x00684D2A);
+ window_invalidate_by_id(WC_CONSTRUCT_RIDE, 0);
+ window_invalidate_by_id(WC_RESEARCH, 0);
+ break;
+ case RESEARCH_STAGE_COMPLETING_DESIGN:
+ RCT2_CALLPROC_X(0x006848D4, RCT2_GLOBAL(0x013580E0, uint32), 0, 0, 0, 0, 0, 0);
+ RCT2_CALLPROC_EBPSAFE(0x006848D4);
+ RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) = 0;
+ RCT2_CALLPROC_EBPSAFE(0x00684D2A);
+ RCT2_CALLPROC_EBPSAFE(0x00684BAE);
+ window_invalidate_by_id(WC_CONSTRUCT_RIDE, 0);
+ window_invalidate_by_id(WC_RESEARCH, 0);
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/research.h b/src/research.h
new file mode 100644
index 0000000000..909e8d1088
--- /dev/null
+++ b/src/research.h
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * 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 .
+ *****************************************************************************/
+
+#ifndef _RESEARCH_H_
+#define _RESEARCH_H_
+
+enum {
+ RESEARCH_STAGE_INITIAL_RESEARCH,
+ RESEARCH_STAGE_DESIGNING,
+ RESEARCH_STAGE_COMPLETING_DESIGN,
+ RESEARCH_STAGE_UNKNOWN
+};
+
+void research_update();
+
+#endif
\ No newline at end of file
diff --git a/src/window_research.c b/src/window_research.c
index 5685c80da1..c599eb67a5 100644
--- a/src/window_research.c
+++ b/src/window_research.c
@@ -339,9 +339,9 @@ static void window_research_development_paint()
// Research type
stringId = STR_RESEARCH_UNKNOWN;
- if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) {
+ if (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) != 0) {
stringId = STR_TRANSPORT_RIDE + RCT2_GLOBAL(0x013580E6, uint8);
- if (RCT2_GLOBAL(0x01357CF3, uint8) != 1) {
+ if (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) != 1) {
uint32 typeId = RCT2_GLOBAL(0x013580E0, uint32);
if (typeId >= 0x10000) {
rct_ride_type *rideEntry = RCT2_GLOBAL(0x009ACFA4 + (typeId & 0xFF) * 4, rct_ride_type*);
@@ -357,13 +357,13 @@ static void window_research_development_paint()
y += 25;
// Progress
- stringId = 2285 + RCT2_GLOBAL(0x01357CF3, uint8);
+ stringId = 2285 + RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8);
gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_PROGRESS_LABEL, 0);
y += 15;
// Expected
RCT2_GLOBAL(0x013CE952, uint16) = STR_UNKNOWN;
- if (RCT2_GLOBAL(0x01357CF3, uint8) != 0) {
+ if (RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS_STAGE, uint8) != 0) {
uint16 expectedDay = RCT2_GLOBAL(RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY, uint8);
if (expectedDay != 255) {
RCT2_GLOBAL(0x013CE952 + 2, uint16) = STR_DATE_DAY_1 + expectedDay;