Merge pull request #4696 from IntelOrca/render/night-lights

The light effects mod branch #3798 by @JeroenDStout has become quite out of date. I plan to properly implement it, but first I want to merge in what we have already, so that I can branch off develop again and rebase (currently rebasing this branch is too difficult, far too many commits).

Most code that this is merging is protected by the __ENABLE_LIGHTFX__ directive, so it should not make any difference until its time to enable it via a new pull request.

I have isolated it as much as possible to lightfx.c.
This commit is contained in:
Ted John 2016-10-25 12:12:48 +01:00 committed by GitHub
commit aef32c0fba
11 changed files with 1298 additions and 55 deletions

View File

@ -73,6 +73,7 @@
<ClCompile Include="src\drawing\engines\SoftwareDrawingEngine.cpp" />
<ClCompile Include="src\drawing\font.c" />
<ClCompile Include="src\drawing\Image.cpp" />
<ClCompile Include="src\drawing\lightfx.c" />
<ClCompile Include="src\drawing\line.c" />
<ClCompile Include="src\drawing\NewDrawing.cpp" />
<ClCompile Include="src\drawing\Rain.cpp" />
@ -407,6 +408,7 @@
<ClInclude Include="src\drawing\IDrawingEngine.h" />
<ClInclude Include="src\drawing\NewDrawing.h" />
<ClInclude Include="src\drawing\Rain.h" />
<ClInclude Include="src\drawing\lightfx.h" />
<ClInclude Include="src\editor.h" />
<ClInclude Include="src\game.h" />
<ClInclude Include="src\hook.h" />

View File

