mirror of https://github.com/OpenRCT2/OpenRCT2.git
draw rain via new IRainDrawer interface
This commit is contained in:
parent
d4edf58a51
commit
3e6eb48d4c
|
@ -46,7 +46,7 @@
|
|||
<ClCompile Include="src\drawing\font.c" />
|
||||
<ClCompile Include="src\drawing\line.c" />
|
||||
<ClCompile Include="src\drawing\NewDrawing.cpp" />
|
||||
<ClCompile Include="src\drawing\rain.c" />
|
||||
<ClCompile Include="src\drawing\Rain.cpp" />
|
||||
<ClCompile Include="src\drawing\rect.c" />
|
||||
<ClCompile Include="src\drawing\scrolling_text.c" />
|
||||
<ClCompile Include="src\drawing\sprite.c" />
|
||||
|
@ -339,6 +339,7 @@
|
|||
<ClInclude Include="src\drawing\IDrawingContext.h" />
|
||||
<ClInclude Include="src\drawing\IDrawingEngine.h" />
|
||||
<ClInclude Include="src\drawing\NewDrawing.h" />
|
||||
<ClInclude Include="src\drawing\Rain.h" />
|
||||
<ClInclude Include="src\editor.h" />
|
||||
<ClInclude Include="src\game.h" />
|
||||
<ClInclude Include="src\hook.h" />
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <SDL_video.h>
|
||||
|
||||
struct rct_drawpixelinfo;
|
||||
|
||||
interface IDrawingEngine
|
||||
{
|
||||
virtual ~IDrawingEngine() { }
|
||||
|
@ -36,3 +38,14 @@ namespace DrawingEngineFactory
|
|||
{
|
||||
IDrawingEngine * CreateSoftware();
|
||||
};
|
||||
|
||||
interface IRainDrawer
|
||||
{
|
||||
virtual ~IRainDrawer() { }
|
||||
virtual void Draw(sint32 x,
|
||||
sint32 y,
|
||||
sint32 width,
|
||||
sint32 height,
|
||||
sint32 xStart,
|
||||
sint32 yStart) abstract;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#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
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
interface IRainDrawer;
|
||||
|
||||
void DrawRain(IRainDrawer * rainDrawer);
|
|
@ -39,15 +39,6 @@ uint8 _screenDirtyBlockShiftY;
|
|||
rct_drawpixelinfo gScreenDPI;
|
||||
rct_drawpixelinfo gWindowDPI;
|
||||
|
||||
typedef struct rain_pixel {
|
||||
uint32 position;
|
||||
uint8 colour;
|
||||
} rain_pixel;
|
||||
|
||||
#define MAX_RAIN_PIXELS 0xFFFE
|
||||
static rain_pixel _rainPixels[MAX_RAIN_PIXELS];
|
||||
static uint32 _numRainPixels;
|
||||
|
||||
uint8 gGamePalette[256 * 4];
|
||||
uint32 gPaletteEffectFrame;
|
||||
|
||||
|
@ -295,91 +286,6 @@ bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, int x, i
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00684027
|
||||
* ebp used to be a parameter but it is always zero
|
||||
* left : eax
|
||||
* top : ebx
|
||||
* width : ecx
|
||||
* height : edx
|
||||
* x_start: edi
|
||||
* y_start: esi
|
||||
*/
|
||||
void gfx_draw_rain(int left, int top, int width, int height, sint32 x_start, sint32 y_start)
|
||||
{
|
||||
static const uint8 RainPattern[] = {
|
||||
32, 32, 0, 12, 0, 14, 0, 16, -1, 0, -1, 0, -1, 0, -1, 0, -1,
|
||||
0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0,
|
||||
-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1,
|
||||
0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 0
|
||||
};
|
||||
|
||||
const uint8 *pattern = RainPattern;
|
||||
uint8 pattern_x_space = *pattern++;
|
||||
uint8 pattern_y_space = *pattern++;
|
||||
|
||||
uint8 pattern_start_x_offset = x_start % pattern_x_space;
|
||||
uint8 pattern_start_y_offset = y_start % pattern_y_space;
|
||||
|
||||
rct_drawpixelinfo *dpi = &gScreenDPI;
|
||||
uint32 pixel_offset = (dpi->pitch + dpi->width) * top + left;
|
||||
uint8 pattern_y_pos = pattern_start_y_offset % pattern_y_space;
|
||||
|
||||
//Stores the colours of changed pixels
|
||||
rain_pixel *pixel_store = &_rainPixels[_numRainPixels];
|
||||
for (; height != 0; height--) {
|
||||
uint8 pattern_x = pattern[pattern_y_pos * 2];
|
||||
if (pattern_x != 0xFF) {
|
||||
if (_numRainPixels < (MAX_RAIN_PIXELS - (uint32)width)) {
|
||||
int final_pixel_offset = width + pixel_offset;
|
||||
|
||||
int x_pixel_offset = pixel_offset;
|
||||
x_pixel_offset += ((uint8)(pattern_x - pattern_start_x_offset)) % pattern_x_space;
|
||||
|
||||
uint8 pattern_pixel = pattern[pattern_y_pos * 2 + 1];
|
||||
for (; x_pixel_offset < final_pixel_offset; x_pixel_offset += pattern_x_space){
|
||||
uint8 current_pixel = dpi->bits[x_pixel_offset];
|
||||
dpi->bits[x_pixel_offset] = pattern_pixel;
|
||||
_numRainPixels++;
|
||||
|
||||
// Store colour and position
|
||||
*pixel_store++ = (rain_pixel){ x_pixel_offset, current_pixel };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pixel_offset += dpi->pitch + dpi->width;
|
||||
pattern_y_pos++;
|
||||
pattern_y_pos %= pattern_y_space;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006843DC
|
||||
*/
|
||||
void redraw_rain()
|
||||
{
|
||||
if (_numRainPixels > 0) {
|
||||
rct_window *window = window_get_main();
|
||||
uint32 numPixels = window->width * window->height;
|
||||
|
||||
uint8 *screenPixels = gScreenDPI.bits;
|
||||
for (uint32 i = 0; i < _numRainPixels; i++) {
|
||||
rain_pixel rainPixel = _rainPixels[i];
|
||||
|
||||
// HACK
|
||||
if (rainPixel.position > numPixels) {
|
||||
log_verbose("Pixel error, skipping rain draw in this frame");
|
||||
break;
|
||||
}
|
||||
screenPixels[rainPixel.position] = rainPixel.colour;
|
||||
}
|
||||
_numRainPixels = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_invalidate_pickedup_peep()
|
||||
{
|
||||
uint32 sprite = gPickupPeepImage;
|
||||
|
|
|
@ -181,10 +181,6 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, int availab
|
|||
bool ttf_initialise();
|
||||
void ttf_dispose();
|
||||
|
||||
// rain
|
||||
void update_rain_animation();
|
||||
void redraw_rain();
|
||||
|
||||
// scrolling text
|
||||
void scrolling_text_initialise_bitmaps();
|
||||
int scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../../core/Math.hpp"
|
||||
#include "../../core/Memory.hpp"
|
||||
#include "../IDrawingEngine.h"
|
||||
#include "../Rain.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -36,6 +37,117 @@ struct DirtyGrid
|
|||
uint8 * Blocks;
|
||||
};
|
||||
|
||||
class RainDrawer : public IRainDrawer
|
||||
{
|
||||
private:
|
||||
struct RainPixel
|
||||
{
|
||||
uint32 Position;
|
||||
uint8 Colour;
|
||||
};
|
||||
|
||||
static constexpr uint32 MaxRainPixels = 0xFFFE;
|
||||
|
||||
size_t _rainPixelsCapacity;
|
||||
uint32 _rainPixelsCount;
|
||||
RainPixel * _rainPixels;
|
||||
rct_drawpixelinfo * _screenDPI;
|
||||
|
||||
public:
|
||||
RainDrawer()
|
||||
{
|
||||
_rainPixelsCapacity = MaxRainPixels;
|
||||
_rainPixelsCount = 0;
|
||||
_rainPixels = new RainPixel[_rainPixelsCapacity];
|
||||
}
|
||||
|
||||
~RainDrawer()
|
||||
{
|
||||
delete _rainPixels;
|
||||
}
|
||||
|
||||
void SetDPI(rct_drawpixelinfo * dpi)
|
||||
{
|
||||
_screenDPI = dpi;
|
||||
}
|
||||
|
||||
void Draw(sint32 x, sint32 y, sint32 width, sint32 height, sint32 xStart, sint32 yStart)
|
||||
{
|
||||
static const uint8 RainPattern[] =
|
||||
{
|
||||
32, 32, 0, 12, 0, 14, 0, 16, 255, 0, 255, 0, 255, 0, 255, 0, 255,
|
||||
0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
|
||||
255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
|
||||
0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0
|
||||
};
|
||||
|
||||
const uint8 * pattern = RainPattern;
|
||||
uint8 patternXSpace = *pattern++;
|
||||
uint8 patternYSpace = *pattern++;
|
||||
|
||||
uint8 patternStartXOffset = xStart % patternXSpace;
|
||||
uint8 patternStartYOffset = yStart % patternYSpace;
|
||||
|
||||
uint32 pixelOffset = (_screenDPI->pitch + _screenDPI->width) * y + x;
|
||||
uint8 patternYPos = patternStartYOffset % patternYSpace;
|
||||
|
||||
uint8 * screenBits = _screenDPI->bits;
|
||||
|
||||
//Stores the colours of changed pixels
|
||||
RainPixel * newPixels = &_rainPixels[_rainPixelsCount];
|
||||
for (; height != 0; height--)
|
||||
{
|
||||
uint8 patternX = pattern[patternYPos * 2];
|
||||
if (patternX != 0xFF)
|
||||
{
|
||||
if (_rainPixelsCount < (_rainPixelsCapacity - (uint32)width))
|
||||
{
|
||||
uint32 finalPixelOffset = width + pixelOffset;
|
||||
|
||||
uint32 xPixelOffset = pixelOffset;
|
||||
xPixelOffset += ((uint8)(patternX - patternStartXOffset)) % patternXSpace;
|
||||
|
||||
uint8 patternPixel = pattern[patternYPos * 2 + 1];
|
||||
for (; xPixelOffset < finalPixelOffset; xPixelOffset += patternXSpace)
|
||||
{
|
||||
uint8 current_pixel = screenBits[xPixelOffset];
|
||||
screenBits[xPixelOffset] = patternPixel;
|
||||
_rainPixelsCount++;
|
||||
|
||||
// Store colour and position
|
||||
*newPixels++ = { xPixelOffset, current_pixel };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pixelOffset += _screenDPI->pitch + _screenDPI->width;
|
||||
patternYPos++;
|
||||
patternYPos %= patternYSpace;
|
||||
}
|
||||
}
|
||||
|
||||
void Restore()
|
||||
{
|
||||
if (_rainPixelsCount > 0)
|
||||
{
|
||||
uint32 numPixels = (_screenDPI->width + _screenDPI->pitch) * _screenDPI->height;
|
||||
uint8 * bits = _screenDPI->bits;
|
||||
for (uint32 i = 0; i < _rainPixelsCount; i++)
|
||||
{
|
||||
RainPixel rainPixel = _rainPixels[i];
|
||||
if (rainPixel.Position >= numPixels)
|
||||
{
|
||||
// Pixel out of bounds, bail
|
||||
break;
|
||||
}
|
||||
|
||||
bits[rainPixel.Position] = rainPixel.Colour;
|
||||
}
|
||||
_rainPixelsCount = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SoftwareDrawingEngine : public IDrawingEngine
|
||||
{
|
||||
private:
|
||||
|
@ -54,6 +166,8 @@ private:
|
|||
|
||||
rct_drawpixelinfo _bitsDPI = { 0 };
|
||||
|
||||
RainDrawer _rainDrawer;
|
||||
|
||||
public:
|
||||
SoftwareDrawingEngine()
|
||||
{
|
||||
|
@ -150,13 +264,19 @@ public:
|
|||
|
||||
void Draw() override
|
||||
{
|
||||
redraw_rain();
|
||||
_rainDrawer.SetDPI(&_bitsDPI);
|
||||
_rainDrawer.Restore();
|
||||
|
||||
gfx_invalidate_pickedup_peep();
|
||||
gfx_draw_pickedup_peep();
|
||||
|
||||
DrawAllDirtyBlocks();
|
||||
window_update_all_viewports();
|
||||
DrawAllDirtyBlocks();
|
||||
window_update_all();
|
||||
|
||||
DrawRain(&_rainDrawer);
|
||||
|
||||
rct2_draw();
|
||||
Display();
|
||||
}
|
||||
|
|
|
@ -1,223 +0,0 @@
|
|||
#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
|
||||
|
||||
#include "../addresses.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../world/climate.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 = gWindowNextSlot;
|
||||
|
||||
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 = &gScreenDPI;
|
||||
short left = screenDPI->x;
|
||||
short right = left + screenDPI->width;
|
||||
short top = screenDPI->y;
|
||||
short bottom = top + screenDPI->height;
|
||||
|
||||
rct_window* newWindow = gWindowNextSlot;
|
||||
|
||||
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()
|
||||
{
|
||||
// Get rain draw function and draw rain
|
||||
uint32 draw_rain_func = gClimateCurrentRainLevel;
|
||||
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 = -(int)gScenarioTicks + 8;
|
||||
int y_start = (gScenarioTicks * 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 = -(int)gScenarioTicks + 0x18;
|
||||
y_start = (gScenarioTicks * 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 = -(int)gScenarioTicks;
|
||||
int y_start = gScenarioTicks * 5;
|
||||
y_start = -y_start;
|
||||
|
||||
x_start += left;
|
||||
y_start += top;
|
||||
|
||||
gfx_draw_rain(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;
|
||||
|
||||
gfx_draw_rain(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;
|
||||
|
||||
gfx_draw_rain(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;
|
||||
|
||||
gfx_draw_rain(left, top, width, height, x_start, y_start);
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
#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 "../addresses.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../world/climate.h"
|
||||
#include "drawing.h"
|
||||
}
|
||||
|
||||
#include "IDrawingEngine.h"
|
||||
#include "Rain.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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(IRainDrawer * rainDrawer, uint32 rainType)
|
||||
{
|
||||
rct_drawpixelinfo * screenDPI = &gScreenDPI;
|
||||
sint32 left = screenDPI->x;
|
||||
sint32 right = left + screenDPI->width;
|
||||
sint32 top = screenDPI->y;
|
||||
sint32 bottom = top + screenDPI->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(IRainDrawer * rainDrawer)
|
||||
{
|
||||
// Get rain draw function and draw rain
|
||||
uint32 rainType = gClimateCurrentRainLevel;
|
||||
if (rainType > 0 && !(RCT2_GLOBAL(0x009DEA6F, uint8) & 1))
|
||||
{
|
||||
DrawRainAnimation(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);
|
||||
}
|
|
@ -42,7 +42,7 @@ void screenshot_check()
|
|||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, uint8) != 0) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, uint8)--;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, uint8) == 0) {
|
||||
update_rain_animation();
|
||||
// update_rain_animation();
|
||||
screenshotIndex = screenshot_dump();
|
||||
|
||||
if (screenshotIndex != -1) {
|
||||
|
@ -55,7 +55,7 @@ void screenshot_check()
|
|||
}
|
||||
|
||||
RCT2_GLOBAL(0x009A8C29, uint8) &= ~1;
|
||||
redraw_rain();
|
||||
// redraw_rain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,9 +281,9 @@ void rct2_draw()
|
|||
|
||||
// redraw_rain();
|
||||
// window_update_all();
|
||||
gfx_invalidate_pickedup_peep();
|
||||
gfx_draw_pickedup_peep();
|
||||
update_rain_animation();
|
||||
// gfx_invalidate_pickedup_peep();
|
||||
// gfx_draw_pickedup_peep();
|
||||
// update_rain_animation();
|
||||
update_palette_effects();
|
||||
|
||||
chat_draw();
|
||||
|
|
|
@ -485,7 +485,7 @@ static void title_update_showcase()
|
|||
game_logic_update();
|
||||
}
|
||||
update_palette_effects();
|
||||
update_rain_animation();
|
||||
// update_rain_animation();
|
||||
}
|
||||
} while (gTitleScriptSkipTo != -1 && gTitleScriptSkipLoad == -1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue