OpenRCT2/src/openrct2/drawing/Rain.cpp

241 lines
6.6 KiB
C++
Raw Normal View History

#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"
#include "../config.h"
}
#include "IDrawingEngine.h"
#include "Rain.h"
2016-06-05 03:53:09 +02:00
#include "../core/Math.hpp"
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);
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)
{
if (!gConfigGeneral.render_weather_effects)
return;
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
*/
static void DrawRainAnimation(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer, uint32 rainType)
{
sint32 left = dpi->x;
sint32 right = left + dpi->width;
sint32 top = dpi->y;
sint32 bottom = top + dpi->height;
rct_window * newWindow = gWindowNextSlot;
for (rct_window * w = g_window_list; w < newWindow; w++)
{
DrawRainWindow(rainDrawer, w, left, right, top, bottom, rainType);
}
}
/**
*
* rct2: 0x00684218
*/
void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer)
{
// Get rain draw function and draw rain
uint32 rainType = gClimateCurrentRainLevel;
2016-09-10 19:03:25 +02:00
if (rainType > 0 && !gTrackDesignSaveMode)
{
DrawRainAnimation(dpi, rainDrawer, rainType);
}
}
/**
*
* 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);
}