2016-06-04 00:06:22 +02:00
|
|
|
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
|
|
|
/*****************************************************************************
|
|
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
|
|
*
|
|
|
|
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
|
|
|
* For more information, visit https://github.com/OpenRCT2/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.
|
|
|
|
*
|
|
|
|
* A full copy of the GNU General Public License can be found in licence.txt
|
|
|
|
*****************************************************************************/
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#include "../interface/window.h"
|
|
|
|
#include "../world/climate.h"
|
|
|
|
#include "drawing.h"
|
2016-08-17 00:23:16 +02:00
|
|
|
#include "../config.h"
|
2016-06-04 00:06:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#include "IDrawingEngine.h"
|
|
|
|
#include "Rain.h"
|
2016-06-05 03:53:09 +02:00
|
|
|
#include "../core/Math.hpp"
|
2016-06-04 00:06:22 +02:00
|
|
|
|
|
|
|
typedef void (* DrawRainFunc)(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height);
|
|
|
|
|
|
|
|
static void DrawLightRain(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height);
|
|
|
|
static void DrawHeavyRain(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height);
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x009AC058
|
|
|
|
*/
|
|
|
|
const DrawRainFunc DrawRainFunctions[] =
|
|
|
|
{
|
|
|
|
nullptr,
|
|
|
|
&DrawLightRain,
|
|
|
|
&DrawHeavyRain
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684383
|
|
|
|
*/
|
|
|
|
static void CallDrawRainFunc(IRainDrawer * rainDrawer,
|
|
|
|
rct_window * w,
|
|
|
|
sint16 left,
|
|
|
|
sint16 right,
|
|
|
|
sint16 top,
|
|
|
|
sint16 bottom,
|
|
|
|
uint32 rainType)
|
|
|
|
{
|
|
|
|
rct_viewport * vp = w->viewport;
|
|
|
|
if (vp == nullptr)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-06-05 03:53:09 +02:00
|
|
|
left = Math::Max(left, vp->x);
|
|
|
|
right = Math::Min(right, vp->width);
|
|
|
|
top = Math::Max(top, vp->y);
|
|
|
|
bottom = Math::Min(bottom, vp->height);
|
2016-06-04 00:06:22 +02:00
|
|
|
if (left >= right || top >= bottom)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint32 width = right - left;
|
|
|
|
sint32 height = bottom - top;
|
|
|
|
DrawRainFunctions[rainType](rainDrawer, left, top, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006842AF
|
|
|
|
* From 0x00684383 on: split into call_draw_rain_func
|
|
|
|
*/
|
|
|
|
static void DrawRainWindow(IRainDrawer * rainDrawer,
|
|
|
|
rct_window * original_w,
|
|
|
|
sint16 left,
|
|
|
|
sint16 right,
|
|
|
|
sint16 top,
|
|
|
|
sint16 bottom,
|
|
|
|
uint32 rainType)
|
|
|
|
{
|
2016-08-17 00:23:16 +02:00
|
|
|
if (!gConfigGeneral.render_weather_effects)
|
|
|
|
return;
|
|
|
|
|
2016-06-04 00:06:22 +02:00
|
|
|
rct_window * newWindow = gWindowNextSlot;
|
|
|
|
rct_window * w = original_w + 1; // Start from second window
|
|
|
|
for (; ; w++)
|
|
|
|
{
|
|
|
|
if (w >= newWindow)
|
|
|
|
{
|
|
|
|
// Loop ended, draw rain for original_w
|
|
|
|
CallDrawRainFunc(rainDrawer, original_w, left, right, top, bottom, rainType);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, w->x, top, bottom, rainType);
|
|
|
|
|
|
|
|
left = w->x;
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint16 w_right = RCT_WINDOW_RIGHT(w);
|
|
|
|
if (right > w_right) {
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, w_right, top, bottom, rainType);
|
|
|
|
|
|
|
|
left = w_right;
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (top < w->y) {
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, right, top, w->y, rainType);
|
|
|
|
|
|
|
|
top = w->y;
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint16 w_bottom = RCT_WINDOW_BOTTOM(w);
|
|
|
|
if (bottom > w_bottom)
|
|
|
|
{
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, right, top, w_bottom, rainType);
|
|
|
|
|
|
|
|
top = w_bottom;
|
|
|
|
DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684266
|
|
|
|
*/
|
2016-06-05 16:11:12 +02:00
|
|
|
static void DrawRainAnimation(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer, uint32 rainType)
|
2016-06-04 00:06:22 +02:00
|
|
|
{
|
2016-06-05 16:11:12 +02:00
|
|
|
sint32 left = dpi->x;
|
|
|
|
sint32 right = left + dpi->width;
|
|
|
|
sint32 top = dpi->y;
|
|
|
|
sint32 bottom = top + dpi->height;
|
2016-06-04 00:06:22 +02:00
|
|
|
|
|
|
|
rct_window * newWindow = gWindowNextSlot;
|
|
|
|
for (rct_window * w = g_window_list; w < newWindow; w++)
|
|
|
|
{
|
|
|
|
DrawRainWindow(rainDrawer, w, left, right, top, bottom, rainType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684218
|
|
|
|
*/
|
2016-06-05 16:11:12 +02:00
|
|
|
void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer)
|
2016-06-04 00:06:22 +02:00
|
|
|
{
|
|
|
|
// Get rain draw function and draw rain
|
|
|
|
uint32 rainType = gClimateCurrentRainLevel;
|
2016-09-10 19:03:25 +02:00
|
|
|
if (rainType > 0 && !gTrackDesignSaveMode)
|
2016-06-04 00:06:22 +02:00
|
|
|
{
|
2016-06-05 16:11:12 +02:00
|
|
|
DrawRainAnimation(dpi, rainDrawer, rainType);
|
2016-06-04 00:06:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x00684114
|
|
|
|
*/
|
|
|
|
static void DrawLightRain(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height)
|
|
|
|
{
|
|
|
|
int x_start = -(int)gScenarioTicks + 8;
|
|
|
|
int y_start = (gScenarioTicks * 3) + 7;
|
|
|
|
y_start = -y_start;
|
|
|
|
x_start += left;
|
|
|
|
y_start += top;
|
|
|
|
rainDrawer->Draw(left, top, width, height, x_start, y_start);
|
|
|
|
|
|
|
|
x_start = -(int)gScenarioTicks + 0x18;
|
|
|
|
y_start = (gScenarioTicks * 4) + 0x0D;
|
|
|
|
y_start = -y_start;
|
|
|
|
x_start += left;
|
|
|
|
y_start += top;
|
|
|
|
rainDrawer->Draw(left, top, width, height, x_start, y_start);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0068416D
|
|
|
|
*/
|
|
|
|
static void DrawHeavyRain(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height)
|
|
|
|
{
|
|
|
|
int x_start = -(int)gScenarioTicks;
|
|
|
|
int y_start = gScenarioTicks * 5;
|
|
|
|
y_start = -y_start;
|
|
|
|
x_start += left;
|
|
|
|
y_start += top;
|
|
|
|
rainDrawer->Draw(left, top, width, height, x_start, y_start);
|
|
|
|
|
|
|
|
x_start = -(int)gScenarioTicks + 0x10;
|
|
|
|
y_start = (gScenarioTicks * 6) + 5;
|
|
|
|
y_start = -y_start;
|
|
|
|
x_start += left;
|
|
|
|
y_start += top;
|
|
|
|
rainDrawer->Draw(left, top, width, height, x_start, y_start);
|
|
|
|
|
|
|
|
x_start = -(int)gScenarioTicks + 8;
|
|
|
|
y_start = (gScenarioTicks * 3) + 7;
|
|
|
|
y_start = -y_start;
|
|
|
|
x_start += left;
|
|
|
|
y_start += top;
|
|
|
|
rainDrawer->Draw(left, top, width, height, x_start, y_start);
|
|
|
|
|
|
|
|
x_start = -(int)gScenarioTicks + 0x18;
|
|
|
|
y_start = (gScenarioTicks * 4) + 0x0D;
|
|
|
|
y_start = -y_start;
|
|
|
|
x_start += left;
|
|
|
|
y_start += top;
|
|
|
|
rainDrawer->Draw(left, top, width, height, x_start, y_start);
|
|
|
|
}
|