diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 1f0a9b9fb0..5d856b42d7 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -45,6 +45,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index 1e47f241f4..e1b4435a08 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -356,7 +356,6 @@
Source\Management
-
Source\Windows
@@ -369,10 +368,6 @@
-
- Libraries\libspeex
-
-
Source\Windows
@@ -381,9 +376,6 @@
-
- Libraries\lodepng
-
Libraries\libspeex
@@ -400,6 +392,29 @@
Libraries\libspeex
+
+ Source\Drawing
+
+
+
+
+ Libraries\lodepng
+
+
+
+ Libraries\libspeex
+
+
+
+
+
+ Libraries\libspeex
+
+
+
+ Libraries\lodepng
+
+
diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h
index a240d5429f..a9dabe0648 100644
--- a/src/drawing/drawing.h
+++ b/src/drawing/drawing.h
@@ -112,4 +112,7 @@ void draw_string_centred_raw(rct_drawpixelinfo *dpi, int x, int y, int numLines,
void gfx_draw_string_right(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
void draw_string_right_underline(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
+// rain
+void update_rain_animation();
+
#endif
diff --git a/src/drawing/rain.c b/src/drawing/rain.c
new file mode 100644
index 0000000000..b1660e5fb6
--- /dev/null
+++ b/src/drawing/rain.c
@@ -0,0 +1,239 @@
+/*****************************************************************************
+ * Copyright (c) 2014
+ * 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 "../interface/window.h"
+#include "drawing.h"
+
+typedef void(*draw_rain_func)(int left, int top, int width, int height);
+
+static void draw_light_rain(int left, int top, int width, int height);
+static void draw_heavy_rain(int left, int top, int width, int height);
+
+/**
+ *
+ * rct2: 0x009AC058
+ */
+const draw_rain_func draw_rain_function[] = {
+ NULL,
+ &draw_light_rain,
+ &draw_heavy_rain
+};
+
+/**
+ *
+ * rct2: 0x00684383
+ */
+static void call_draw_rain_func(rct_window* w, short left, short right, short top, short bottom, uint32 draw_rain_func)
+{
+ rct_viewport* vp = w->viewport;
+ if (vp == NULL) {
+ return;
+ }
+
+ left = max(left, vp->x);
+ right = min(right, vp->width);
+
+ top = max(top, vp->y);
+ bottom = min(bottom, vp->height);
+
+ if (left >= right || top >= bottom) {
+ return;
+ }
+
+ int width = right - left;
+ int height = bottom - top;
+
+ draw_rain_function[draw_rain_func](left, top, width, height);
+}
+
+/**
+ *
+ * rct2: 0x006842AF
+ * From 0x00684383 on: split into call_draw_rain_func
+ */
+static void draw_rain_window(rct_window* original_w, short left, short right, short top, short bottom, uint32 draw_rain_func)
+{
+ rct_window* newWindow = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*);
+
+ rct_window* w = original_w + 1; // Start from second window
+ for (; ; w++) {
+ if (w >= newWindow) {
+ // Loop ended, draw rain for original_w
+ call_draw_rain_func(original_w, left, right, top, bottom, draw_rain_func);
+ return;
+ }
+
+ if (right <= w->x || bottom <= w->y) {
+ continue;
+ }
+
+ if (RCT_WINDOW_RIGHT(w) <= left || RCT_WINDOW_BOTTOM(w) <= top) {
+ continue;
+ }
+
+ if (left >= w->x) {
+ break;
+ }
+
+ draw_rain_window(original_w, left, w->x, top, bottom, draw_rain_func);
+
+ left = w->x;
+ draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
+ return;
+ }
+
+ sint16 w_right = RCT_WINDOW_RIGHT(w);
+ if (right > w_right) {
+ draw_rain_window(original_w, left, w_right, top, bottom, draw_rain_func);
+
+ left = w_right;
+ draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
+ return;
+ }
+
+ if (top < w->y) {
+ draw_rain_window(original_w, left, right, top, w->y, draw_rain_func);
+
+ top = w->y;
+ draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
+ return;
+ }
+
+ sint16 w_bottom = RCT_WINDOW_BOTTOM(w);
+ if (bottom > w_bottom) {
+ draw_rain_window(original_w, left, right, top, w_bottom, draw_rain_func);
+
+ top = w_bottom;
+ draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
+ return;
+ }
+}
+
+/**
+ *
+ * rct2: 0x00684266
+ */
+static void draw_rain_animation(uint32 draw_rain_func)
+{
+ rct_drawpixelinfo *screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
+ short left = screenDPI->x;
+ short right = left + screenDPI->width;
+ short top = screenDPI->y;
+ short bottom = top + screenDPI->height;
+
+ rct_window* newWindow = (RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*));
+
+ for (rct_window* w = g_window_list; w < newWindow; w++) {
+ draw_rain_window(w, left, right, top, bottom, draw_rain_func);
+ }
+}
+
+/**
+ *
+ * rct2: 0x00684218
+ */
+void update_rain_animation()
+{
+ if (RCT2_GLOBAL(0x009ABDF2, uint8) == 0)
+ return;
+
+ // Draw picked-up peep
+ if (RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) != 0xFFFFFFFF) {
+ gfx_draw_sprite(
+ (rct_drawpixelinfo*)RCT2_ADDRESS_SCREEN_DPI,
+ RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32),
+ RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16),
+ RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16), 0
+ );
+ }
+
+ // Get rain draw function and draw rain
+ uint32 draw_rain_func = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8);
+ if (draw_rain_func > 0 && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1))
+ draw_rain_animation(draw_rain_func);
+}
+
+/**
+ *
+ * rct2: 0x00684114
+ */
+static void draw_light_rain(int left, int top, int width, int height)
+{
+ int x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 8;
+ int y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 3) + 7;
+ y_start = -y_start;
+
+ x_start += left;
+ y_start += top;
+
+ gfx_draw_rain(left, top, width, height, x_start, y_start);
+
+ x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 0x18;
+ y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 4) + 0x0D;
+ y_start = -y_start;
+
+ x_start += left;
+ y_start += top;
+ gfx_draw_rain(left, top, width, height, x_start, y_start);
+}
+
+/**
+ *
+ * rct2: 0x0068416D
+ */
+static void draw_heavy_rain(int left, int top, int width, int height)
+{
+ int x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int);
+ int y_start = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 5;
+ y_start = -y_start;
+
+ x_start += left;
+ y_start += top;
+
+ gfx_draw_rain(left, top, width, height, x_start, y_start);
+
+ x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 0x10;
+ y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 6) + 5;
+ y_start = -y_start;
+
+ x_start += left;
+ y_start += top;
+
+ gfx_draw_rain(left, top, width, height, x_start, y_start);
+
+ x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 8;
+ y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 3) + 7;
+ y_start = -y_start;
+
+ x_start += left;
+ y_start += top;
+
+ gfx_draw_rain(left, top, width, height, x_start, y_start);
+
+ x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 0x18;
+ y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 4) + 0x0D;
+ y_start = -y_start;
+
+ x_start += left;
+ y_start += top;
+
+ gfx_draw_rain(left, top, width, height, x_start, y_start);
+}
\ No newline at end of file
diff --git a/src/game.c b/src/game.c
index 77d6cbd236..a17383258b 100644
--- a/src/game.c
+++ b/src/game.c
@@ -49,83 +49,6 @@
int gGameSpeed = 1;
-typedef void(*draw_rain_func)(int left, int top, int width, int height);
-
-/**
-*
-* rct2: 0x00684114
-*/
-void draw_light_rain(int left, int top, int width, int height){
- int x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 8;
- int y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 3) + 7;
- y_start = -y_start;
-
- x_start += left;
- y_start += top;
-
- gfx_draw_rain(left, top, width, height, x_start, y_start);
-
- x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 0x18;
- y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 4) + 0x0D;
- y_start = -y_start;
-
- x_start += left;
- y_start += top;
- gfx_draw_rain(left, top, width, height, x_start, y_start);
-}
-
-/**
-*
-* rct2: 0x0068416D
-*/
-void draw_heavy_rain(int left, int top, int width, int height){
- int x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int);
- int y_start = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 5;
- y_start = -y_start;
-
- x_start += left;
- y_start += top;
-
- gfx_draw_rain(left, top, width, height, x_start, y_start);
-
- x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 0x10;
- y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 6) + 5;
- y_start = -y_start;
-
- x_start += left;
- y_start += top;
-
- gfx_draw_rain(left, top, width, height, x_start, y_start);
-
- x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 8;
- y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 3) + 7;
- y_start = -y_start;
-
- x_start += left;
- y_start += top;
-
- gfx_draw_rain(left, top, width, height, x_start, y_start);
-
- x_start = -RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) + 0x18;
- y_start = (RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) * 4) + 0x0D;
- y_start = -y_start;
-
- x_start += left;
- y_start += top;
-
- gfx_draw_rain(left, top, width, height, x_start, y_start);
-}
-
-/**
-*
-* rct2: 0x009AC058
-*/
-const draw_rain_func draw_rain_function[] = {
- NULL,
- &draw_light_rain, // Light rain
- &draw_heavy_rain // Heavy rain
-};
-
/**
*
* rct2: 0x0066B5C0 (part of 0x0066B3E8)
@@ -261,139 +184,7 @@ void update_palette_effects()
}
}
-/**
-*
-* rct2: 0x00684383
-*/
-void call_draw_rain_func(rct_window* w, short left, short right, short top, short bottom, uint32 draw_rain_func)
-{
- rct_viewport* vp = w->viewport;
- if (vp == NULL) {
- return;
- }
- left = max(left, vp->x);
- right = min(right, vp->width);
-
- top = max(top, vp->y);
- bottom = min(bottom, vp->height);
-
- if (left >= right || top >= bottom) {
- return;
- }
-
- int width = right - left;
- int height = bottom - top;
-
- draw_rain_function[draw_rain_func](left, top, width, height);
-}
-
-/**
-*
-* rct2: 0x006842AF
-* From 0x00684383 on: split into call_draw_rain_func
-*/
-void draw_rain_window(rct_window* original_w, short left, short right, short top, short bottom, uint32 draw_rain_func)
-{
- rct_window* newWindow = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*);
-
- rct_window* w = original_w + 1; // Start from second window
- for (; ; w++) {
- if (w >= newWindow) {
- // Loop ended, draw rain for original_w
- call_draw_rain_func(original_w, left, right, top, bottom, draw_rain_func);
- return;
- }
-
- if (right <= w->x || bottom <= w->y) {
- continue;
- }
-
- if (RCT_WINDOW_RIGHT(w) <= left || RCT_WINDOW_BOTTOM(w) <= top) {
- continue;
- }
-
- if (left >= w->x) {
- break;
- }
-
- draw_rain_window(original_w, left, w->x, top, bottom, draw_rain_func);
-
- left = w->x;
- draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
- return;
- }
-
- sint16 w_right = RCT_WINDOW_RIGHT(w);
- if (right > w_right) {
- draw_rain_window(original_w, left, w_right, top, bottom, draw_rain_func);
-
- left = w_right;
- draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
- return;
- }
-
- if (top < w->y) {
- draw_rain_window(original_w, left, right, top, w->y, draw_rain_func);
-
- top = w->y;
- draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
- return;
- }
-
- sint16 w_bottom = RCT_WINDOW_BOTTOM(w);
- if (bottom > w_bottom) {
- draw_rain_window(original_w, left, right, top, w_bottom, draw_rain_func);
-
- top = w_bottom;
- draw_rain_window(original_w, left, right, top, bottom, draw_rain_func);
- return;
- }
-}
-
-/**
-*
-* rct2: 0x00684266
-*/
-void draw_rain_animation(uint32 draw_rain_func)
-{
- rct_drawpixelinfo *screenDPI = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo);
- short left = screenDPI->x;
- short right = left + screenDPI->width;
- short top = screenDPI->y;
- short bottom = top + screenDPI->height;
-
- rct_window* newWindow = (RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*));
-
- for (rct_window* w = g_window_list; w < newWindow; w++) {
- draw_rain_window(w, left, right, top, bottom, draw_rain_func);
- }
-}
-
-/**
- *
- * rct2: 0x00684218
- */
-void update_rain_animation()
-{
- if (RCT2_GLOBAL(0x009ABDF2, uint8) == 0)
- return;
-
- // Draw picked-up peep
- if (RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) != 0xFFFFFFFF) {
- gfx_draw_sprite(
- (rct_drawpixelinfo*)RCT2_ADDRESS_SCREEN_DPI,
- RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32),
- RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16),
- RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16), 0
- );
- }
-
- // Get rain draw function and draw rain
- uint32 draw_rain_func = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8);
- if (draw_rain_func > 0 && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1))
- draw_rain_animation(draw_rain_func);
-}
void game_update()
{
diff --git a/src/game.h b/src/game.h
index 8d660f86e9..e45c4e5c8a 100644
--- a/src/game.h
+++ b/src/game.h
@@ -90,7 +90,6 @@ void game_create_windows();
void game_update();
void game_logic_update();
void sub_0x0069E9A7();
-void update_rain_animation();
void update_palette_effects();
int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp);