mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2024-11-08 21:34:55 +00:00
neo screen droplets
This commit is contained in:
parent
8963cbcb7c
commit
07fe099b4e
|
@ -309,7 +309,10 @@ project "reVC"
|
||||||
linkoptions "/SAFESEH:NO"
|
linkoptions "/SAFESEH:NO"
|
||||||
characterset ("MBCS")
|
characterset ("MBCS")
|
||||||
targetextension ".exe"
|
targetextension ".exe"
|
||||||
staticruntime "on"
|
if(_OPTIONS["with-librw"]) then
|
||||||
|
-- external librw is dynamic
|
||||||
|
staticruntime "on"
|
||||||
|
end
|
||||||
|
|
||||||
filter "platforms:win*glfw*"
|
filter "platforms:win*glfw*"
|
||||||
staticruntime "off"
|
staticruntime "off"
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "ColStore.h"
|
#include "ColStore.h"
|
||||||
#include "Automobile.h"
|
#include "Automobile.h"
|
||||||
#include "MBlur.h"
|
#include "MBlur.h"
|
||||||
|
#include "screendroplets.h"
|
||||||
|
|
||||||
uint8 CGameLogic::ActivePlayers;
|
uint8 CGameLogic::ActivePlayers;
|
||||||
uint8 CGameLogic::ShortCutState;
|
uint8 CGameLogic::ShortCutState;
|
||||||
|
@ -153,6 +154,9 @@ CGameLogic::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CEventList::Initialise();
|
CEventList::Initialise();
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::Initialise();
|
||||||
|
#endif
|
||||||
CMessages::ClearMessages();
|
CMessages::ClearMessages();
|
||||||
CCarCtrl::ClearInterestingVehicleList();
|
CCarCtrl::ClearInterestingVehicleList();
|
||||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||||
|
@ -259,6 +263,9 @@ CGameLogic::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CEventList::Initialise();
|
CEventList::Initialise();
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::Initialise();
|
||||||
|
#endif
|
||||||
CMessages::ClearMessages();
|
CMessages::ClearMessages();
|
||||||
CCarCtrl::ClearInterestingVehicleList();
|
CCarCtrl::ClearInterestingVehicleList();
|
||||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||||
|
@ -311,6 +318,9 @@ CGameLogic::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CEventList::Initialise();
|
CEventList::Initialise();
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::Initialise();
|
||||||
|
#endif
|
||||||
CMessages::ClearMessages();
|
CMessages::ClearMessages();
|
||||||
CCarCtrl::ClearInterestingVehicleList();
|
CCarCtrl::ClearInterestingVehicleList();
|
||||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
#include "WaterCreatures.h"
|
#include "WaterCreatures.h"
|
||||||
#include "postfx.h"
|
#include "postfx.h"
|
||||||
#include "custompipes.h"
|
#include "custompipes.h"
|
||||||
|
#include "screendroplets.h"
|
||||||
|
|
||||||
eLevelName CGame::currLevel;
|
eLevelName CGame::currLevel;
|
||||||
int32 CGame::currArea;
|
int32 CGame::currArea;
|
||||||
|
@ -401,6 +402,9 @@ bool CGame::Initialise(const char* datFile)
|
||||||
CPed::Initialise();
|
CPed::Initialise();
|
||||||
CRouteNode::Initialise();
|
CRouteNode::Initialise();
|
||||||
CEventList::Initialise();
|
CEventList::Initialise();
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::Initialise();
|
||||||
|
#endif
|
||||||
LoadingScreen("Loading the Game", "Find big buildings", nil);
|
LoadingScreen("Loading the Game", "Find big buildings", nil);
|
||||||
CRenderer::Init();
|
CRenderer::Init();
|
||||||
LoadingScreen("Loading the Game", "Setup game variables", nil);
|
LoadingScreen("Loading the Game", "Setup game variables", nil);
|
||||||
|
@ -568,6 +572,9 @@ void CGame::ReInitGameObjectVariables(void)
|
||||||
currArea = AREA_MAIN_MAP;
|
currArea = AREA_MAIN_MAP;
|
||||||
CPed::Initialise();
|
CPed::Initialise();
|
||||||
CEventList::Initialise();
|
CEventList::Initialise();
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::Initialise();
|
||||||
|
#endif
|
||||||
CWeapon::InitialiseWeapons();
|
CWeapon::InitialiseWeapons();
|
||||||
CPopulation::Initialise();
|
CPopulation::Initialise();
|
||||||
|
|
||||||
|
|
|
@ -246,10 +246,18 @@ enum Config {
|
||||||
#ifdef LIBRW
|
#ifdef LIBRW
|
||||||
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
|
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
|
||||||
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
||||||
|
//#define SCREEN_DROPLETS // neo water droplets
|
||||||
//#define NEW_RENDERER // leeds-like world rendering, needs librw
|
//#define NEW_RENDERER // leeds-like world rendering, needs librw
|
||||||
#endif
|
#endif
|
||||||
//#define MULTISAMPLING // adds MSAA option TODO
|
//#define MULTISAMPLING // adds MSAA option TODO
|
||||||
|
|
||||||
|
#ifndef EXTENDED_COLOURFILTER
|
||||||
|
#undef SCREEN_DROPLETS // we need the front- (or back-)buffer for this effect
|
||||||
|
#endif
|
||||||
|
#ifndef EXTENDED_PIPELINES
|
||||||
|
#undef SCREEN_DROPLETS // we need neo.txd
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBRW
|
#ifdef LIBRW
|
||||||
// these are not supported with librw yet
|
// these are not supported with librw yet
|
||||||
# undef MULTISAMPLING
|
# undef MULTISAMPLING
|
||||||
|
|
|
@ -68,7 +68,9 @@
|
||||||
#include "Clock.h"
|
#include "Clock.h"
|
||||||
#include "Occlusion.h"
|
#include "Occlusion.h"
|
||||||
#include "Ropes.h"
|
#include "Ropes.h"
|
||||||
|
#include "postfx.h"
|
||||||
#include "custompipes.h"
|
#include "custompipes.h"
|
||||||
|
#include "screendroplets.h"
|
||||||
|
|
||||||
GlobalScene Scene;
|
GlobalScene Scene;
|
||||||
|
|
||||||
|
@ -401,6 +403,9 @@ Initialise3D(void *param)
|
||||||
bool ret = CGame::InitialiseRenderWare();
|
bool ret = CGame::InitialiseRenderWare();
|
||||||
#ifdef EXTENDED_PIPELINES
|
#ifdef EXTENDED_PIPELINES
|
||||||
CustomPipes::CustomPipeInit(); // need Scene.world for this
|
CustomPipes::CustomPipeInit(); // need Scene.world for this
|
||||||
|
#endif
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::InitDraw();
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -411,6 +416,9 @@ Initialise3D(void *param)
|
||||||
static void
|
static void
|
||||||
Terminate3D(void)
|
Terminate3D(void)
|
||||||
{
|
{
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::Shutdown();
|
||||||
|
#endif
|
||||||
#ifdef EXTENDED_PIPELINES
|
#ifdef EXTENDED_PIPELINES
|
||||||
CustomPipes::CustomPipeShutdown();
|
CustomPipes::CustomPipeShutdown();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1246,10 +1254,17 @@ Idle(void *arg)
|
||||||
RenderDebugShit();
|
RenderDebugShit();
|
||||||
RenderEffects();
|
RenderEffects();
|
||||||
|
|
||||||
tbStartTimer(0, "RenderMotionBlur");
|
|
||||||
if((TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE) &&
|
if((TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE) &&
|
||||||
TheCamera.m_ScreenReductionPercentage > 0.0f)
|
TheCamera.m_ScreenReductionPercentage > 0.0f)
|
||||||
TheCamera.SetMotionBlurAlpha(150);
|
TheCamera.SetMotionBlurAlpha(150);
|
||||||
|
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
CPostFX::GetBackBuffer(Scene.camera);
|
||||||
|
ScreenDroplets::Process();
|
||||||
|
ScreenDroplets::Render();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tbStartTimer(0, "RenderMotionBlur");
|
||||||
TheCamera.RenderMotionBlur();
|
TheCamera.RenderMotionBlur();
|
||||||
tbEndTimer("RenderMotionBlur");
|
tbEndTimer("RenderMotionBlur");
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ CustomMatCopy(void *dst, void *src, int32, int32)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static rw::TexDictionary *neoTxd;
|
rw::TexDictionary *neoTxd;
|
||||||
|
|
||||||
bool bRenderingEnvMap;
|
bool bRenderingEnvMap;
|
||||||
int32 EnvMapSize = 128;
|
int32 EnvMapSize = 128;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
namespace CustomPipes {
|
namespace CustomPipes {
|
||||||
|
|
||||||
|
|
||||||
|
extern rw::TexDictionary *neoTxd;
|
||||||
|
|
||||||
struct CustomMatExt
|
struct CustomMatExt
|
||||||
{
|
{
|
||||||
|
|
|
@ -132,6 +132,8 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d3d::setTexture(1, nil);
|
||||||
|
|
||||||
SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,8 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTexture(1, nil);
|
||||||
|
|
||||||
SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||||
|
|
||||||
#ifndef RW_GL_USE_VAOS
|
#ifndef RW_GL_USE_VAOS
|
||||||
|
|
|
@ -375,6 +375,14 @@ CPostFX::NeedFrontBuffer(int32 type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPostFX::GetBackBuffer(RwCamera *cam)
|
||||||
|
{
|
||||||
|
RwRasterPushContext(pBackBuffer);
|
||||||
|
RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
|
||||||
|
RwRasterPopContext();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
|
CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
|
||||||
{
|
{
|
||||||
|
@ -391,11 +399,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
|
||||||
blur = AvgAlpha;
|
blur = AvgAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NeedBackBuffer()){
|
if(NeedBackBuffer())
|
||||||
RwRasterPushContext(pBackBuffer);
|
GetBackBuffer(cam);
|
||||||
RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
|
|
||||||
RwRasterPopContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
DefinedState();
|
DefinedState();
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ public:
|
||||||
static void SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha);
|
static void SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha);
|
||||||
static bool NeedBackBuffer(void);
|
static bool NeedBackBuffer(void);
|
||||||
static bool NeedFrontBuffer(int32 type);
|
static bool NeedFrontBuffer(int32 type);
|
||||||
|
static void GetBackBuffer(RwCamera *cam);
|
||||||
static bool UseBlurColours(void) { return EffectSwitch != POSTFX_SIMPLE; }
|
static bool UseBlurColours(void) { return EffectSwitch != POSTFX_SIMPLE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
791
src/extras/screendroplets.cpp
Normal file
791
src/extras/screendroplets.cpp
Normal file
|
@ -0,0 +1,791 @@
|
||||||
|
#define WITH_D3D
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
|
||||||
|
#ifndef LIBRW
|
||||||
|
#error "Need librw for SCREEN_DROPLETS"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "General.h"
|
||||||
|
#include "Main.h"
|
||||||
|
#include "RwHelper.h"
|
||||||
|
#include "Main.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "ZoneCull.h"
|
||||||
|
#include "Weather.h"
|
||||||
|
#include "ParticleObject.h"
|
||||||
|
#include "Pad.h"
|
||||||
|
#include "RenderBuffer.h"
|
||||||
|
#include "custompipes.h"
|
||||||
|
#include "postfx.h"
|
||||||
|
#include "screendroplets.h"
|
||||||
|
|
||||||
|
// for 640
|
||||||
|
#define MAXSIZE 15
|
||||||
|
#define MINSIZE 4
|
||||||
|
|
||||||
|
int ScreenDroplets::ms_initialised;
|
||||||
|
RwTexture *ScreenDroplets::ms_maskTex;
|
||||||
|
RwTexture *ScreenDroplets::ms_screenTex;
|
||||||
|
|
||||||
|
bool ScreenDroplets::ms_enabled = true;
|
||||||
|
bool ScreenDroplets::ms_movingEnabled = true;
|
||||||
|
|
||||||
|
ScreenDroplets::ScreenDrop ScreenDroplets::ms_drops[ScreenDroplets::MAXDROPS];
|
||||||
|
int ScreenDroplets::ms_numDrops;
|
||||||
|
ScreenDroplets::ScreenDropMoving ScreenDroplets::ms_dropsMoving[ScreenDroplets::MAXDROPSMOVING];
|
||||||
|
int ScreenDroplets::ms_numDropsMoving;
|
||||||
|
|
||||||
|
CVector ScreenDroplets::ms_prevCamUp;
|
||||||
|
CVector ScreenDroplets::ms_prevCamPos;
|
||||||
|
CVector ScreenDroplets::ms_camMoveDelta;
|
||||||
|
float ScreenDroplets::ms_camMoveDist;
|
||||||
|
CVector ScreenDroplets::ms_screenMoveDelta;
|
||||||
|
float ScreenDroplets::ms_screenMoveDist;
|
||||||
|
float ScreenDroplets::ms_camUpAngle;
|
||||||
|
|
||||||
|
int ScreenDroplets::ms_splashDuration;
|
||||||
|
CParticleObject *ScreenDroplets::ms_splashObject;
|
||||||
|
|
||||||
|
struct Im2DVertexUV2 : rw::RWDEVICE::Im2DVertex
|
||||||
|
{
|
||||||
|
rw::float32 u2, v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
static void *screenDroplet_PS;
|
||||||
|
#endif
|
||||||
|
#ifdef RW_GL3
|
||||||
|
static rw::gl3::Shader *screenDroplet;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// platform specific
|
||||||
|
static void openim2d_uv2(void);
|
||||||
|
static void closeim2d_uv2(void);
|
||||||
|
static void RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices);
|
||||||
|
|
||||||
|
static Im2DVertexUV2 VertexBuffer[TEMPBUFFERVERTSIZE];
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::Initialise(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
ms_splashDuration = -1;
|
||||||
|
ms_splashObject = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::InitDraw(void)
|
||||||
|
{
|
||||||
|
if(CustomPipes::neoTxd)
|
||||||
|
ms_maskTex = CustomPipes::neoTxd->find("dropmask");
|
||||||
|
|
||||||
|
ms_screenTex = RwTextureCreate(nil);
|
||||||
|
RwTextureSetFilterMode(ms_screenTex, rwFILTERLINEAR);
|
||||||
|
|
||||||
|
openim2d_uv2();
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
#include "shaders/screenDroplet_PS.inc"
|
||||||
|
screenDroplet_PS = rw::d3d::createPixelShader(screenDroplet_PS_cso);
|
||||||
|
#endif
|
||||||
|
#ifdef RW_GL3
|
||||||
|
using namespace rw::gl3;
|
||||||
|
{
|
||||||
|
#include "shaders/im2d_UV2_gl.inc"
|
||||||
|
#include "shaders/screenDroplet_fs_gl.inc"
|
||||||
|
const char *vs[] = { shaderDecl, header_vert_src, im2d_UV2_vert_src, nil };
|
||||||
|
const char *fs[] = { shaderDecl, header_frag_src, screenDroplet_frag_src, nil };
|
||||||
|
screenDroplet = Shader::create(vs, fs);
|
||||||
|
assert(screenDroplet);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ms_initialised = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::Shutdown(void)
|
||||||
|
{
|
||||||
|
if(ms_maskTex){
|
||||||
|
RwTextureDestroy(ms_maskTex);
|
||||||
|
ms_maskTex = nil;
|
||||||
|
}
|
||||||
|
if(ms_screenTex){
|
||||||
|
RwTextureSetRaster(ms_screenTex, nil);
|
||||||
|
RwTextureDestroy(ms_screenTex);
|
||||||
|
ms_screenTex = nil;
|
||||||
|
}
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
if(screenDroplet_PS){
|
||||||
|
rw::d3d::destroyPixelShader(screenDroplet_PS);
|
||||||
|
screenDroplet_PS = nil;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef RW_GL3
|
||||||
|
if(screenDroplet){
|
||||||
|
screenDroplet->destroy();
|
||||||
|
screenDroplet = nil;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
closeim2d_uv2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::Process(void)
|
||||||
|
{
|
||||||
|
ProcessCameraMovement();
|
||||||
|
SprayDrops();
|
||||||
|
ProcessMoving();
|
||||||
|
Fade();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FlushBuffer(void)
|
||||||
|
{
|
||||||
|
if(TempBufferIndicesStored){
|
||||||
|
RenderIndexedPrimitive_UV2(rwPRIMTYPETRILIST,
|
||||||
|
VertexBuffer, TempBufferVerticesStored,
|
||||||
|
TempBufferRenderIndexList, TempBufferIndicesStored);
|
||||||
|
TempBufferVerticesStored = 0;
|
||||||
|
TempBufferIndicesStored = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
StartStoring(int numIndices, int numVertices, RwImVertexIndex **indexStart, Im2DVertexUV2 **vertexStart)
|
||||||
|
{
|
||||||
|
if(TempBufferIndicesStored + numIndices >= TEMPBUFFERINDEXSIZE ||
|
||||||
|
TempBufferVerticesStored + numVertices >= TEMPBUFFERVERTSIZE)
|
||||||
|
FlushBuffer();
|
||||||
|
*indexStart = &TempBufferRenderIndexList[TempBufferIndicesStored];
|
||||||
|
*vertexStart = &VertexBuffer[TempBufferVerticesStored];
|
||||||
|
int vertOffset = TempBufferVerticesStored;
|
||||||
|
TempBufferIndicesStored += numIndices;
|
||||||
|
TempBufferVerticesStored += numVertices;
|
||||||
|
return vertOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::Render(void)
|
||||||
|
{
|
||||||
|
ScreenDrop *drop;
|
||||||
|
|
||||||
|
DefinedState();
|
||||||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(ms_maskTex));
|
||||||
|
RwRenderStateSet(rwRENDERSTATEFOGENABLE, FALSE);
|
||||||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, FALSE);
|
||||||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
|
||||||
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||||
|
|
||||||
|
RwTextureSetRaster(ms_screenTex, CPostFX::pBackBuffer);
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
rw::d3d::im2dOverridePS = screenDroplet_PS;
|
||||||
|
rw::d3d::setTexture(1, ms_screenTex);
|
||||||
|
#endif
|
||||||
|
#ifdef RW_GL3
|
||||||
|
rw::gl3::im2dOverrideShader = screenDroplet;
|
||||||
|
rw::gl3::setTexture(1, ms_screenTex);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RenderBuffer::ClearRenderBuffer();
|
||||||
|
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
|
||||||
|
if(drop->active)
|
||||||
|
AddToRenderList(drop);
|
||||||
|
FlushBuffer();
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
rw::d3d::im2dOverridePS = nil;
|
||||||
|
rw::d3d::setTexture(1, nil);
|
||||||
|
#endif
|
||||||
|
#ifdef RW_GL3
|
||||||
|
rw::gl3::im2dOverrideShader = nil;
|
||||||
|
rw::gl3::setTexture(1, nil);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RwRenderStateSet(rwRENDERSTATEFOGENABLE, FALSE);
|
||||||
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||||
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||||
|
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||||||
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::AddToRenderList(ScreenDroplets::ScreenDrop *drop)
|
||||||
|
{
|
||||||
|
static float xy[] = {
|
||||||
|
-1.0f, -1.0f,
|
||||||
|
-1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f,
|
||||||
|
1.0f, -1.0f
|
||||||
|
};
|
||||||
|
static float uv[] = {
|
||||||
|
0.0f, 0.0f,
|
||||||
|
0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f,
|
||||||
|
1.0f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
RwImVertexIndex *indices;
|
||||||
|
Im2DVertexUV2 *verts;
|
||||||
|
int first = StartStoring(6, 4, &indices, &verts);
|
||||||
|
|
||||||
|
float scale = 0.5f*SCREEN_SCALE_X(drop->size);
|
||||||
|
|
||||||
|
float screenz = RwIm2DGetNearScreenZ();
|
||||||
|
float z = RwCameraGetNearClipPlane(Scene.camera);
|
||||||
|
float recipz = 1.0f/z;
|
||||||
|
|
||||||
|
float magSize = SCREEN_SCALE_Y(drop->magnification*(300.0f-40.0f) + 40.0f);
|
||||||
|
float ul = drop->x - magSize;
|
||||||
|
float vt = drop->y - magSize;
|
||||||
|
float ur = drop->x + magSize;
|
||||||
|
float vb = drop->y + magSize;
|
||||||
|
ul = Max(ul, 0.0f)/RwRasterGetWidth(CPostFX::pBackBuffer);
|
||||||
|
vt = Max(vt, 0.0f)/RwRasterGetHeight(CPostFX::pBackBuffer);
|
||||||
|
ur = Min(ur, SCREEN_WIDTH)/RwRasterGetWidth(CPostFX::pBackBuffer);
|
||||||
|
vb = Min(vb, SCREEN_HEIGHT)/RwRasterGetHeight(CPostFX::pBackBuffer);
|
||||||
|
|
||||||
|
for(i = 0; i < 4; i++){
|
||||||
|
RwIm2DVertexSetScreenX(&verts[i], drop->x + xy[i*2]*scale);
|
||||||
|
RwIm2DVertexSetScreenY(&verts[i], drop->y + xy[i*2+1]*scale);
|
||||||
|
RwIm2DVertexSetScreenZ(&verts[i], screenz);
|
||||||
|
RwIm2DVertexSetCameraZ(&verts[i], z);
|
||||||
|
RwIm2DVertexSetRecipCameraZ(&verts[i], recipz);
|
||||||
|
RwIm2DVertexSetIntRGBA(&verts[i], drop->color.r, drop->color.g, drop->color.b, drop->color.a);
|
||||||
|
RwIm2DVertexSetU(&verts[i], uv[i*2], recipz);
|
||||||
|
RwIm2DVertexSetV(&verts[i], uv[i*2+1], recipz);
|
||||||
|
|
||||||
|
verts[i].u2 = i < 2 ? ul : ur;
|
||||||
|
verts[i].v2 = i % 3 ? vt : vb;
|
||||||
|
}
|
||||||
|
indices[0] = first + 0;
|
||||||
|
indices[1] = first + 1;
|
||||||
|
indices[2] = first + 2;
|
||||||
|
indices[3] = first + 2;
|
||||||
|
indices[4] = first + 3;
|
||||||
|
indices[5] = first + 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::Clear(void)
|
||||||
|
{
|
||||||
|
ScreenDrop *drop;
|
||||||
|
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
|
||||||
|
drop->active = false;
|
||||||
|
ms_numDrops = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenDroplets::ScreenDrop*
|
||||||
|
ScreenDroplets::NewDrop(float x, float y, float size, float lifetime, bool fades, int r, int g, int b)
|
||||||
|
{
|
||||||
|
ScreenDrop *drop;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0, drop = ms_drops; i < MAXDROPS; i++, drop++)
|
||||||
|
if(!ms_drops[i].active)
|
||||||
|
goto found;
|
||||||
|
return nil;
|
||||||
|
found:
|
||||||
|
ms_numDrops++;
|
||||||
|
drop->x = x;
|
||||||
|
drop->y = y;
|
||||||
|
drop->size = size;
|
||||||
|
drop->magnification = (MAXSIZE - size + 1.0f) / (MAXSIZE - MINSIZE + 1.0f);
|
||||||
|
drop->fades = fades;
|
||||||
|
drop->active = true;
|
||||||
|
drop->color.r = r;
|
||||||
|
drop->color.g = g;
|
||||||
|
drop->color.b = b;
|
||||||
|
drop->color.a = 255;
|
||||||
|
drop->time = 0.0f;
|
||||||
|
drop->lifetime = lifetime;
|
||||||
|
return drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::SetMoving(ScreenDroplets::ScreenDrop *drop)
|
||||||
|
{
|
||||||
|
ScreenDropMoving *moving;
|
||||||
|
for(moving = ms_dropsMoving; moving < &ms_dropsMoving[MAXDROPSMOVING]; moving++)
|
||||||
|
if(moving->drop == nil)
|
||||||
|
goto found;
|
||||||
|
return;
|
||||||
|
found:
|
||||||
|
ms_numDropsMoving++;
|
||||||
|
moving->drop = drop;
|
||||||
|
moving->dist = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::FillScreen(int n)
|
||||||
|
{
|
||||||
|
float x, y, size;
|
||||||
|
ScreenDrop *drop;
|
||||||
|
|
||||||
|
if(!ms_initialised)
|
||||||
|
return;
|
||||||
|
ms_numDrops = 0;
|
||||||
|
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++){
|
||||||
|
drop->active = false;
|
||||||
|
if(drop < &ms_drops[n]){
|
||||||
|
x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
|
||||||
|
y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
|
||||||
|
size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
|
||||||
|
NewDrop(x, y, size, 2000.0f, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::FillScreenMoving(float amount, bool isBlood)
|
||||||
|
{
|
||||||
|
int n = (ms_screenMoveDelta.z > 5.0f ? 1.5f : 1.0f)*amount*20.0f;
|
||||||
|
float x, y, size;
|
||||||
|
ScreenDrop *drop;
|
||||||
|
|
||||||
|
while(n--)
|
||||||
|
if(ms_numDrops < MAXDROPS && ms_numDropsMoving < MAXDROPSMOVING){
|
||||||
|
x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
|
||||||
|
y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
|
||||||
|
size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
|
||||||
|
drop = nil;
|
||||||
|
if(isBlood)
|
||||||
|
drop = NewDrop(x, y, size, 2000.0f, true, 255, 0, 0);
|
||||||
|
else
|
||||||
|
drop = NewDrop(x, y, size, 2000.0f, true);
|
||||||
|
if(drop)
|
||||||
|
SetMoving(drop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::RegisterSplash(CParticleObject *pobj)
|
||||||
|
{
|
||||||
|
CVector dist = pobj->GetPosition() - ms_prevCamPos;
|
||||||
|
if(dist.MagnitudeSqr() < 20.0f){
|
||||||
|
ms_splashDuration = 14;
|
||||||
|
ms_splashObject = pobj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::ProcessCameraMovement(void)
|
||||||
|
{
|
||||||
|
RwMatrix *camMat = RwFrameGetMatrix(RwCameraGetFrame(Scene.camera));
|
||||||
|
CVector camPos = camMat->pos;
|
||||||
|
CVector camUp = camMat->at;
|
||||||
|
ms_camMoveDelta = camPos - ms_prevCamPos;
|
||||||
|
ms_camMoveDist = ms_camMoveDelta.Magnitude();
|
||||||
|
|
||||||
|
ms_prevCamUp = camUp;
|
||||||
|
ms_prevCamPos = camPos;
|
||||||
|
|
||||||
|
ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, (RwV3d*)&ms_camMoveDelta);
|
||||||
|
ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, (RwV3d*)&ms_camMoveDelta);
|
||||||
|
ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, (RwV3d*)&ms_camMoveDelta);
|
||||||
|
ms_screenMoveDelta *= 10.0f;
|
||||||
|
ms_screenMoveDist = ms_screenMoveDelta.Magnitude2D();
|
||||||
|
|
||||||
|
uint16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
|
||||||
|
bool isTopDown = mode == CCam::MODE_TOPDOWN || mode == CCam::MODE_GTACLASSIC || mode == CCam::MODE_TOP_DOWN_PED;
|
||||||
|
bool isLookingInDirection = CPad::GetPad(0)->GetLookBehindForCar() || CPad::GetPad(0)->GetLookLeft() || CPad::GetPad(0)->GetLookRight();
|
||||||
|
ms_enabled = !isTopDown && !isLookingInDirection;
|
||||||
|
ms_movingEnabled = !isTopDown && !isLookingInDirection;
|
||||||
|
|
||||||
|
// 0 when looking stright up, 180 when looking up or down
|
||||||
|
ms_camUpAngle = RADTODEG(Acos(clamp(camUp.z, -1.0f, 1.0f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::SprayDrops(void)
|
||||||
|
{
|
||||||
|
bool noRain = CCullZones::PlayerNoRain() || CCullZones::CamNoRain();
|
||||||
|
if(!noRain && CWeather::Rain > 0.0f && ms_enabled){
|
||||||
|
// 180 when looking stright up, 0 when looking up or down
|
||||||
|
float angle = 180.0f - ms_camUpAngle;
|
||||||
|
angle = Max(angle, 40.0f); // want at least some rain
|
||||||
|
FillScreenMoving((angle - 40.0f) / 150.0f * CWeather::Rain * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < MAX_AUDIOHYDRANTS; i++){
|
||||||
|
CAudioHydrant *hyd = CAudioHydrant::Get(i);
|
||||||
|
if (hyd->pParticleObject){
|
||||||
|
CVector dist = hyd->pParticleObject->GetPosition() - ms_prevCamPos;
|
||||||
|
if(dist.MagnitudeSqr() > 40.0f ||
|
||||||
|
DotProduct(dist, ms_prevCamUp) < 0.0f) continue;
|
||||||
|
|
||||||
|
FillScreenMoving(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ndrops[] = {
|
||||||
|
125, 250, 500, 1000, 1000,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
if(ms_splashDuration >= 0){
|
||||||
|
if(ms_numDrops < MAXDROPS) {
|
||||||
|
float numDropMult = 1.0f;
|
||||||
|
if(ms_splashObject){
|
||||||
|
float dist = (ms_splashObject->GetPosition() - ms_prevCamPos).Magnitude();
|
||||||
|
numDropMult = 1.0f - (dist - 5.0f)/15.0f;
|
||||||
|
if(numDropMult < 0) numDropMult = 0.0f; // fix
|
||||||
|
}
|
||||||
|
int n = ndrops[ms_splashDuration] * numDropMult;
|
||||||
|
while(n--)
|
||||||
|
if(ms_numDrops < MAXDROPS){
|
||||||
|
float x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
|
||||||
|
float y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
|
||||||
|
float size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
|
||||||
|
NewDrop(x, y, size, 10000.0f, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ms_splashDuration--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::NewTrace(ScreenDroplets::ScreenDropMoving *moving)
|
||||||
|
{
|
||||||
|
if(ms_numDrops < MAXDROPS){
|
||||||
|
moving->dist = 0.0f;
|
||||||
|
NewDrop(moving->drop->x, moving->drop->y, MINSIZE, 500.0f, true,
|
||||||
|
moving->drop->color.r, moving->drop->color.g, moving->drop->color.b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::MoveDrop(ScreenDroplets::ScreenDropMoving *moving)
|
||||||
|
{
|
||||||
|
ScreenDrop *drop = moving->drop;
|
||||||
|
if(!ms_movingEnabled)
|
||||||
|
return;
|
||||||
|
if(!drop->active){
|
||||||
|
moving->drop = nil;
|
||||||
|
ms_numDropsMoving--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(ms_screenMoveDelta.z > 0.0f && ms_camMoveDist > 0.3f){
|
||||||
|
if(ms_screenMoveDist > 0.5f && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){
|
||||||
|
// movement when camera turns
|
||||||
|
moving->dist += ms_screenMoveDist;
|
||||||
|
if(moving->dist > 20.0f && drop->color.a > 100)
|
||||||
|
NewTrace(moving);
|
||||||
|
|
||||||
|
drop->x -= ms_screenMoveDelta.x;
|
||||||
|
drop->y += ms_screenMoveDelta.y;
|
||||||
|
}else{
|
||||||
|
// movement out of center
|
||||||
|
float d = ms_screenMoveDelta.z*0.2f;
|
||||||
|
float dx, dy, sum;
|
||||||
|
dx = drop->x - SCREEN_WIDTH*0.5f + ms_screenMoveDelta.x;
|
||||||
|
if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON)
|
||||||
|
dy = drop->y - SCREEN_HEIGHT*1.2f - ms_screenMoveDelta.y;
|
||||||
|
else
|
||||||
|
dy = drop->y - SCREEN_HEIGHT*0.5f - ms_screenMoveDelta.y;
|
||||||
|
sum = fabs(dx) + fabs(dy);
|
||||||
|
if(sum > 0.001f){
|
||||||
|
dx /= sum;
|
||||||
|
dy /= sum;
|
||||||
|
}
|
||||||
|
moving->dist += d;
|
||||||
|
if(moving->dist > 20.0f && drop->color.a > 100)
|
||||||
|
NewTrace(moving);
|
||||||
|
drop->x += dx * d;
|
||||||
|
drop->y += dy * d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drop->x < 0.0f || drop->y < 0.0f ||
|
||||||
|
drop->x > SCREEN_WIDTH || drop->y > SCREEN_HEIGHT){
|
||||||
|
moving->drop = nil;
|
||||||
|
ms_numDropsMoving--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::ProcessMoving(void)
|
||||||
|
{
|
||||||
|
ScreenDropMoving *moving;
|
||||||
|
if(!ms_movingEnabled)
|
||||||
|
return;
|
||||||
|
for(moving = ms_dropsMoving; moving < &ms_dropsMoving[MAXDROPSMOVING]; moving++)
|
||||||
|
if(moving->drop)
|
||||||
|
MoveDrop(moving);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::Fade(void)
|
||||||
|
{
|
||||||
|
ScreenDrop *drop;
|
||||||
|
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
|
||||||
|
if(drop->active)
|
||||||
|
drop->Fade();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenDroplets::ScreenDrop::Fade(void)
|
||||||
|
{
|
||||||
|
int delta = CTimer::GetTimeStepInMilliseconds();
|
||||||
|
time += delta;
|
||||||
|
if(time < lifetime){
|
||||||
|
color.a = 255 - time/lifetime*255;
|
||||||
|
}else if(fades){
|
||||||
|
ScreenDroplets::ms_numDrops--;
|
||||||
|
active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Im2D with two uv coors
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef RW_D3D9
|
||||||
|
// stolen from RW, not in a public header
|
||||||
|
namespace rw {
|
||||||
|
namespace d3d {
|
||||||
|
void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer
|
||||||
|
void removeDynamicVB(IDirect3DVertexBuffer9 **buf);
|
||||||
|
void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); // NB: don't share this pointer
|
||||||
|
void removeDynamicIB(IDirect3DIndexBuffer9 **buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// different than im2d
|
||||||
|
#define NUMINDICES 1024
|
||||||
|
#define NUMVERTICES 1024
|
||||||
|
|
||||||
|
static int primTypeMap[] = {
|
||||||
|
D3DPT_POINTLIST, // invalid
|
||||||
|
D3DPT_LINELIST,
|
||||||
|
D3DPT_LINESTRIP,
|
||||||
|
D3DPT_TRIANGLELIST,
|
||||||
|
D3DPT_TRIANGLESTRIP,
|
||||||
|
D3DPT_TRIANGLEFAN,
|
||||||
|
D3DPT_POINTLIST, // actually not supported!
|
||||||
|
};
|
||||||
|
// end of stolen stuff
|
||||||
|
|
||||||
|
|
||||||
|
static IDirect3DVertexDeclaration9 *im2ddecl_uv2;
|
||||||
|
static IDirect3DVertexBuffer9 *im2dvertbuf_uv2;
|
||||||
|
static IDirect3DIndexBuffer9 *im2dindbuf_uv2;
|
||||||
|
|
||||||
|
void
|
||||||
|
openim2d_uv2(void)
|
||||||
|
{
|
||||||
|
using namespace rw;
|
||||||
|
using namespace d3d;
|
||||||
|
D3DVERTEXELEMENT9 elements[5] = {
|
||||||
|
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
|
||||||
|
{ 0, offsetof(Im2DVertexUV2, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
|
||||||
|
{ 0, offsetof(Im2DVertexUV2, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||||
|
{ 0, offsetof(Im2DVertexUV2, u2), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
|
||||||
|
D3DDECL_END()
|
||||||
|
};
|
||||||
|
assert(im2ddecl_uv2 == nil);
|
||||||
|
im2ddecl_uv2 = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements);
|
||||||
|
assert(im2ddecl_uv2);
|
||||||
|
|
||||||
|
assert(im2dvertbuf_uv2 == nil);
|
||||||
|
im2dvertbuf_uv2 = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertexUV2), 0, true);
|
||||||
|
assert(im2dvertbuf_uv2);
|
||||||
|
addDynamicVB(NUMVERTICES*sizeof(Im2DVertexUV2), 0, &im2dvertbuf_uv2);
|
||||||
|
|
||||||
|
assert(im2dindbuf_uv2 == nil);
|
||||||
|
im2dindbuf_uv2 = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(rw::uint16), true);
|
||||||
|
assert(im2dindbuf_uv2);
|
||||||
|
addDynamicIB(NUMINDICES*sizeof(rw::uint16), &im2dindbuf_uv2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
closeim2d_uv2(void)
|
||||||
|
{
|
||||||
|
using namespace rw;
|
||||||
|
using namespace d3d;
|
||||||
|
|
||||||
|
d3d9::destroyVertexDeclaration(im2ddecl_uv2);
|
||||||
|
im2ddecl_uv2 = nil;
|
||||||
|
|
||||||
|
removeDynamicVB(&im2dvertbuf_uv2);
|
||||||
|
destroyVertexBuffer(im2dvertbuf_uv2);
|
||||||
|
im2dvertbuf_uv2 = nil;
|
||||||
|
|
||||||
|
removeDynamicIB(&im2dindbuf_uv2);
|
||||||
|
destroyIndexBuffer(im2dindbuf_uv2);
|
||||||
|
im2dindbuf_uv2 = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
|
||||||
|
{
|
||||||
|
using namespace rw;
|
||||||
|
using namespace d3d;
|
||||||
|
|
||||||
|
if(numVertices > NUMVERTICES ||
|
||||||
|
numIndices > NUMINDICES){
|
||||||
|
// TODO: error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rw::uint16 *lockedindices = lockIndices(im2dindbuf_uv2, 0, numIndices*sizeof(rw::uint16), D3DLOCK_DISCARD);
|
||||||
|
memcpy(lockedindices, indices, numIndices*sizeof(rw::uint16));
|
||||||
|
unlockIndices(im2dindbuf_uv2);
|
||||||
|
|
||||||
|
rw::uint8 *lockedvertices = lockVertices(im2dvertbuf_uv2, 0, numVertices*sizeof(Im2DVertexUV2), D3DLOCK_DISCARD);
|
||||||
|
memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertexUV2));
|
||||||
|
unlockVertices(im2dvertbuf_uv2);
|
||||||
|
|
||||||
|
setStreamSource(0, im2dvertbuf_uv2, 0, sizeof(Im2DVertexUV2));
|
||||||
|
setIndices(im2dindbuf_uv2);
|
||||||
|
setVertexDeclaration(im2ddecl_uv2);
|
||||||
|
|
||||||
|
if(im2dOverridePS)
|
||||||
|
setPixelShader(im2dOverridePS);
|
||||||
|
else if(engine->device.getRenderState(TEXTURERASTER))
|
||||||
|
setPixelShader(im2d_tex_PS);
|
||||||
|
else
|
||||||
|
setPixelShader(im2d_PS);
|
||||||
|
|
||||||
|
d3d::flushCache();
|
||||||
|
|
||||||
|
rw::uint32 primCount = 0;
|
||||||
|
switch(primType){
|
||||||
|
case PRIMTYPELINELIST:
|
||||||
|
primCount = numIndices/2;
|
||||||
|
break;
|
||||||
|
case PRIMTYPEPOLYLINE:
|
||||||
|
primCount = numIndices-1;
|
||||||
|
break;
|
||||||
|
case PRIMTYPETRILIST:
|
||||||
|
primCount = numIndices/3;
|
||||||
|
break;
|
||||||
|
case PRIMTYPETRISTRIP:
|
||||||
|
primCount = numIndices-2;
|
||||||
|
break;
|
||||||
|
case PRIMTYPETRIFAN:
|
||||||
|
primCount = numIndices-2;
|
||||||
|
break;
|
||||||
|
case PRIMTYPEPOINTLIST:
|
||||||
|
primCount = numIndices;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
|
||||||
|
0, numVertices,
|
||||||
|
0, primCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RW_GL3
|
||||||
|
// different than im2d
|
||||||
|
#define NUMINDICES 1024
|
||||||
|
#define NUMVERTICES 1024
|
||||||
|
|
||||||
|
static rw::gl3::AttribDesc im2d_UV2_attribDesc[4] = {
|
||||||
|
{ rw::gl3::ATTRIB_POS, GL_FLOAT, GL_FALSE, 4,
|
||||||
|
sizeof(Im2DVertexUV2), 0 },
|
||||||
|
{ rw::gl3::ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
||||||
|
sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, r) },
|
||||||
|
{ rw::gl3::ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
||||||
|
sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, u) },
|
||||||
|
{ rw::gl3::ATTRIB_TEXCOORDS1, GL_FLOAT, GL_FALSE, 2,
|
||||||
|
sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, u2) }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int primTypeMap[] = {
|
||||||
|
GL_POINTS, // invalid
|
||||||
|
GL_LINES,
|
||||||
|
GL_LINE_STRIP,
|
||||||
|
GL_TRIANGLES,
|
||||||
|
GL_TRIANGLE_STRIP,
|
||||||
|
GL_TRIANGLE_FAN,
|
||||||
|
GL_POINTS
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32 u_xform;
|
||||||
|
|
||||||
|
uint32 im2D_UV2_Vbo, im2D_UV2_Ibo;
|
||||||
|
#ifdef RW_GL_USE_VAOS
|
||||||
|
uint32 im2D_UV2_Vao;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
openim2d_uv2(void)
|
||||||
|
{
|
||||||
|
u_xform = rw::gl3::registerUniform("u_xform"); // this doesn't add a new one, so it's safe
|
||||||
|
|
||||||
|
glGenBuffers(1, &im2D_UV2_Ibo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMINDICES*2, nil, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
glGenBuffers(1, &im2D_UV2_Vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, im2D_UV2_Vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, NUMVERTICES*sizeof(Im2DVertexUV2), nil, GL_STREAM_DRAW);
|
||||||
|
|
||||||
|
#ifdef RW_GL_USE_VAOS
|
||||||
|
glGenVertexArrays(1, &im2D_UV2_Vao);
|
||||||
|
glBindVertexArray(im2D_UV2_Vao);
|
||||||
|
setAttribPointers(im2d_UV2_attribDesc, 4);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
closeim2d_uv2(void)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &im2D_UV2_Ibo);
|
||||||
|
glDeleteBuffers(1, &im2D_UV2_Vbo);
|
||||||
|
#ifdef RW_GL_USE_VAOS
|
||||||
|
glDeleteVertexArrays(1, &im2D_UV2_Vao);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
|
||||||
|
{
|
||||||
|
using namespace rw;
|
||||||
|
using namespace gl3;
|
||||||
|
|
||||||
|
GLfloat xform[4];
|
||||||
|
Camera *cam;
|
||||||
|
cam = (Camera*)engine->currentCamera;
|
||||||
|
|
||||||
|
#ifdef RW_GL_USE_VAOS
|
||||||
|
glBindVertexArray(im2D_UV2_Vao);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMINDICES*2, nil, GL_STREAM_DRAW);
|
||||||
|
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, im2D_UV2_Vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, NUMVERTICES*sizeof(Im2DVertexUV2), nil, GL_STREAM_DRAW);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertexUV2), vertices);
|
||||||
|
|
||||||
|
xform[0] = 2.0f/cam->frameBuffer->width;
|
||||||
|
xform[1] = -2.0f/cam->frameBuffer->height;
|
||||||
|
xform[2] = -1.0f;
|
||||||
|
xform[3] = 1.0f;
|
||||||
|
|
||||||
|
if(im2dOverrideShader)
|
||||||
|
im2dOverrideShader->use();
|
||||||
|
else
|
||||||
|
assert(0);//im2dShader->use();
|
||||||
|
#ifndef RW_GL_USE_VAOS
|
||||||
|
setAttribPointers(im2d_UV2_attribDesc, 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
||||||
|
|
||||||
|
flushCache();
|
||||||
|
glDrawElements(primTypeMap[primType], numIndices,
|
||||||
|
GL_UNSIGNED_SHORT, nil);
|
||||||
|
#ifndef RW_GL_USE_VAOS
|
||||||
|
disableAttribPointers(im2d_UV2_attribDesc, 4);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
78
src/extras/screendroplets.h
Normal file
78
src/extras/screendroplets.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
|
||||||
|
class CParticleObject;
|
||||||
|
|
||||||
|
class ScreenDroplets
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
MAXDROPS = 2000,
|
||||||
|
MAXDROPSMOVING = 700
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScreenDrop
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float x, y, time; // shorts on xbox (short float?)
|
||||||
|
float size, magnification, lifetime; // "
|
||||||
|
CRGBA color;
|
||||||
|
bool active;
|
||||||
|
bool fades;
|
||||||
|
|
||||||
|
void Fade(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScreenDropMoving
|
||||||
|
{
|
||||||
|
ScreenDrop *drop;
|
||||||
|
float dist;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ms_initialised;
|
||||||
|
static RwTexture *ms_maskTex;
|
||||||
|
static RwTexture *ms_screenTex;
|
||||||
|
|
||||||
|
static bool ms_enabled;
|
||||||
|
static bool ms_movingEnabled;
|
||||||
|
|
||||||
|
static ScreenDrop ms_drops[MAXDROPS];
|
||||||
|
static int ms_numDrops;
|
||||||
|
static ScreenDropMoving ms_dropsMoving[MAXDROPSMOVING];
|
||||||
|
static int ms_numDropsMoving;
|
||||||
|
|
||||||
|
static CVector ms_prevCamUp;
|
||||||
|
static CVector ms_prevCamPos;
|
||||||
|
static CVector ms_camMoveDelta;
|
||||||
|
static float ms_camMoveDist;
|
||||||
|
static CVector ms_screenMoveDelta;
|
||||||
|
static float ms_screenMoveDist;
|
||||||
|
static float ms_camUpAngle;
|
||||||
|
|
||||||
|
static int ms_splashDuration;
|
||||||
|
static CParticleObject *ms_splashObject;
|
||||||
|
|
||||||
|
static void Initialise(void);
|
||||||
|
static void InitDraw(void);
|
||||||
|
static void Shutdown(void);
|
||||||
|
static void Process(void);
|
||||||
|
static void Render(void);
|
||||||
|
static void AddToRenderList(ScreenDrop *drop);
|
||||||
|
|
||||||
|
static void Clear(void);
|
||||||
|
static ScreenDrop *NewDrop(float x, float y, float size, float lifetime, bool fades, int r = 255, int g = 255, int b = 255);
|
||||||
|
static void SetMoving(ScreenDroplets::ScreenDrop *drop);
|
||||||
|
static void FillScreen(int n);
|
||||||
|
static void FillScreenMoving(float amount, bool isBlood = false);
|
||||||
|
static void RegisterSplash(CParticleObject *pobj);
|
||||||
|
|
||||||
|
static void ProcessCameraMovement(void);
|
||||||
|
static void SprayDrops(void);
|
||||||
|
static void NewTrace(ScreenDroplets::ScreenDropMoving *moving);
|
||||||
|
static void MoveDrop(ScreenDropMoving *moving);
|
||||||
|
static void ProcessMoving(void);
|
||||||
|
static void Fade(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -65,3 +65,13 @@ neoVehicle_fs_gl.inc: neoVehicle.frag
|
||||||
(echo 'const char *neoVehicle_frag_src =';\
|
(echo 'const char *neoVehicle_frag_src =';\
|
||||||
sed 's/..*/"&\\n"/' neoVehicle.frag;\
|
sed 's/..*/"&\\n"/' neoVehicle.frag;\
|
||||||
echo ';') >neoVehicle_fs_gl.inc
|
echo ';') >neoVehicle_fs_gl.inc
|
||||||
|
|
||||||
|
im2d_UV2_gl.inc: im2d_UV2.vert
|
||||||
|
(echo 'const char *im2d_UV2_vert_src =';\
|
||||||
|
sed 's/..*/"&\\n"/' im2d_UV2.vert;\
|
||||||
|
echo ';') >im2d_UV2_gl.inc
|
||||||
|
|
||||||
|
screenDroplet_fs_gl.inc: screenDroplet.frag
|
||||||
|
(echo 'const char *screenDroplet_frag_src =';\
|
||||||
|
sed 's/..*/"&\\n"/' screenDroplet.frag;\
|
||||||
|
echo ';') >screenDroplet_fs_gl.inc
|
||||||
|
|
21
src/extras/shaders/im2d_UV2.vert
Normal file
21
src/extras/shaders/im2d_UV2.vert
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
uniform vec4 u_xform;
|
||||||
|
|
||||||
|
VSIN(ATTRIB_POS) vec4 in_pos;
|
||||||
|
|
||||||
|
VSOUT vec4 v_color;
|
||||||
|
VSOUT vec2 v_tex0;
|
||||||
|
VSOUT vec2 v_tex1;
|
||||||
|
VSOUT float v_fog;
|
||||||
|
|
||||||
|
void
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
gl_Position = in_pos;
|
||||||
|
gl_Position.w = 1.0;
|
||||||
|
gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
|
||||||
|
v_fog = DoFog(gl_Position.z);
|
||||||
|
gl_Position.xyz *= gl_Position.w;
|
||||||
|
v_color = in_color;
|
||||||
|
v_tex0 = in_tex0;
|
||||||
|
v_tex1 = in_tex1;
|
||||||
|
}
|
18
src/extras/shaders/screenDroplet.frag
Normal file
18
src/extras/shaders/screenDroplet.frag
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
uniform sampler2D tex0;
|
||||||
|
uniform sampler2D tex1;
|
||||||
|
|
||||||
|
FSIN vec4 v_color;
|
||||||
|
FSIN vec2 v_tex0;
|
||||||
|
FSIN vec2 v_tex1;
|
||||||
|
FSIN float v_fog;
|
||||||
|
|
||||||
|
void
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
vec4 color;
|
||||||
|
color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
|
||||||
|
color *= texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));
|
||||||
|
|
||||||
|
FRAGCOLOR(color);
|
||||||
|
}
|
||||||
|
|
BIN
src/extras/shaders/screenDroplet_PS.cso
Normal file
BIN
src/extras/shaders/screenDroplet_PS.cso
Normal file
Binary file not shown.
17
src/extras/shaders/screenDroplet_PS.hlsl
Normal file
17
src/extras/shaders/screenDroplet_PS.hlsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
struct VS_out {
|
||||||
|
float4 Position : POSITION;
|
||||||
|
float2 TexCoord0 : TEXCOORD0;
|
||||||
|
float2 TexCoord1 : TEXCOORD1;
|
||||||
|
float4 Color : COLOR0;
|
||||||
|
};
|
||||||
|
|
||||||
|
sampler2D tex0 : register(s0);
|
||||||
|
sampler2D tex1 : register(s1);
|
||||||
|
|
||||||
|
float4 main(VS_out input) : COLOR
|
||||||
|
{
|
||||||
|
float4 color = input.Color;
|
||||||
|
color *= tex2D(tex0, input.TexCoord0.xy);
|
||||||
|
color *= tex2D(tex1, input.TexCoord1.xy);
|
||||||
|
return color;
|
||||||
|
}
|
29
src/extras/shaders/screenDroplet_PS.inc
Normal file
29
src/extras/shaders/screenDroplet_PS.inc
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
static unsigned char screenDroplet_PS_cso[] = {
|
||||||
|
0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2c, 0x00, 0x43, 0x54, 0x41, 0x42,
|
||||||
|
0x1c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x74, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0x00,
|
||||||
|
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x30,
|
||||||
|
0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x31,
|
||||||
|
0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32,
|
||||||
|
0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
|
||||||
|
0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68,
|
||||||
|
0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
|
||||||
|
0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33,
|
||||||
|
0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
|
||||||
|
0x00, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
|
||||||
|
0x01, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
|
||||||
|
0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
|
||||||
|
0x00, 0x08, 0x0f, 0xa0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
|
||||||
|
0x01, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
|
||||||
|
0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0, 0x42, 0x00, 0x00, 0x03,
|
||||||
|
0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0xb0, 0x01, 0x08, 0xe4, 0xa0,
|
||||||
|
0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80,
|
||||||
|
0x00, 0x00, 0xe4, 0x90, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
|
||||||
|
0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
|
||||||
|
0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
|
||||||
|
};
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "DMAudio.h"
|
#include "DMAudio.h"
|
||||||
|
#include "screendroplets.h"
|
||||||
|
|
||||||
|
|
||||||
CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
|
CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
|
||||||
|
@ -18,6 +19,8 @@ CParticleObject *CParticleObject::pUnusedListHead;
|
||||||
|
|
||||||
CAudioHydrant List[MAX_AUDIOHYDRANTS];
|
CAudioHydrant List[MAX_AUDIOHYDRANTS];
|
||||||
|
|
||||||
|
CAudioHydrant *CAudioHydrant::Get(int n) { return &List[n]; }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CAudioHydrant::Add(CParticleObject *particleobject)
|
CAudioHydrant::Add(CParticleObject *particleobject)
|
||||||
{
|
{
|
||||||
|
@ -246,6 +249,9 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
|
||||||
pobj->m_nNumEffectCycles = 0;
|
pobj->m_nNumEffectCycles = 0;
|
||||||
pobj->m_nSkipFrames = 1;
|
pobj->m_nSkipFrames = 1;
|
||||||
pobj->m_nCreationChance = 0;
|
pobj->m_nCreationChance = 0;
|
||||||
|
#ifdef SCREEN_DROPLETS
|
||||||
|
ScreenDroplets::RegisterSplash(pobj);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,4 +107,6 @@ public:
|
||||||
|
|
||||||
static bool Add (CParticleObject *particleobject);
|
static bool Add (CParticleObject *particleobject);
|
||||||
static void Remove(CParticleObject *particleobject);
|
static void Remove(CParticleObject *particleobject);
|
||||||
|
|
||||||
|
static CAudioHydrant *Get(int n); // for neo screen droplets
|
||||||
};
|
};
|
Loading…
Reference in a new issue