@ -30,6 +30,7 @@ extern "C"
#include "../../interface/window.h"
#include "../../intro.h"
#include "../drawing.h"
#include "../lightfx.h"
}
class SoftwareDrawingEngine;
@ -194,6 +195,9 @@ private:
SDL_Texture * _screenTexture = nullptr;
SDL_PixelFormat * _screenTextureFormat = nullptr;
uint32 _paletteHWMapped[256] = { 0 };
#ifdef __ENABLE_LIGHTFX__
uint32 _lightPaletteHWMapped[256] = { 0 };
#endif
// Steam overlay checking
uint32 _pixelBeforeOverlay = 0;
@ -268,7 +272,7 @@ public:
}
_screenTexture = SDL_CreateTexture(_sdlRenderer, pixelFormat, SDL_TEXTUREACCESS_STREAMING, width, height);
uint32 format;
SDL_QueryTexture(_screenTexture, &format, 0, 0, 0);
_screenTextureFormat = SDL_AllocFormat(format);
@ -306,9 +310,15 @@ public:
{
if (_screenTextureFormat != nullptr)
{
#ifdef __ENABLE_LIGHTFX__
const SDL_Color * lightPalette = lightfx_get_palette();
#endif
for (int i = 0; i < 256; i++)
{
_paletteHWMapped[i] = SDL_MapRGB(_screenTextureFormat, palette[i].r, palette[i].g, palette[i].b);
#ifdef __ENABLE_LIGHTFX__
_lightPaletteHWMapped[i] = SDL_MapRGBA(_screenTextureFormat, lightPalette[i].r, lightPalette[i].g, lightPalette[i].b, lightPalette[i].a);
#endif
}
}
}
@ -522,6 +532,10 @@ private:
dpi->pitch = _pitch - width;
ConfigureDirtyGrid();
#ifdef __ENABLE_LIGHTFX__
lightfx_update_buffers(dpi);
#endif
}
void ConfigureDirtyGrid()
@ -681,52 +695,12 @@ private:
void DisplayViaTexture()
{
void * pixels;
int pitch;
if (SDL_LockTexture(_screenTexture, nullptr, &pixels, &pitch) == 0)
{
uint8 * src = _bits;
int padding = pitch - (_width * 4);
if ((uint32)pitch == _width * 4) {
uint32 * dst = (uint32 *)pixels;
for (int i = _width * _height; i > 0; i--)
{
*dst++ = _paletteHWMapped[*src++];
}
}
else
{
if ((uint32)pitch == (_width * 2) + padding)
{
uint16 * dst = (uint16 *)pixels;
for (sint32 y = (sint32)_height; y > 0; y--) {
for (sint32 x = (sint32)_width; x > 0; x--) {
const uint8 lower = *(uint8 *)(&_paletteHWMapped[*src++]);
const uint8 upper = *(uint8 *)(&_paletteHWMapped[*src++]);
*dst++ = (lower << 8) | upper;
}
dst = (uint16*)(((uint8 *)dst) + padding);
}
}
else
{
if ((uint32)pitch == _width + padding)
{
uint8 * dst = (uint8 *)pixels;
for (sint32 y = (sint32)_height; y > 0; y--) {
for (sint32 x = (sint32)_width; x > 0; x--)
{
*dst++ = *(uint8 *)(&_paletteHWMapped[*src++]);
}
dst += padding;
}
}
}
}
SDL_UnlockTexture(_screenTexture);
}
SDL_RenderCopy(_sdlRenderer, _screenTexture, NULL, NULL);
#ifdef __ENABLE_LIGHTFX__
lightfx_render_to_texture(_screenTexture, _bits, _width, _height, _paletteHWMapped, _lightPaletteHWMapped);
#else
CopyBitsToTexture(_screenTexture, _bits, (sint32)_width, (sint32)_height, _paletteHWMapped);
#endif
SDL_RenderCopy(_sdlRenderer, _screenTexture, nullptr, nullptr);
if (gSteamOverlayActive && gConfigGeneral.steam_overlay_pause)
{
@ -741,6 +715,54 @@ private:
}
}
void CopyBitsToTexture(SDL_Texture * texture, uint8 * src, sint32 width, sint32 height, uint32 * palette)
{
void * pixels;
int pitch;
if (SDL_LockTexture(texture, nullptr, &pixels, &pitch) == 0)
{
sint32 padding = pitch - (width * 4);
if (pitch == width * 4)
{
uint32 * dst = (uint32 *)pixels;
for (sint32 i = width * height; i > 0; i--)
{
*dst++ = palette[*src++];
}
}
else
{
if (pitch == (width * 2) + padding)
{
uint16 * dst = (uint16 *)pixels;
for (sint32 y = height; y > 0; y--)
{
for (sint32 x = width; x > 0; x--)
{
const uint8 lower = *(uint8 *)(&palette[*src++]);
const uint8 upper = *(uint8 *)(&palette[*src++]);
*dst++ = (lower << 8) | upper;
}
dst = (uint16*)(((uint8 *)dst) + padding);
}
}
else if (pitch == width + padding)
{
uint8 * dst = (uint8 *)pixels;
for (sint32 y = height; y > 0; y--)
{
for (sint32 x = width; x > 0; x--)
{
*dst++ = *(uint8 *)(&palette[*src++]);
}
dst += padding;
}
}
}
SDL_UnlockTexture(texture);
}
}
void ReadCentrePixel(uint32 * pixel)
{
SDL_Rect centrePixelRegion = { (sint32)(_width / 2), (sint32)(_height / 2), 1, 1 };

1029
src/drawing/lightfx.c Normal file

File diff suppressed because it is too large Load Diff

80
src/drawing/lightfx.h Normal file
View File

@ -0,0 +1,80 @@
#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
#ifndef _LIGHTFX_H
#define _LIGHTFX_H
#ifdef __ENABLE_LIGHTFX__
#include "../common.h"
#include "drawing.h"
typedef struct SDL_Texture;
enum LIGHTFX_LIGHT_TYPE {
LIGHTFX_LIGHT_TYPE_NONE = 0,
LIGHTFX_LIGHT_TYPE_RESERVED_01 = 1,
LIGHTFX_LIGHT_TYPE_LANTERN_0 = 4,
LIGHTFX_LIGHT_TYPE_LANTERN_1 = 5,
LIGHTFX_LIGHT_TYPE_LANTERN_2 = 6,
LIGHTFX_LIGHT_TYPE_LANTERN_3 = 7,
LIGHTFX_LIGHT_TYPE_SPOT_0 = 8,
LIGHTFX_LIGHT_TYPE_SPOT_1 = 9,
LIGHTFX_LIGHT_TYPE_SPOT_2 = 10,
LIGHTFX_LIGHT_TYPE_SPOT_3 = 11,
LIGHTFX_LIGHT_TYPE_RESERVED_FF = 0xFF
};
enum LIGHTFX_LIGHT_QUALIFIER {
LIGHTFX_LIGHT_QUALIFIER_SPRITE = 0x1,
LIGHTFX_LIGHT_QUALIFIER_MAP = 0x2
};
extern void lightfx_init();
extern void lightfx_update_buffers(rct_drawpixelinfo*);
extern void lightfx_prepare_light_list();
extern void lightfx_swap_buffers();
extern void lightfx_render_lights_to_frontbuffer();
extern void lightfx_update_viewport_settings();
extern void* lightfx_get_front_buffer();
const SDL_Color * lightfx_get_palette();
extern void lightfx_add_3d_light(uint32 lightID, uint16 lightIDqualifier, sint16 x, sint16 y, uint16 z, uint8 lightType);
extern void lightfx_add_3d_light_magic_from_drawing_tile(sint16 offsetX, sint16 offsetY, sint16 offsetZ, uint8 lightType);
extern void lightfx_add_lights_magic_vehicles();
extern uint32 lightfx_get_light_polution();
void lightfx_apply_palette_filter(uint8 i, uint8 *r, uint8 *g, uint8 *b);
void lightfx_render_to_texture(
struct SDL_Texture * texture,
uint8 * bits,
uint32 width,
uint32 height,
uint32 * palette,
uint32 * lightPalette);
#endif // __ENABLE_LIGHTFX__
#endif

View File

@ -24,6 +24,7 @@
#include "../paint.h"
#include "../supports.h"
#include "map_element.h"
#include "../../drawing/lightfx.h"
static uint32 _unk9E32BC;
@ -33,6 +34,7 @@ static uint32 _unk9E32BC;
*/
static void ride_entrance_exit_paint(uint8 direction, int height, rct_map_element* map_element)
{
uint8 is_exit = map_element->properties.entrance.type == ENTRANCE_TYPE_RIDE_EXIT;
if (gTrackDesignSaveMode) {
@ -40,6 +42,29 @@ static void ride_entrance_exit_paint(uint8 direction, int height, rct_map_elemen
return;
}
#ifdef __ENABLE_LIGHTFX__
if (!is_exit) {
lightfx_add_3d_light_magic_from_drawing_tile(0, 0, height + 45, LIGHTFX_LIGHT_TYPE_LANTERN_3);
}
switch (map_element->type & MAP_ELEMENT_DIRECTION_MASK) {
case 0:
lightfx_add_3d_light_magic_from_drawing_tile(16, 0, height + 16, LIGHTFX_LIGHT_TYPE_LANTERN_2);
break;
case 1:
lightfx_add_3d_light_magic_from_drawing_tile(0, -16, height + 16, LIGHTFX_LIGHT_TYPE_LANTERN_2);
break;
case 2:
lightfx_add_3d_light_magic_from_drawing_tile(-16, 0, height + 16, LIGHTFX_LIGHT_TYPE_LANTERN_2);
break;
case 3:
lightfx_add_3d_light_magic_from_drawing_tile(0, 16, height + 16, LIGHTFX_LIGHT_TYPE_LANTERN_2);
break;
};
#endif
rct_ride* ride = get_ride(map_element->properties.entrance.ride_index);
if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) return;
@ -164,6 +189,12 @@ static void park_entrance_paint(uint8 direction, int height, rct_map_element* ma
if (gTrackDesignSaveMode)
return;
#ifdef __ENABLE_LIGHTFX__
lightfx_add_3d_light_magic_from_drawing_tile(0, 0, 155, LIGHTFX_LIGHT_TYPE_LANTERN_3);
#endif
gPaintInteractionType = VIEWPORT_INTERACTION_ITEM_PARK;
_unk9E32BC = 0;
uint32 image_id, ghost_id = 0;

View File

@ -28,6 +28,8 @@
#include "../supports.h"
#include "map_element.h"
#include "surface.h"
#include "../../world/map.h"
#include "../../drawing/lightfx.h"
// #3628: Until path_paint is implemented, this variable is used by scrolling_text_setup
// to use the old string arguments array. Remove when scrolling_text_setup is no
@ -761,6 +763,26 @@ void path_paint(uint8 direction, uint16 height, rct_map_element * map_element)
} else {
loc_6A3B57(map_element, height, footpathEntry, word_F3F038, imageFlags, sceneryImageFlags);
}
#ifdef __ENABLE_LIGHTFX__
if (footpath_element_has_path_scenery(map_element) && !(map_element->flags & MAP_ELEMENT_FLAG_BROKEN)) {
rct_scenery_entry *sceneryEntry = get_footpath_item_entry(footpath_element_get_path_scenery_index(map_element));
if (sceneryEntry->path_bit.flags & PATH_BIT_FLAG_LAMP) {
if (!(map_element->properties.path.edges & (1 << 0))) {
lightfx_add_3d_light_magic_from_drawing_tile(-16, 0, height + 23, LIGHTFX_LIGHT_TYPE_LANTERN_3);
}
if (!(map_element->properties.path.edges & (1 << 1))) {
lightfx_add_3d_light_magic_from_drawing_tile(0, 16, height + 23, LIGHTFX_LIGHT_TYPE_LANTERN_3);
}
if (!(map_element->properties.path.edges & (1 << 2))) {
lightfx_add_3d_light_magic_from_drawing_tile(16, 0, height + 23, LIGHTFX_LIGHT_TYPE_LANTERN_3);
}
if (!(map_element->properties.path.edges & (1 << 3))) {
lightfx_add_3d_light_magic_from_drawing_tile(0, -16, height + 23, LIGHTFX_LIGHT_TYPE_LANTERN_3);
}
}
}
#endif
}
void loc_6A37C9(rct_map_element * mapElement, int height, rct_footpath_entry * footpathEntry, bool hasFences, uint32 imageFlags, uint32 sceneryImageFlags)

View File

@ -19,6 +19,7 @@
#include "../../paint/sprite/sprite.h"
#include "../../peep/peep.h"
#include "../paint.h"
#include "../../drawing/lightfx.h"
/**
*
@ -26,6 +27,37 @@
*/
void peep_paint(rct_peep * peep, int imageDirection)
{
#ifdef __ENABLE_LIGHTFX__
if (peep->type == PEEP_TYPE_STAFF){
sint16 peep_x, peep_y, peep_z;
peep_x = peep->x;
peep_y = peep->y;
peep_z = peep->z;
switch (peep->sprite_direction) {
case 0:
peep_x -= 10;
break;
case 8:
peep_y += 10;
break;
case 16:
peep_x += 10;
break;
case 24:
peep_y -= 10;
break;
default:
return;
};
lightfx_add_3d_light(peep->sprite_index, 0x0000 | LIGHTFX_LIGHT_QUALIFIER_SPRITE, peep_x, peep_y, peep_z, LIGHTFX_LIGHT_TYPE_SPOT_1);
}
#endif
rct_drawpixelinfo * dpi = unk_140E9A8;
if (dpi->zoom_level > 2) {
return;

View File

@ -130,6 +130,7 @@ void platform_update_fullscreen_resolutions();
void platform_get_closest_resolution(int inWidth, int inHeight, int *outWidth, int *outHeight);
void platform_init();
void platform_draw();
void platform_draw_require_end();
void platform_free();
void platform_trigger_resize();
void platform_update_palette(const uint8 *colours, int start_index, int num_colours);

View File

@ -18,6 +18,7 @@
#include "../audio/mixer.h"
#include "../config.h"
#include "../drawing/drawing.h"
#include "../drawing/lightfx.h"
#include "../game.h"
#include "../input.h"
#include "../interface/console.h"
@ -254,18 +255,25 @@ void platform_update_palette(const uint8* colours, int start_index, int num_colo
colours += start_index * 4;
for (int i = start_index; i < num_colours + start_index; i++) {
gPalette[i].r = colours[2];
gPalette[i].g = colours[1];
gPalette[i].b = colours[0];
gPalette[i].a = 0;
uint8 r = colours[2];
uint8 g = colours[1];
uint8 b = colours[0];
#ifdef __ENABLE_LIGHTFX__
lightfx_apply_palette_filter(i, &r, &g, &b);
#else
float night = gDayNightCycle;
if (night >= 0 && gClimateLightningFlash == 0) {
gPalette[i].r = lerp(gPalette[i].r, soft_light(gPalette[i].r, 8), night);
gPalette[i].g = lerp(gPalette[i].g, soft_light(gPalette[i].g, 8), night);
gPalette[i].b = lerp(gPalette[i].b, soft_light(gPalette[i].b, 128), night);
r = lerp(r, soft_light(r, 8), night);
g = lerp(g, soft_light(g, 8), night);
b = lerp(b, soft_light(b, 128), night);
}
#endif
gPalette[i].r = r;
gPalette[i].g = g;
gPalette[i].b = b;
gPalette[i].a = 0;
colours += 4;
if (gBufferTextureFormat != NULL) {
gPaletteHWMapped[i] = SDL_MapRGB(gBufferTextureFormat, gPalette[i].r, gPalette[i].g, gPalette[i].b);

View File

@ -52,6 +52,12 @@
#include "world/scenery.h"
#include "world/sprite.h"
#ifdef __ENABLE_LIGHTFX__
#include "drawing/lightfx.h"
#endif
// rct2: 0x0097F67C
const char * const RCT2FilePaths[PATH_ID_END] = {
"Data" PATH_SEPARATOR "g1.dat",
@ -193,6 +199,14 @@ bool rct2_init()
window_guest_list_init_vars_b();
window_staff_list_init_vars();
#ifdef __ENABLE_LIGHTFX__
lightfx_init();
#endif
log_verbose("initialising game finished");
return true;
}

View File

@ -21,6 +21,7 @@
#include "../ride/track.h"
#include "../interface/viewport.h"
#include "../game.h"
#include "../drawing/lightfx.h"
#include "vehicle_paint.h"
// 0x0098E52C:
@ -891,6 +892,7 @@ const vehicle_boundbox VehicleBoundboxes[16][224] = {
// 6D5214
static void vehicle_sprite_paint(rct_vehicle *vehicle, int ebx, int ecx, int z, const rct_ride_entry_vehicle *vehicleEntry)
{
int baseImage_id = ebx;
vehicle_boundbox bb = VehicleBoundboxes[vehicleEntry->draw_order][ecx];
if (vehicleEntry->flags_a & 0x4000) {
@ -2333,7 +2335,7 @@ void vehicle_visual_default(int x, int imageDirection, int y, int z, rct_vehicle
*/
void vehicle_paint(rct_vehicle *vehicle, int imageDirection)
{
rct_ride_entry *rideEntry;
rct_ride_entry *rideEntry = 0;
const rct_ride_entry_vehicle *vehicleEntry;
int x = vehicle->x;