1
0
Fork 0
mirror of https://github.com/halpz/re3.git synced 2024-12-25 18:05:27 +00:00

CWindModifiers

This commit is contained in:
majestic 2020-08-09 12:54:00 -07:00
commit 70029752f5
69 changed files with 6544 additions and 1001 deletions

67
.github/workflows/reVC_msvc_amd64.yml vendored Normal file
View file

@ -0,0 +1,67 @@
name: reVC_msvc_amd64
on:
pull_request:
push:
release:
types: published
env:
GLEW_VER: "2.1.0"
GLFW_VER: "3.3.2"
GLEW_BASE: "glew-2.1.0"
GLFW_BASE: "glfw-3.3.2.bin.WIN64"
GLEW_FILE: "glew-2.1.0-win32.zip"
GLFW_FILE: "glfw-3.3.2.bin.WIN64.zip"
GLEW_URL: "https://github.com/nigels-com/glew/releases/download/glew-2.1.0/glew-2.1.0-win32.zip"
GLFW_URL: "https://github.com/glfw/glfw/releases/download/3.3.2/glfw-3.3.2.bin.WIN64.zip"
jobs:
build:
runs-on: windows-2019
strategy:
matrix:
platform: [win-amd64-librw_d3d9-oal, win-amd64-librw_gl3_glfw-oal]
buildtype: [Debug, Release]
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1
- uses: actions/checkout@v2
with:
submodules: 'true'
- if: ${{ matrix.platform }} == "win-amd64-librw_gl3_glfw-mss"
name: Download glew
uses: carlosperate/download-file-action@v1.0.3
with:
file-url: ${{env.GLEW_URL}}
- if: ${{ matrix.platform }} == "win-amd64-librw_gl3_glfw-mss"
name: Download glfw
uses: carlosperate/download-file-action@v1.0.3
with:
file-url: ${{env.GLFW_URL}}
- if: ${{ matrix.platform }} == "win-amd64-librw_gl3_glfw-mss"
name: Unpack archives
run: |
7z x ${{env.GLEW_FILE}}
7z x ${{env.GLFW_FILE}}
- name: Configure build
run: |
./premake5 vs2019 --with-librw --glewdir=${{env.GLEW_BASE}} --glfwdir64=${{env.GLFW_BASE}}
- name: Build
run: |
msbuild -m build/reVC.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}
- name: Pack artifacts
run: |
7z a reVC_${{matrix.buildtype}}_${{matrix.platform}}.zip ./bin/${{matrix.platform}}/${{matrix.buildtype}}/*
- name: Upload artifact to actions
uses: actions/upload-artifact@v2
with:
name: reVC_${{matrix.buildtype}}_${{matrix.platform}}
path: ./bin/${{matrix.platform}}/${{matrix.buildtype}}
# - name: Upload artifact to Bintray
# uses: hpcsc/upload-bintray-docker-action@v1
# with:
# repository: reVC
# package: ${{matrix.buildtype}}_${{matrix.platform}}
# version: 1.0-$(echo ${GITHUB_SHA}
# sourcePath: ./bin/${{matrix.platform}}/${{matrix.buildtype}}
# username: gtamodding
# apiKey: ${{secrets.BINTRAY_API_KEY}}

68
.github/workflows/reVC_msvc_x86.yml vendored Normal file
View file

@ -0,0 +1,68 @@
name: reVC_msvc_x86
on:
pull_request:
push:
release:
types: published
env:
GLEW_VER: "2.1.0"
GLFW_VER: "3.3.2"
GLEW_BASE: "glew-2.1.0"
GLFW_BASE: "glfw-3.3.2.bin.WIN32"
GLEW_FILE: "glew-2.1.0-win32.zip"
GLFW_FILE: "glfw-3.3.2.bin.WIN32.zip"
GLEW_URL: "https://github.com/nigels-com/glew/releases/download/glew-2.1.0/glew-2.1.0-win32.zip"
GLFW_URL: "https://github.com/glfw/glfw/releases/download/3.3.2/glfw-3.3.2.bin.WIN32.zip"
jobs:
build:
runs-on: windows-2019
strategy:
matrix:
platform: [win-x86-librw_d3d9-mss, win-x86-librw_gl3_glfw-mss, win-x86-librw_d3d9-oal, win-x86-librw_gl3_glfw-oal]
buildtype: [Debug, Release]
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1
- uses: actions/checkout@v2
with:
submodules: 'true'
- if: ${{ matrix.platform }} == "win-x86-librw_gl3_glfw-mss"
name: Download glew
uses: carlosperate/download-file-action@v1.0.3
with:
file-url: ${{env.GLEW_URL}}
- if: ${{ matrix.platform }} == "win-x86-librw_gl3_glfw-mss"
name: Download glfw
uses: carlosperate/download-file-action@v1.0.3
with:
file-url: ${{env.GLFW_URL}}
- if: ${{ matrix.platform }} == "win-x86-librw_gl3_glfw-mss"
name: Unpack archives
run: |
7z x ${{env.GLEW_FILE}}
7z x ${{env.GLFW_FILE}}
- name: Configure build
run: |
./premake5 vs2019 --with-librw --glewdir=${{env.GLEW_BASE}} --glfwdir32=${{env.GLFW_BASE}}
- name: Build
run: |
msbuild -m build/reVC.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}
- name: Pack artifacts
run: |
7z a reVC_${{matrix.buildtype}}_${{matrix.platform}}.zip ./bin/${{matrix.platform}}/${{matrix.buildtype}}/*
- name: Upload artifact to actions
uses: actions/upload-artifact@v2
with:
name: reVC_${{matrix.buildtype}}_${{matrix.platform}}
path: reVC_${{matrix.buildtype}}_${{matrix.platform}}.zip
# - name: Upload artifact to Bintray
# uses: hpcsc/upload-bintray-docker-action@v1
# with:
# repository: reVC
# package: ${{matrix.buildtype}}_${{matrix.platform}}
# version: 1.0-$(echo ${GITHUB_SHA}
# sourcePath: ./bin/${{matrix.platform}}/${{matrix.buildtype}}
# username: gtamodding
# apiKey: ${{secrets.BINTRAY_API_KEY}}

BIN
mpg123.32/dist/libmpg123-0.dll vendored Normal file

Binary file not shown.

Binary file not shown.

159
mpg123.32/include/fmt123.h Normal file
View file

@ -0,0 +1,159 @@
/*
libmpg123: MPEG Audio Decoder library
separate header just for audio format definitions not tied to
library code
copyright 1995-2020 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
#ifndef MPG123_ENC_H
#define MPG123_ENC_H
/** \file fmt123.h Audio format definitions. */
/** \defgroup mpg123_enc mpg123 PCM sample encodings
* These are definitions for audio formats used by libmpg123 and
* libout123.
*
* @{
*/
/** An enum over all sample types possibly known to mpg123.
* The values are designed as bit flags to allow bitmasking for encoding
* families.
* This is also why the enum is not used as type for actual encoding variables,
* plain integers (at least 16 bit, 15 bit being used) cover the possible
* combinations of these flags.
*
* Note that (your build of) libmpg123 does not necessarily support all these.
* Usually, you can expect the 8bit encodings and signed 16 bit.
* Also 32bit float will be usual beginning with mpg123-1.7.0 .
* What you should bear in mind is that (SSE, etc) optimized routines may be
* absent for some formats. We do have SSE for 16, 32 bit and float, though.
* 24 bit integer is done via postprocessing of 32 bit output -- just cutting
* the last byte, no rounding, even. If you want better, do it yourself.
*
* All formats are in native byte order. If you need different endinaness, you
* can simply postprocess the output buffers (libmpg123 wouldn't do anything
* else). The macro MPG123_SAMPLESIZE() can be helpful there.
*/
enum mpg123_enc_enum
{
/* 0000 0000 0000 1111 Some 8 bit integer encoding. */
MPG123_ENC_8 = 0x00f
/* 0000 0000 0100 0000 Some 16 bit integer encoding. */
, MPG123_ENC_16 = 0x040
/* 0100 0000 0000 0000 Some 24 bit integer encoding. */
, MPG123_ENC_24 = 0x4000
/* 0000 0001 0000 0000 Some 32 bit integer encoding. */
, MPG123_ENC_32 = 0x100
/* 0000 0000 1000 0000 Some signed integer encoding. */
, MPG123_ENC_SIGNED = 0x080
/* 0000 1110 0000 0000 Some float encoding. */
, MPG123_ENC_FLOAT = 0xe00
/* 0000 0000 1101 0000 signed 16 bit */
, MPG123_ENC_SIGNED_16 = (MPG123_ENC_16|MPG123_ENC_SIGNED|0x10)
/* 0000 0000 0110 0000 unsigned 16 bit */
, MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16|0x20)
/* 0000 0000 0000 0001 unsigned 8 bit */
, MPG123_ENC_UNSIGNED_8 = 0x01
/* 0000 0000 1000 0010 signed 8 bit */
, MPG123_ENC_SIGNED_8 = (MPG123_ENC_SIGNED|0x02)
/* 0000 0000 0000 0100 ulaw 8 bit */
, MPG123_ENC_ULAW_8 = 0x04
/* 0000 0000 0000 1000 alaw 8 bit */
, MPG123_ENC_ALAW_8 = 0x08
/* 0001 0001 1000 0000 signed 32 bit */
, MPG123_ENC_SIGNED_32 = MPG123_ENC_32|MPG123_ENC_SIGNED|0x1000
/* 0010 0001 0000 0000 unsigned 32 bit */
, MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32|0x2000
/* 0101 0000 1000 0000 signed 24 bit */
, MPG123_ENC_SIGNED_24 = MPG123_ENC_24|MPG123_ENC_SIGNED|0x1000
/* 0110 0000 0000 0000 unsigned 24 bit */
, MPG123_ENC_UNSIGNED_24 = MPG123_ENC_24|0x2000
/* 0000 0010 0000 0000 32bit float */
, MPG123_ENC_FLOAT_32 = 0x200
/* 0000 0100 0000 0000 64bit float */
, MPG123_ENC_FLOAT_64 = 0x400
/* Any possibly known encoding from the list above. */
, MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 | MPG123_ENC_UNSIGNED_16
| MPG123_ENC_UNSIGNED_8 | MPG123_ENC_SIGNED_8
| MPG123_ENC_ULAW_8 | MPG123_ENC_ALAW_8
| MPG123_ENC_SIGNED_32 | MPG123_ENC_UNSIGNED_32
| MPG123_ENC_SIGNED_24 | MPG123_ENC_UNSIGNED_24
| MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 )
};
/** Get size of one PCM sample with given encoding.
* This is included both in libmpg123 and libout123. Both offer
* an API function to provide the macro results from library
* compile-time, not that of you application. This most likely
* does not matter as I do not expect any fresh PCM sample
* encoding to appear. But who knows? Perhaps the encoding type
* will be abused for funny things in future, not even plain PCM.
* And, by the way: Thomas really likes the ?: operator.
* \param enc the encoding (mpg123_enc_enum value)
* \return size of one sample in bytes
*/
#define MPG123_SAMPLESIZE(enc) ( \
(enc) < 1 \
? 0 \
: ( (enc) & MPG123_ENC_8 \
? 1 \
: ( (enc) & MPG123_ENC_16 \
? 2 \
: ( (enc) & MPG123_ENC_24 \
? 3 \
: ( ( (enc) & MPG123_ENC_32 \
|| (enc) == MPG123_ENC_FLOAT_32 ) \
? 4 \
: ( (enc) == MPG123_ENC_FLOAT_64 \
? 8 \
: 0 \
) ) ) ) ) )
/** Representation of zero in differing encodings.
* This exists to define proper silence in various encodings without
* having to link to libsyn123 to do actual conversions at runtime.
* You have to handle big/little endian order yourself, though.
* This takes the shortcut that any signed encoding has a zero with
* all-zero bits. Unsigned linear encodings just have the highest bit set
* (2^(n-1) for n bits), while the nonlinear 8-bit ones are special.
* \param enc the encoding (mpg123_enc_enum value)
* \param siz bytes per sample (return value of MPG123_SAMPLESIZE(enc))
* \param off byte (octet) offset counted from LSB
* \return unsigned byte value for the designated octet
*/
#define MPG123_ZEROSAMPLE(enc, siz, off) ( \
(enc) == MPG123_ENC_ULAW_8 \
? (off == 0 ? 0xff : 0x00) \
: ( (enc) == MPG123_ENC_ALAW_8 \
? (off == 0 ? 0xd5 : 0x00) \
: ( (((enc) & (MPG123_ENC_SIGNED|MPG123_ENC_FLOAT)) || (siz) != ((off)+1)) \
? 0x00 \
: 0x80 \
) ) )
/** Structure defining an audio format.
* Providing the members as individual function arguments to define a certain
* output format is easy enough. This struct makes is more comfortable to deal
* with a list of formats.
* Negative values for the members might be used to communicate use of default
* values.
*/
struct mpg123_fmt
{
long rate; /**< sampling rate in Hz */
int channels; /**< channel count */
/** encoding code, can be single value or bitwise or of members of
* mpg123_enc_enum */
int encoding;
};
/* @} */
#endif

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

View file

@ -8,13 +8,8 @@
#include <opusfile.h>
#else
#ifdef _WIN32
// TODO: This is due to version difference of 32-bit libmpg123 and 64-bit libmpg123, fix it
#ifndef _WIN64
typedef long ssize_t;
#endif
#pragma comment( lib, "libsndfile-1.lib" )
#pragma comment( lib, "libmpg123.lib" )
#pragma comment( lib, "libmpg123-0.lib" )
#else
#include "crossplatform.h"
#endif

View file

@ -111,6 +111,10 @@ CRoadBlocks::GenerateRoadBlocks(void)
{
CMatrix tmp1, tmp2;
static int16 unk;
#ifdef SQUEEZE_PERFORMANCE
if (FindPlayerPed()->m_pWanted->m_RoadblockDensity == 0)
return;
#endif
uint32 frame = CTimer::GetFrameCounter() & 0xF;
int16 nRoadblockNode = (int16)(NUMROADBLOCKS * frame) / 16;
const int16 maxRoadBlocks = (int16)(NUMROADBLOCKS * (frame + 1)) / 16;

View file

@ -12709,13 +12709,13 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
case COMMAND_SET_EXTRA_COLOURS:
{
CollectParameters(&m_nIp, 2);
debug("SET_EXTRA_COLOURS not implemented, skipping\n");
CTimeCycle::StartExtraColour(ScriptParams[0]-1, ScriptParams[1] != 0);
return 0;
}
case COMMAND_CLEAR_EXTRA_COLOURS:
{
CollectParameters(&m_nIp, 1);
debug("CLEAR_EXTRA_COLOURS not implemented, skipping\n");
CTimeCycle::StopExtraColour(ScriptParams[0]);
return 0;
}
//case COMMAND_CLOSE_CAR_BOOT:

View file

@ -53,6 +53,10 @@ CAccidentManager::ReportAccident(CPed *ped)
void
CAccidentManager::Update()
{
#ifdef SQUEEZE_PERFORMANCE
// Handled after injury registered.
return;
#endif
int32 e;
if (CEventList::GetEvent(EVENT_INJURED_PED, &e)) {
CPed *ped = CPools::GetPed(gaEvent[e].entityRef);

View file

@ -1,5 +1,4 @@
#pragma once
#include "common.h"
#include "config.h"
class CPed;

View file

@ -3958,7 +3958,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
128, 128, 128, 128, 1000.0f, false, 1.0f);
128, 128, 128, 128, 1000.0f, false, 1.0f, nil, false);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];
@ -4103,7 +4103,7 @@ CCam::Process_Editor(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
128, 128, 128, 128, 1000.0f, false, 1.0f);
128, 128, 128, 128, 1000.0f, false, 1.0f, nil, false);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,12 @@
#include "templates.h"
#include "Game.h" // for eLevelName
#ifdef VU_COLLISION
#include "VuVector.h"
#endif
// If you spawn many tanks at once, you will see that collisions of two entity exceeds 32.
#ifdef FIX_BUGS
#if defined(FIX_BUGS) && !defined(SQUEEZE_PERFORMANCE)
#define MAX_COLLISION_POINTS 64
#else
#define MAX_COLLISION_POINTS 32
@ -16,6 +19,28 @@ struct CompressedVector
int16 x, y, z;
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
#ifdef GTA_PS2
void Unpack(uint128 &qword) const {
__asm__ volatile (
"lh $8, 0(%1)\n"
"lh $9, 2(%1)\n"
"lh $10, 4(%1)\n"
"pextlw $10, $8\n"
"pextlw $2, $9, $10\n"
"sq $2, %0\n"
: "=m" (qword)
: "r" (this)
: "$8", "$9", "$10", "$2"
);
}
#else
void Unpack(int32 *qword) const {
qword[0] = x;
qword[1] = y;
qword[2] = z;
qword[3] = 0; // junk
}
#endif
#else
float x, y, z;
CVector Get(void) const { return CVector(x, y, z); };
@ -25,6 +50,7 @@ struct CompressedVector
struct CSphere
{
// NB: this has to be compatible with a CVuVector
CVector center;
float radius;
void Set(float radius, const CVector &center) { this->center = center; this->radius = radius; }
@ -59,6 +85,7 @@ struct CColBox : public CBox
struct CColLine
{
// NB: this has to be compatible with two CVuVectors
CVector p0;
int pad0;
CVector p1;
@ -81,6 +108,39 @@ struct CColTriangle
struct CColTrianglePlane
{
#ifdef VU_COLLISION
CompressedVector normal;
int16 dist;
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n.x = normal.x/4096.0f; n.y = normal.y/4096.0f; n.z = normal.z/4096.0f; }
float CalcPoint(const CVector &v) const { CVector n; GetNormal(n); return DotProduct(n, v) - dist/128.0f; };
#ifdef GTA_PS2
void Unpack(uint128 &qword) const {
__asm__ volatile (
"lh $8, 0(%1)\n"
"lh $9, 2(%1)\n"
"lh $10, 4(%1)\n"
"lh $11, 6(%1)\n"
"pextlw $10, $8\n"
"pextlw $11, $9\n"
"pextlw $2, $11, $10\n"
"sq $2, %0\n"
: "=m" (qword)
: "r" (this)
: "$8", "$9", "$10", "$11", "$2"
);
}
#else
void Unpack(int32 *qword) const {
qword[0] = normal.x;
qword[1] = normal.y;
qword[2] = normal.z;
qword[3] = dist;
}
#endif
#else
CVector normal;
float dist;
uint8 dir;
@ -88,7 +148,11 @@ struct CColTrianglePlane
void Set(const CVector &va, const CVector &vb, const CVector &vc);
void Set(const CompressedVector *v, CColTriangle &tri) { Set(v[tri.a].Get(), v[tri.b].Get(), v[tri.c].Get()); }
void GetNormal(CVector &n) const { n = normal; }
float GetNormalX() const { return normal.x; }
float GetNormalY() const { return normal.y; }
float GetNormalZ() const { return normal.z; }
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
#endif
};
struct CColPoint
@ -109,7 +173,11 @@ struct CColPoint
struct CStoredCollPoly
{
#ifdef VU_COLLISION
CVuVector verts[3];
#else
CVector verts[3];
#endif
bool valid;
};

View file

@ -8,6 +8,7 @@
#include "Messages.h"
#include "Text.h"
#include "main.h"
#include "Accident.h"
int32 CEventList::ms_nFirstFreeSlotIndex;
CEvent gaEvent[NUMEVENTS];
@ -63,6 +64,13 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent
int ref;
bool copsDontCare;
#ifdef SQUEEZE_PERFORMANCE
if (type == EVENT_INJURED_PED) {
gAccidentManager.ReportAccident((CPed*)ent);
return;
}
#endif
copsDontCare = false;
switch(entityType){
case EVENT_ENTITY_PED:

View file

@ -110,6 +110,7 @@ int gameTxdSlot;
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
#ifdef PS2_MENU
void MessageScreen(char *msg)
{
//TODO: stretch_screen
@ -143,6 +144,7 @@ void MessageScreen(char *msg)
DoRWStuffEndOfFrame();
}
#endif
bool
CGame::InitialiseOnceBeforeRW(void)

View file

@ -61,6 +61,7 @@ int32 CStats::FastestTimes[CStats::TOTAL_FASTEST_TIMES];
int32 CStats::HighestScores[CStats::TOTAL_HIGHEST_SCORES];
int32 CStats::BestPositions[CStats::TOTAL_BEST_POSITIONS];
int32 CStats::PropertyDestroyed;
int32 CStats::PamphletMissionPassed;
int32 CStats::Sprayings;
float CStats::AutoPaintingBudget;

View file

@ -65,6 +65,7 @@ public:
static int32 HighestScores[TOTAL_HIGHEST_SCORES];
static int32 BestPositions[TOTAL_BEST_POSITIONS];
static int32 PropertyDestroyed;
static int32 PamphletMissionPassed;
static int32 Sprayings;
static float AutoPaintingBudget;
static int32 NoMoreHurricanes;

View file

@ -1933,6 +1933,11 @@ CWorld::Process(void)
} else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item;
#ifdef SQUEEZE_PERFORMANCE
if (movingEnt->bRemoveFromWorld) {
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else
#endif
if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
// TODO(MIAMI): doRender argument

View file

@ -7,6 +7,7 @@
#include "Clock.h"
#include "Text.h"
#include "World.h"
#include "Timer.h"
eLevelName CTheZones::m_CurrLevel;
int16 CTheZones::FindIndex;
@ -127,6 +128,10 @@ CTheZones::Init(void)
void
CTheZones::Update(void)
{
#ifdef SQUEEZE_PERFORMANCE
if (CTimer::GetFrameCounter() % 5 != 0)
return;
#endif
CVector pos;
pos = FindPlayerCoors();
m_CurrLevel = GetLevelFromPosition(&pos);

View file

@ -89,6 +89,16 @@ typedef uint16_t wchar;
#include <rpskin.h>
#endif
#ifdef __GNUC__
#define TYPEALIGN(n) __attribute__ ((aligned (n)))
#else
#ifdef _MSC_VER
#define TYPEALIGN(n) __declspec(align(n))
#else
#define TYPEALIGN(n) // unknown compiler...ignore
#endif
#endif
#define ALIGNPTR(p) (void*)((((uintptr)(void*)p) + sizeof(void*)-1) & ~(sizeof(void*)-1))
// PDP-10 like byte functions

View file

@ -167,7 +167,7 @@ enum Config {
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
# define COMPRESSED_COL_VECTORS
# define VU_COLLISION
#elif defined GTA_PC
# define GTA3_1_1_PATCH
//# define GTA3_STEAM_PATCH
@ -180,6 +180,10 @@ enum Config {
#elif defined GTA_XBOX
#endif
#ifdef VU_COLLISION
#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code
#endif
#ifdef MASTER
// only in master builds
#else
@ -228,6 +232,9 @@ enum Config {
// #define PC_WATER
#define WATER_CHEATS
//#define USE_CUTSCENE_SHADOW_FOR_PED
#define DISABLE_CUTSCENE_SHADOWS
// Pad
#if !defined(RW_GL3) && defined(_WIN32)
#define XINPUT
@ -297,4 +304,13 @@ enum Config {
#ifndef AUDIO_OAL // is not working yet for openal
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
#endif
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
//#define SQUEEZE_PERFORMANCE
#ifdef SQUEEZE_PERFORMANCE
#undef PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING
#define PC_PARTICLE
#define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
#endif

View file

@ -852,7 +852,7 @@ RenderScene(void)
CRenderer::RenderFadingInEntities();
RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
CWeather::RenderRainStreaks();
// CCoronas::RenderSunReflection
CCoronas::RenderSunReflection();
}
void

View file

@ -7,6 +7,7 @@
#include "Credits.h"
#include "Camera.h"
#include "Weather.h"
#include "Timecycle.h"
#include "Clock.h"
#include "World.h"
#include "Vehicle.h"
@ -406,6 +407,26 @@ DebugMenuPopulate(void)
static const char *weathers[] = {
"Sunny", "Cloudy", "Rainy", "Foggy", "Extrasunny", "Stormy"
};
static const char *extracols[] = {
"1 - Malibu club",
"2 - Strib club",
"3 - Hotel",
"4 - Bank",
"5 - Police HQ",
"6 - Mall",
"7 - Rifle Range",
"8 - Mansion",
"9 - Dirt ring",
"10 - Blood ring",
"11 - Hot ring",
"12 - Concert hall",
"13 - Auntie Poulets",
"14 - Intro at docks",
"15 - Biker bar",
"16 - Intro cafe",
"17 - Studio",
"18", "19", "20", "21", "22", "23", "24"
};
DebugMenuEntry *e;
e = DebugMenuAddVar("Time & Weather", "Current Hour", &CClock::GetHoursRef(), nil, 1, 0, 23, nil);
DebugMenuEntrySetWrap(e, true);
@ -416,7 +437,8 @@ DebugMenuPopulate(void)
DebugMenuEntrySetWrap(e, true);
e = DebugMenuAddVar("Time & Weather", "New Weather", (int16*)&CWeather::NewWeatherType, nil, 1, 0, 5, weathers);
DebugMenuEntrySetWrap(e, true);
DebugMenuAddVar("Time & Weather", "Wind", (float*)&CWeather::Wind, nil, 0.1f, 0.0f, 1.0f);
DebugMenuAddVarBool8("Time & Weather", "Extracolours On", &CTimeCycle::m_bExtraColourOn, nil);
DebugMenuAddVar("Time & Weather", "Extracolour", &CTimeCycle::m_ExtraColour, nil, 1, 0, 23, extracols);
DebugMenuAddVar("Time & Weather", "Time scale", (float*)&CTimer::GetTimeScale(), nil, 0.1f, 0.0f, 10.0f);
DebugMenuAddCmd("Cheats", "Weapon set 1", WeaponCheat1);
@ -489,9 +511,7 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil);
DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil);
#ifdef LIBRW
DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil);
#endif
DebugMenuAddVarBool8("Render", "Frame limiter", &FrontEndMenuManager.m_PrefsFrameLimiter, nil);
DebugMenuAddVarBool8("Render", "VSynch", &FrontEndMenuManager.m_PrefsVsync, nil);
DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil);

21
src/core/vu0Collision.dsm Normal file
View file

@ -0,0 +1,21 @@
.align 4
.global Vu0CollisionDmaTag
Vu0CollisionDmaTag:
DMAcnt *
MPG 0, *
.vu
.include "vu0Collision_1.s"
.EndMPG
.EndDmaData
DMAend
.global Vu0Collision2DmaTag
Vu0Collision2DmaTag:
DMAcnt *
MPG 0, *
.vu
.include "vu0Collision_2.s"
.EndMPG
.EndDmaData
DMAend
.end

610
src/core/vu0Collision_1.s Normal file
View file

@ -0,0 +1,610 @@
QuitAndFail:
NOP[E] IADDIU VI01, VI00, 0
NOP NOP
QuitAndSucceed:
NOP[E] IADDIU VI01, VI00, 1
NOP NOP
; 20 -- unused
; VF12, VF13 xyz: sphere centers
; VF14, VF15 x: sphere radii
; out:
; VI01: set when collision
; VF01: supposed to be intersection point?
; VF02: normal (pointing towards s1, not normalized)
.globl Vu0SphereToSphereCollision
Vu0SphereToSphereCollision:
SUB.xyz VF02, VF13, VF12 NOP ; dist of centers
ADD.x VF04, VF14, VF15 NOP ; s = sum of radii
MUL.xyzw VF03, VF02, VF02 NOP ;
MUL.x VF04, VF04, VF04 DIV Q, VF14x, VF04x ; square s
NOP NOP ;
NOP NOP ;
MULAx.w ACC, VF00, VF03 NOP ;
MADDAy.w ACC, VF00, VF03 NOP ;
MADDz.w VF03, VF00, VF03 NOP ; d = DistSq of centers
NOP NOP ;
MULAw.xyz ACC, VF12, VF00 NOP ;
MADDq.xyz VF01, VF02, Q NOP ; intersection, but wrong
CLIPw.xyz VF04, VF03 NOP ; compare s and d
SUB.xyz VF02, VF00, VF02 NOP ; compute normal
NOP NOP ;
NOP NOP ;
NOP FCAND VI01, 0x3 ; 0x2 cannot be set here
NOP[E] NOP ;
NOP NOP ;
; B8 -- unused
; VF12:
; VF13: radius
; VF14:
; VF15: box dimensions (?)
.globl Vu0SphereToAABBCollision
Vu0SphereToAABBCollision:
SUB.xyz VF03, VF12, VF14 LOI 0.5
MULi.xyz VF15, VF15, I NOP
MUL.x VF13, VF13, VF13 NOP
SUB.xyz VF04, VF03, VF15 NOP
ADD.xyz VF05, VF03, VF15 MR32.xyzw VF16, VF15
CLIPw.xyz VF03, VF16 MR32.xyzw VF17, VF16
MUL.xyz VF04, VF04, VF04 NOP
MUL.xyz VF05, VF05, VF05 NOP
CLIPw.xyz VF03, VF17 MR32.xyzw VF16, VF17
NOP FCAND VI01, 0x1
MINI.xyz VF04, VF04, VF05 MFIR.x VF09, VI01
NOP NOP
CLIPw.xyz VF03, VF16 FCAND VI01, 0x4
NOP MFIR.y VF09, VI01
NOP NOP
MULAx.w ACC, VF00, VF00 NOP
ADD.xyz VF01, VF00, VF03 FCAND VI01, 0x10
NOP MFIR.z VF09, VI01
NOP LOI 2
NOP FCAND VI01, 0x30
SUBAw.xyz ACC, VF00, VF00 IADD VI04, VI00, VI01
ITOF0.xyz VF09, VF09 FCAND VI01, 0x300
NOP IADD VI03, VI00, VI01
NOP FCAND VI01, 0x3000
NOP IADD VI02, VI00, VI01
MADDi.xyzw VF09, VF09, I NOP
NOP IBEQ VI04, VI00, IgnoreZValue
NOP NOP
MADDAz.w ACC, VF00, VF04 NOP
MUL.z VF01, VF09, VF15 NOP
IgnoreZValue:
NOP IBEQ VI03, VI00, IgnoreYValue
NOP NOP
MADDAy.w ACC, VF00, VF04 NOP
MUL.y VF01, VF09, VF15 NOP
IgnoreYValue:
NOP IBEQ VI02, VI00, IgnoreXValue
NOP NOP
MADDAx.w ACC, VF00, VF04 NOP
MUL.x VF01, VF09, VF15 NOP
IgnoreXValue:
MADDx.w VF06, VF00, VF00 NOP
SUB.xyz VF02, VF03, VF01 NOP
ADD.xyz VF01, VF01, VF14 NOP
MULx.w VF01, VF00, VF00 NOP
CLIPw.xyz VF13, VF06 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x1
QuitMicrocode:
NOP[E] NOP
NOP NOP
; 240
.globl Vu0LineToSphereCollision
Vu0LineToSphereCollision:
SUB.xyzw VF01, VF13, VF12 NOP
SUB.xyzw VF02, VF14, VF12 NOP
MUL.xyz VF03, VF01, VF02 NOP
MUL.xyz VF04, VF01, VF01 NOP
MUL.x VF15, VF15, VF15 NOP
MUL.xyz VF02, VF02, VF02 NOP
MULAx.w ACC, VF00, VF03 NOP
MADDAy.w ACC, VF00, VF03 NOP
MADDz.w VF03, VF00, VF03 NOP
MULAx.w ACC, VF00, VF04 NOP
MADDAy.w ACC, VF00, VF04 NOP
MADDz.w VF01, VF00, VF04 NOP
MULAx.w ACC, VF00, VF02 NOP
MADDAy.w ACC, VF00, VF02 NOP
MADDz.w VF02, VF00, VF02 NOP
MULA.w ACC, VF03, VF03 NOP
MADDAx.w ACC, VF01, VF15 NOP
MSUB.w VF05, VF01, VF02 NOP
NOP NOP
NOP NOP
NOP IADDIU VI02, VI00, 0x10
NOP FMAND VI01, VI02
NOP IBNE VI01, VI00, QuitAndFail
NOP NOP
CLIPw.xyz VF15, VF02 SQRT Q, VF05w
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x1
NOP IBNE VI00, VI01, LineStartInsideSphere
NOP NOP
SUBq.w VF05, VF03, Q NOP
SUB.w VF05, VF05, VF01 DIV Q, VF05w, VF01w
NOP FMAND VI01, VI02
NOP IBNE VI01, VI00, QuitAndFail
NOP NOP
NOP FMAND VI01, VI02
NOP IBEQ VI01, VI00, QuitAndFail
NOP NOP
ADDA.xyz ACC, VF12, VF00 NOP
MADDq.xyz VF01, VF01, Q NOP
MULx.w VF01, VF00, VF00 NOP
SUB.xyz VF02, VF01, VF14 NOP
NOP[E] NOP
NOP NOP
LineStartInsideSphere:
NOP MOVE.xyzw VF01, VF12
NOP[E] IADDIU VI01, VI00, 0x1
NOP NOP
; 3C0
.globl Vu0LineToAABBCollision
Vu0LineToAABBCollision:
SUB.xyzw VF08, VF13, VF12 LOI 0.5
MULi.xyz VF15, VF15, I IADDIU VI08, VI00, 0x0
SUB.xyzw VF12, VF12, VF14 NOP
SUB.xyzw VF13, VF13, VF14 NOP
NOP DIV Q, VF00w, VF08x
NOP MR32.xyzw VF03, VF15
SUB.xyz VF06, VF15, VF12 NOP
ADD.xyz VF07, VF15, VF12 NOP
NOP NOP
CLIPw.xyz VF12, VF03 MR32.xyzw VF04, VF03
NOP NOP
ADDq.x VF09, VF00, Q DIV Q, VF00w, VF08y
NOP NOP
CLIPw.xyz VF12, VF04 MR32.xyzw VF05, VF04
SUB.xyz VF07, VF00, VF07 IADDIU VI06, VI00, 0xCC
NOP IADDIU VI07, VI00, 0x30
NOP NOP
CLIPw.xyz VF12, VF05 FCGET VI02
NOP IAND VI02, VI02, VI06
ADDq.y VF09, VF00, Q DIV Q, VF00w, VF08z
SUB.xyz VF10, VF00, VF10 NOP
CLIPw.xyz VF13, VF03 FCGET VI03
CLIPw.xyz VF13, VF04 IAND VI03, VI03, VI07
CLIPw.xyz VF13, VF05 FCAND VI01, 0x3330
NOP IBEQ VI01, VI00, StartPointInsideAABB
NOP NOP
ADDq.z VF09, VF00, Q FCGET VI04
NOP FCGET VI05
NOP IAND VI04, VI04, VI06
NOP IAND VI05, VI05, VI07
MULx.xyz VF17, VF08, VF09 NOP
MULy.xyz VF18, VF08, VF09 IADDIU VI07, VI00, 0x80
MULz.xyz VF19, VF08, VF09 IAND VI06, VI02, VI07
MUL.w VF10, VF00, VF00 IAND VI07, VI04, VI07
NOP NOP
NOP IBEQ VI06, VI07, CheckMaxXSide
NOP NOP
MULAx.xyz ACC, VF17, VF07 NOP
MADDw.xyz VF16, VF12, VF00 NOP
MUL.x VF10, VF07, VF09 NOP
CLIPw.xyz VF16, VF04 NOP
CLIPw.xyz VF16, VF05 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x330
NOP IBNE VI01, VI00, CheckMaxXSide
NOP NOP
MULx.w VF10, VF00, VF10 IADDIU VI08, VI00, 0x1
ADD.yz VF02, VF00, VF00 MOVE.xyzw VF01, VF16
SUBw.x VF02, VF00, VF00 NOP
CheckMaxXSide:
MULAx.xyz ACC, VF17, VF06 IADDIU VI07, VI00, 0x40
MADDw.xyz VF16, VF12, VF00 IAND VI06, VI02, VI07
MUL.x VF10, VF06, VF09 IAND VI07, VI04, VI07
NOP NOP
NOP IBEQ VI06, VI07, CheckMinYSide
NOP NOP
CLIPw.xyz VF16, VF04 NOP
CLIPw.xyz VF16, VF05 NOP
CLIPw.xyz VF10, VF10 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0xCC03
NOP IBNE VI01, VI00, CheckMinYSide
NOP NOP
MULx.w VF10, VF00, VF10 IADDIU VI08, VI00, 0x1
ADD.yz VF02, VF00, VF00 MOVE.xyzw VF01, VF16
ADDw.x VF02, VF00, VF00 NOP
CheckMinYSide:
MULAy.xyz ACC, VF18, VF07 IADDIU VI07, VI00, 0x8
MADDw.xyz VF16, VF12, VF00 IAND VI06, VI02, VI07
MUL.y VF10, VF07, VF09 IAND VI07, VI04, VI07
NOP NOP
NOP IBEQ VI06, VI07, CheckMaxYSide
NOP NOP
CLIPw.xyz VF16, VF03 NOP
CLIPw.xyz VF16, VF05 NOP
CLIPw.xyz VF10, VF10 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x3C0C
NOP IBNE VI01, VI00, CheckMaxYSide
NOP NOP
MULy.w VF10, VF00, VF10 IADDIU VI08, VI00, 0x1
ADD.xz VF02, VF00, VF00 MOVE.xyzw VF01, VF16
SUBw.y VF02, VF00, VF00 NOP
CheckMaxYSide:
MULAy.xyz ACC, VF18, VF06 IADDIU VI07, VI00, 0x4
MADDw.xyz VF16, VF12, VF00 IAND VI06, VI02, VI07
MUL.y VF10, VF06, VF09 IAND VI07, VI04, VI07
NOP NOP
NOP IBEQ VI06, VI07, CheckMinZSide
NOP NOP
CLIPw.xyz VF16, VF03 NOP
CLIPw.xyz VF16, VF05 NOP
CLIPw.xyz VF10, VF10 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x3C0C
NOP IBNE VI01, VI00, CheckMinZSide
NOP NOP
MULy.w VF10, VF00, VF10 IADDIU VI08, VI00, 0x1
ADD.xz VF02, VF00, VF00 MOVE.xyzw VF01, VF16
ADDw.y VF02, VF00, VF00 NOP
CheckMinZSide:
MULAz.xyz ACC, VF19, VF07 IADDIU VI07, VI00, 0x20
MADDw.xyz VF16, VF12, VF00 IAND VI06, VI03, VI07
MUL.z VF10, VF07, VF09 IAND VI07, VI05, VI07
NOP NOP
NOP IBEQ VI06, VI07, CheckMaxZSide
NOP NOP
CLIPw.xyz VF16, VF03 NOP
CLIPw.xyz VF16, VF04 NOP
CLIPw.xyz VF10, VF10 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x3330
NOP IBNE VI01, VI00, CheckMaxZSide
NOP NOP
MULz.w VF10, VF00, VF10 IADDIU VI08, VI00, 0x1
ADD.xy VF02, VF00, VF00 MOVE.xyzw VF01, VF16
SUBw.z VF02, VF00, VF00 NOP
CheckMaxZSide:
MULAz.xyz ACC, VF19, VF06 IADDIU VI07, VI00, 0x10
MADDw.xyz VF16, VF12, VF00 IAND VI06, VI03, VI07
MUL.z VF10, VF06, VF09 IAND VI07, VI05, VI07
NOP NOP
NOP IBEQ VI06, VI07, DoneAllChecks
NOP NOP
CLIPw.xyz VF16, VF03 NOP
CLIPw.xyz VF16, VF04 NOP
CLIPw.xyz VF10, VF10 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x3330
NOP IBNE VI01, VI00, DoneAllChecks
NOP NOP
MULz.w VF10, VF00, VF10 IADDIU VI08, VI00, 0x1
ADD.xy VF02, VF00, VF00 MOVE.xyzw VF01, VF16
ADDw.z VF02, VF00, VF00 NOP
DoneAllChecks:
ADD.xyz VF01, VF01, VF14 IADD VI01, VI00, VI08
NOP[E] NOP
NOP NOP
StartPointInsideAABB:
ADD.xyz VF01, VF12, VF14 WAITQ
NOP IADDIU VI01, VI00, 0x1
NOP[E] NOP
NOP NOP
; 860
.globl Vu0LineToTriangleCollisionCompressedStart
Vu0LineToTriangleCollisionCompressedStart:
ITOF0.xyzw VF17, VF17 LOI 0.000244140625 ; 1.0/4096.0
ITOF0.xyzw VF14, VF14 NOP
ITOF0.xyzw VF15, VF15 NOP
ITOF0.xyzw VF16, VF16 NOP
MULi.xyz VF17, VF17, I LOI 0.0078125 ; 1.0/128.0
MULi.w VF17, VF17, I NOP
MULi.xyzw VF14, VF14, I NOP
MULi.xyzw VF15, VF15, I NOP
MULi.xyzw VF16, VF16, I NOP
; fall through
; 8A8
; VF12: point0
; VF13: point1
; VF14-16: verts
; VF17: plane
; out:
; VF01: intersection point
; VF02: triangle normal
; VF03 x: intersection parameter
.globl Vu0LineToTriangleCollisionStart
Vu0LineToTriangleCollisionStart:
MUL.xyz VF10, VF17, VF12 LOI 0.5
MUL.xyz VF11, VF17, VF13 NOP
SUB.xyz VF02, VF13, VF12 NOP ; line dist
ADD.xyz VF17, VF17, VF00 NOP
MULi.w VF03, VF00, I NOP
MULAx.w ACC, VF00, VF10 NOP
MADDAy.w ACC, VF00, VF10 IADDIU VI06, VI00, 0xE0
MADDz.w VF10, VF00, VF10 FMAND VI05, VI06 ; -- normal sign flags, unused
MULAx.w ACC, VF00, VF11 NOP
MADDAy.w ACC, VF00, VF11 NOP
MADDz.w VF11, VF00, VF11 NOP
SUB.w VF09, VF17, VF10 NOP ; plane-pos 0
CLIPw.xyz VF17, VF03 NOP ; compare normal against 0.5 to figure out which in which dimension to compare
NOP IADDIU VI02, VI00, 0x10 ; Sw flag
SUBA.w ACC, VF17, VF11 NOP ; plane-pos 1
SUB.w VF08, VF11, VF10 FMAND VI01, VI02
NOP NOP
NOP NOP
NOP FMAND VI02, VI02
NOP IBEQ VI01, VI02, QuitAndFail ; if on same side, no collision
NOP NOP
NOP DIV Q, VF09w, VF08w ; parameter of intersection
NOP FCAND VI01, 0x3 ; check x direction
NOP IADDIU VI02, VI01, 0x7F
NOP IADDIU VI06, VI00, 0x80
NOP IAND VI02, VI02, VI06 ; Sx flag
NOP FCAND VI01, 0xC ; check y direction
NOP IADDIU VI03, VI01, 0x3F
MULAw.xyz ACC, VF12, VF00 IADDIU VI06, VI00, 0x40
MADDq.xyz VF01, VF02, Q IAND VI03, VI03, VI06 ; point of intersection -- Sy flag
MULx.w VF01, VF00, VF00 FCAND VI01, 0x30 ; -- check z direction
ADDq.x VF03, VF00, Q IADDIU VI04, VI01, 0x1F ; output parameter
SUB.xyz VF05, VF15, VF14 IADDIU VI06, VI00, 0x20 ; edge vectors
SUB.xyz VF08, VF01, VF14 IAND VI04, VI04, VI06 ; edge vectors -- Sz flag
SUB.xyz VF06, VF16, VF15 IADD VI06, VI02, VI03 ; edge vectors
SUB.xyz VF09, VF01, VF15 IADD VI06, VI06, VI04 ; edge vectors -- combine flags
SUB.xyz VF07, VF14, VF16 NOP ; edge vectors
SUB.xyz VF10, VF01, VF16 NOP ; edge vectors
OPMULA.xyz ACC, VF08, VF05 NOP
OPMSUB.xyz VF18, VF05, VF08 NOP ; cross1
OPMULA.xyz ACC, VF09, VF06 NOP
OPMSUB.xyz VF19, VF06, VF09 NOP ; cross2
OPMULA.xyz ACC, VF10, VF07 NOP
OPMSUB.xyz VF20, VF07, VF10 FMAND VI02, VI06 ; cross3
NOP NOP
NOP FMAND VI03, VI06
NOP NOP
NOP FMAND VI04, VI06
NOP NOP
NOP IBNE VI03, VI02, QuitAndFail ; point has to lie on the same side of all edges (i.e. inside)
NOP NOP
NOP IBNE VI04, VI02, QuitAndFail
NOP NOP
MULw.xyz VF02, VF17, VF00 IADDIU VI01, VI00, 0x1 ; success
NOP[E] NOP
NOP NOP
; A68
; VF12: center
; VF14: line origin
; VF15: line vector to other point
; out: VF16 xyz: nearest point on line; w: distance to that point
DistanceBetweenSphereAndLine:
SUB.xyz VF20, VF12, VF14 NOP
MUL.xyz VF21, VF15, VF15 NOP
ADDA.xyz ACC, VF14, VF15 NOP
MSUBw.xyz VF25, VF12, VF00 NOP ; VF25 = VF12 - (VF14+VF15)
MUL.xyz VF22, VF20, VF20 NOP
MUL.xyz VF23, VF20, VF15 NOP
MULAx.w ACC, VF00, VF21 NOP
MADDAy.w ACC, VF00, VF21 NOP
MADDz.w VF21, VF00, VF21 NOP ; MagSq VF15 (line length)
MULAx.w ACC, VF00, VF23 NOP
MADDAy.w ACC, VF00, VF23 NOP
MADDz.w VF23, VF00, VF23 NOP ; dot(VF12-VF14, VF15)
MULAx.w ACC, VF00, VF22 NOP
MADDAy.w ACC, VF00, VF22 NOP
MADDz.w VF22, VF00, VF22 IADDIU VI08, VI00, 0x10 ; MagSq VF12-VF14 -- Sw bit
MUL.xyz VF25, VF25, VF25 FMAND VI08, VI08
NOP DIV Q, VF23w, VF21w
NOP IBNE VI00, VI08, NegativeRatio
NOP NOP
ADDA.xyz ACC, VF00, VF14 NOP
MADDq.xyz VF16, VF15, Q WAITQ ; nearest point on infinte line
ADDq.x VF24, VF00, Q NOP ; ratio
NOP NOP
NOP NOP
SUB.xyz VF26, VF16, VF12 NOP
CLIPw.xyz VF24, VF00 NOP ; compare ratio to 1.0
NOP NOP
NOP NOP
MUL.xyz VF26, VF26, VF26 NOP
NOP FCAND VI01, 0x1
NOP IBNE VI00, VI01, RatioGreaterThanOne
NOP NOP
MULAx.w ACC, VF00, VF26 NOP
MADDAy.w ACC, VF00, VF26 NOP
MADDz.w VF16, VF00, VF26 NOP ; distance
NOP JR VI15
NOP NOP
NegativeRatio:
ADD.xyz VF16, VF00, VF14 NOP ; return line origin
MUL.w VF16, VF00, VF22 NOP ; and DistSq to it
NOP JR VI15
NOP NOP
RatioGreaterThanOne:
MULAx.w ACC, VF00, VF25 NOP
MADDAy.w ACC, VF00, VF25 NOP
MADDz.w VF16, VF00, VF25 NOP
ADD.xyz VF16, VF14, VF15 NOP ; return toerh line point
NOP JR VI15
NOP NOP
; BE0
.globl Vu0SphereToTriangleCollisionCompressedStart
Vu0SphereToTriangleCollisionCompressedStart:
ITOF0.xyzw VF17, VF17 LOI 0.000244140625 ; 1.0/4096.0
ITOF0.xyzw VF14, VF14 NOP
ITOF0.xyzw VF15, VF15 NOP
ITOF0.xyzw VF16, VF16 NOP
MULi.xyz VF17, VF17, I LOI 0.0078125 ; 1.0/128.0
MULi.w VF17, VF17, I NOP
MULi.xyzw VF14, VF14, I NOP
MULi.xyzw VF15, VF15, I NOP
MULi.xyzw VF16, VF16, I NOP
; fall through
; C28
; VF12: sphere
; VF14-16: verts
; VF17: plane
; out:
; VF01: intersection point
; VF02: triangle normal
; VF03 x: intersection parameter
.globl Vu0SphereToTriangleCollisionStart
Vu0SphereToTriangleCollisionStart:
MUL.xyz VF02, VF12, VF17 LOI 0.1
ADD.xyz VF17, VF17, VF00 NOP
ADDw.x VF13, VF00, VF12 NOP
NOP NOP
MULAx.w ACC, VF00, VF02 IADDIU VI06, VI00, 0xE0
MADDAy.w ACC, VF00, VF02 FMAND VI05, VI06 ; normal sign flags
MADDAz.w ACC, VF00, VF02 NOP
MSUB.w VF02, VF00, VF17 NOP ; center plane pos
MULi.w VF03, VF00, I MOVE.xyzw VF04, VF03
NOP NOP
NOP NOP
CLIPw.xyz VF13, VF02 NOP ; compare dist and radius
CLIPw.xyz VF17, VF03 NOP
MULAw.xyz ACC, VF12, VF00 IADDIU VI07, VI00, 0x0 ; -- clear test case
MSUBw.xyz VF01, VF17, VF02 NOP
MULx.w VF01, VF00, VF00 FCAND VI01, 0x3 ; projected center on plane
ABS.w VF02, VF02 IBEQ VI00, VI01, QuitAndFail ; no intersection
NOP NOP
NOP FCAND VI01, 0x3 ; -- check x direction
SUB.xyz VF02, VF12, VF01 IADDIU VI02, VI01, 0x7F
NOP IADDIU VI06, VI00, 0x80
SUB.xyz VF05, VF15, VF14 IAND VI02, VI02, VI06
SUB.xyz VF08, VF01, VF14 FCAND VI01, 0xC ; -- check y direction
SUB.xyz VF06, VF16, VF15 IADDIU VI03, VI01, 0x3F
SUB.xyz VF09, VF01, VF15 IADDIU VI06, VI00, 0x40
SUB.xyz VF07, VF14, VF16 IAND VI03, VI03, VI06
SUB.xyz VF10, VF01, VF16 FCAND VI01, 0x30 ; -- check z direction
MUL.xyz VF03, VF02, VF02 IADDIU VI04, VI01, 0x1F
OPMULA.xyz ACC, VF08, VF05 IADDIU VI06, VI00, 0x20
OPMSUB.xyz VF18, VF05, VF08 IAND VI04, VI04, VI06
OPMULA.xyz ACC, VF09, VF06 NOP
OPMSUB.xyz VF19, VF06, VF09 IADD VI06, VI02, VI03
OPMULA.xyz ACC, VF10, VF07 IADD VI06, VI06, VI04 ; -- combine flags
OPMSUB.xyz VF20, VF07, VF10 FMAND VI02, VI06 ; -- cross 1 flags
MULAx.w ACC, VF00, VF03 IAND VI05, VI05, VI06
MADDAy.w ACC, VF00, VF03 FMAND VI03, VI06 ; -- cross 2 flags
MADDz.w VF03, VF00, VF03 IADDIU VI08, VI00, 0x3
NOP FMAND VI04, VI06 ; -- cross 3 flags
NOP NOP
NOP IBNE VI02, VI05, CheckSide2
NOP RSQRT Q, VF00w, VF03w
ADD.xyz VF04, VF00, VF16 IADDIU VI07, VI07, 0x1 ; inside side 1
CheckSide2:
NOP IBNE VI03, VI05, CheckSide3
NOP NOP
ADD.xyz VF04, VF00, VF14 IADDIU VI07, VI07, 0x1 ; inside side 2
CheckSide3:
NOP IBNE VI04, VI05, FinishCheckingSides
NOP NOP
ADD.xyz VF04, VF00, VF15 IADDIU VI07, VI07, 0x1 ; inside side 3
NOP NOP
NOP IBEQ VI07, VI08, TotallyInsideTriangle
NOP NOP
FinishCheckingSides:
MUL.x VF13, VF13, VF13 IADDIU VI08, VI00, 0x2
MULq.xyz VF02, VF02, Q WAITQ
NOP IBNE VI07, VI08, IntersectionOutsideTwoSides
NOP NOP
NOP IBEQ VI02, VI05, CheckDistanceSide2
NOP NOP
NOP MOVE.xyzw VF15, VF05
NOP BAL VI15, DistanceBetweenSphereAndLine
NOP NOP
NOP B ProcessLineResult
NOP NOP
CheckDistanceSide2:
NOP IBEQ VI03, VI05, CheckDistanceSide3
NOP NOP
NOP MOVE.xyzw VF14, VF15
NOP MOVE.xyzw VF15, VF06
NOP BAL VI15, DistanceBetweenSphereAndLine
NOP NOP
NOP B ProcessLineResult
NOP NOP
CheckDistanceSide3:
NOP MOVE.xyzw VF14, VF16
NOP MOVE.xyzw VF15, VF07
NOP BAL VI15, DistanceBetweenSphereAndLine
NOP NOP
NOP B ProcessLineResult
NOP NOP
IntersectionOutsideTwoSides:
SUB.xyz VF05, VF04, VF12 NOP
ADD.xyz VF01, VF00, VF04 NOP ; col point
SUB.xyz VF02, VF12, VF04 NOP
NOP NOP
MUL.xyz VF05, VF05, VF05 NOP
NOP NOP
NOP NOP
NOP NOP
MULAx.w ACC, VF00, VF05 NOP
MADDAy.w ACC, VF00, VF05 NOP
MADDz.w VF05, VF00, VF05 NOP ; distSq to vertex
NOP NOP
NOP NOP
NOP NOP
CLIPw.xyz VF13, VF05 SQRT Q, VF05w ; compare radiusSq and distSq
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x1
ADDq.x VF03, VF00, Q WAITQ ; dist to vertex
NOP IBEQ VI00, VI01, QuitAndFail ; too far
NOP NOP
NOP NOP
NOP DIV Q, VF00w, VF03x
MULq.xyz VF02, VF02, Q WAITQ ; col normal
NOP[E] NOP
NOP NOP
TotallyInsideTriangle:
ADDw.x VF03, VF00, VF02 WAITQ
MULq.xyz VF02, VF02, Q NOP
NOP[E] IADDIU VI01, VI00, 0x1
NOP NOP
ProcessLineResult:
CLIPw.xyz VF13, VF16 SQRT Q, VF16w
ADD.xyz VF01, VF00, VF16 NOP
SUB.xyz VF02, VF12, VF16 NOP
NOP NOP
NOP FCAND VI01, 0x1
ADDq.x VF03, VF00, Q WAITQ
NOP IBEQ VI00, VI01, QuitAndFail
NOP NOP
NOP NOP
NOP DIV Q, VF00w, VF03x
MULq.xyz VF02, VF02, Q WAITQ
NOP[E] NOP
NOP NOP
EndOfMicrocode:

191
src/core/vu0Collision_2.s Normal file
View file

@ -0,0 +1,191 @@
QuitAndFail2:
NOP[E] IADDIU VI01, VI00, 0x0
NOP NOP
QuitAndSucceed2:
NOP[E] IADDIU VI01, VI00, 0x1
NOP NOP
; 20
GetBBVertices:
MULw.xy VF02, VF01, VF00 NOP
MUL.z VF02, VF01, VF11 NOP
MULw.xz VF03, VF01, VF00 NOP
MUL.y VF03, VF01, VF11 NOP
MULw.x VF04, VF01, VF00 NOP
MUL.yz VF04, VF01, VF11 NOP
NOP JR VI15
NOP NOP
; 60
Vu0OBBToOBBCollision:
SUBw.xyz VF11, VF00, VF00 LOI 0.5
MULi.xyz VF12, VF12, I NOP
MULi.xyz VF13, VF13, I NOP
NOP NOP
NOP NOP
NOP MOVE.xyz VF01, VF12
NOP BAL VI15, GetBBVertices
NOP NOP
MULAx.xyz ACC, VF14, VF01 NOP
MADDAy.xyz ACC, VF15, VF01 NOP
MADDz.xyz VF01, VF16, VF01 NOP
MULAx.xyz ACC, VF14, VF02 NOP
MADDAy.xyz ACC, VF15, VF02 NOP
MADDz.xyz VF02, VF16, VF02 NOP
MULAx.xyz ACC, VF14, VF03 NOP
MADDAy.xyz ACC, VF15, VF03 NOP
MADDz.xyz VF03, VF16, VF03 NOP
MULAx.xyz ACC, VF14, VF04 NOP
MADDAy.xyz ACC, VF15, VF04 NOP
MADDz.xyz VF04, VF16, VF04 NOP
ABS.xyz VF05, VF01 NOP
ABS.xyz VF06, VF02 NOP
ABS.xyz VF07, VF03 NOP
ABS.xyz VF08, VF04 NOP
NOP NOP
MAX.xyz VF05, VF05, VF06 NOP
NOP NOP
MAX.xyz VF07, VF07, VF08 NOP
NOP NOP
NOP NOP
NOP NOP
MAX.xyz VF05, VF05, VF07 NOP
NOP NOP
NOP NOP
NOP NOP
ADD.xyz VF09, VF05, VF13 NOP
NOP NOP
NOP NOP
NOP NOP
MULx.w VF05, VF00, VF09 NOP
MULy.w VF06, VF00, VF09 NOP
MULz.w VF07, VF00, VF09 NOP
CLIPw.xyz VF17, VF05 NOP
CLIPw.xyz VF17, VF06 NOP
CLIPw.xyz VF17, VF07 MOVE.xyz VF01, VF13
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x3330
NOP IBNE VI01, VI00, QuitAndFail2
NOP NOP
NOP BAL VI15, GetBBVertices
NOP NOP
MULAx.xyz ACC, VF18, VF01 NOP
MADDAy.xyz ACC, VF19, VF01 NOP
MADDz.xyz VF01, VF20, VF01 NOP
MULAx.xyz ACC, VF18, VF02 NOP
MADDAy.xyz ACC, VF19, VF02 NOP
MADDz.xyz VF02, VF20, VF02 NOP
MULAx.xyz ACC, VF18, VF03 NOP
MADDAy.xyz ACC, VF19, VF03 NOP
MADDz.xyz VF03, VF20, VF03 NOP
MULAx.xyz ACC, VF18, VF04 NOP
MADDAy.xyz ACC, VF19, VF04 NOP
MADDz.xyz VF04, VF20, VF04 NOP
ABS.xyz VF05, VF01 NOP
ABS.xyz VF06, VF02 NOP
ABS.xyz VF07, VF03 NOP
ABS.xyz VF08, VF04 NOP
NOP NOP
MAX.xyz VF05, VF05, VF06 NOP
NOP NOP
MAX.xyz VF07, VF07, VF08 NOP
NOP NOP
NOP NOP
NOP NOP
MAX.xyz VF05, VF05, VF07 NOP
NOP NOP
NOP NOP
NOP NOP
ADD.xyz VF09, VF05, VF12 NOP
NOP NOP
NOP NOP
NOP NOP
MULx.w VF05, VF00, VF09 NOP
MULy.w VF06, VF00, VF09 NOP
MULz.w VF07, VF00, VF09 NOP
CLIPw.xyz VF21, VF05 NOP
CLIPw.xyz VF21, VF06 NOP
CLIPw.xyz VF21, VF07 NOP
NOP NOP
NOP NOP
NOP NOP
NOP FCAND VI01, 0x3330
NOP IBNE VI01, VI00, QuitAndFail2
NOP NOP
SUB.xyz VF06, VF02, VF01 NOP
SUB.xyz VF07, VF03, VF01 NOP
ADD.xyz VF08, VF04, VF01 NOP
ADD.x VF09, VF00, VF12 NOP
ADD.yz VF09, VF00, VF00 NOP
ADD.y VF10, VF00, VF12 NOP
ADD.xz VF10, VF00, VF00 NOP
ADD.z VF11, VF00, VF12 IADDI VI04, VI00, 0x0
ADD.xy VF11, VF00, VF00 IADD VI02, VI00, VI00
OPMULA.xyz ACC, VF06, VF09 NOP
OPMSUB.xyz VF01, VF09, VF06 NOP
OPMULA.xyz ACC, VF06, VF10 NOP
OPMSUB.xyz VF02, VF10, VF06 NOP
OPMULA.xyz ACC, VF06, VF11 NOP
OPMSUB.xyz VF03, VF11, VF06 SQI.xyzw VF01, (VI02++)
OPMULA.xyz ACC, VF07, VF09 NOP
OPMSUB.xyz VF01, VF09, VF07 SQI.xyzw VF02, (VI02++)
OPMULA.xyz ACC, VF07, VF10 NOP
OPMSUB.xyz VF02, VF10, VF07 SQI.xyzw VF03, (VI02++)
OPMULA.xyz ACC, VF07, VF11 NOP
OPMSUB.xyz VF03, VF11, VF07 SQI.xyzw VF01, (VI02++)
OPMULA.xyz ACC, VF08, VF09 NOP
OPMSUB.xyz VF01, VF09, VF08 SQI.xyzw VF02, (VI02++)
OPMULA.xyz ACC, VF08, VF10 NOP
OPMSUB.xyz VF02, VF10, VF08 SQI.xyzw VF03, (VI02++)
OPMULA.xyz ACC, VF08, VF11 LOI 0.5
OPMSUB.xyz VF01, VF11, VF08 SQI.xyzw VF01, (VI02++)
MULi.xyz VF06, VF06, I NOP
MULi.xyz VF07, VF07, I SQI.xyzw VF02, (VI02++)
MULi.xyz VF08, VF08, I NOP
MUL.xyz VF02, VF21, VF01 NOP
MUL.xyz VF03, VF12, VF01 NOP
MUL.xyz VF09, VF06, VF01 NOP
MUL.xyz VF10, VF07, VF01 NOP
MUL.xyz VF11, VF08, VF01 NOP
ABS.xyz VF03, VF03 NOP
ADDy.x VF05, VF09, VF09 NOP
ADDx.y VF05, VF10, VF10 NOP
ADDx.z VF05, VF11, VF11 NOP
NOP NOP
EdgePairLoop:
ADDz.x VF05, VF05, VF09 NOP
ADDz.y VF05, VF05, VF10 NOP
ADDy.z VF05, VF05, VF11 NOP
MULAx.w ACC, VF00, VF02 IADD VI03, VI02, VI00
MADDAy.w ACC, VF00, VF02 LQD.xyzw VF01, (--VI02)
MADDz.w VF02, VF00, VF02 NOP
ABS.xyz VF05, VF05 NOP
MULAx.w ACC, VF00, VF03 NOP
MADDAy.w ACC, VF00, VF03 NOP
MADDAz.w ACC, VF00, VF03 NOP
MADDAx.w ACC, VF00, VF05 NOP
MADDAy.w ACC, VF00, VF05 NOP
MADDz.w VF03, VF00, VF05 NOP
ADDw.x VF04, VF00, VF02 NOP
MUL.xyz VF02, VF21, VF01 NOP
MUL.xyz VF03, VF12, VF01 NOP
MUL.xyz VF09, VF06, VF01 NOP
CLIPw.xyz VF04, VF03 NOP
MUL.xyz VF10, VF07, VF01 NOP
MUL.xyz VF11, VF08, VF01 NOP
ABS.xyz VF03, VF03 NOP
ADDy.x VF05, VF09, VF09 FCAND VI01, 0x3
ADDx.y VF05, VF10, VF10 IBNE VI01, VI00, QuitAndFail2
ADDx.z VF05, VF11, VF11 NOP
NOP IBNE VI03, VI00, EdgePairLoop
NOP NOP
NOP[E] IADDIU VI01, VI00, 0x1
NOP NOP
EndOfMicrocode2:

View file

@ -445,7 +445,7 @@ CEntity::PreRender(void)
gpShadowExplosionTex, &pos,
8.0f, 0.0f, 0.0f, -8.0f,
255, 200.0f*flicker, 160.0f*flicker, 120.0f*flicker,
20.0f, false, 1.0f);
20.0f, false, 1.0f, nil, false);
CPointLights::AddLight(CPointLights::LIGHT_POINT,
pos, CVector(0.0f, 0.0f, 0.0f),
8.0f,
@ -483,7 +483,7 @@ CEntity::PreRender(void)
CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(),
20.0f, false, 1.0f);
20.0f, false, 1.0f, nil, false);
}
// fall through
case ENTITY_TYPE_DUMMY:

View file

@ -29,6 +29,15 @@ public:
if(m_hasRwMatrix && m_attachment)
RwMatrixDestroy(m_attachment);
}
#ifdef RWCORE_H
operator RwMatrix (void) const {
return m_matrix;
}
operator RwMatrix *(void) {
return &m_matrix;
}
#endif
void Attach(RwMatrix *matrix, bool owner = false){
#ifdef FIX_BUGS
if(m_attachment && m_hasRwMatrix)
@ -81,6 +90,7 @@ public:
m_matrix.pos.z += rhs.m_matrix.pos.z;
return *this;
}
CMatrix& operator*=(CMatrix const &rhs);
const CVector &GetPosition(void) const { return *(CVector*)&m_matrix.pos; }
CVector& GetPosition(void) { return *(CVector*)&m_matrix.pos; }
@ -240,6 +250,15 @@ public:
void CopyOnlyMatrix(CMatrix *other){
m_matrix = other->m_matrix;
}
void CopyRwMatrix(RwMatrix *matrix){
m_matrix = *matrix;
}
void CopyToRwMatrix(RwMatrix *matrix){
*matrix = m_matrix;
RwMatrixUpdate(matrix);
}
void SetUnity(void) {
m_matrix.right.x = 1.0f;
m_matrix.right.y = 0.0f;

41
src/math/VuVector.h Normal file
View file

@ -0,0 +1,41 @@
#pragma once
class TYPEALIGN(16) CVuVector : public CVector
{
public:
float w;
CVuVector(void) {}
CVuVector(float x, float y, float z) : CVector(x, y, z) {}
CVuVector(float x, float y, float z, float w) : CVector(x, y, z), w(w) {}
CVuVector(const CVector &v) : CVector(v.x, v.y, v.z) {}
#ifdef RWCORE_H
CVuVector(const RwV3d &v) : CVector(v.x, v.y, v.z) {}
operator RwV3d (void) const {
RwV3d vecRw = { this->x, this->y, this->z };
return vecRw;
}
operator RwV3d *(void) {
return (RwV3d*)this;
}
#endif
/*
void Normalise(void) {
float sq = MagnitudeSqr();
// TODO: VU0 code
if(sq > 0.0f){
float invsqrt = RecipSqrt(sq);
x *= invsqrt;
y *= invsqrt;
z *= invsqrt;
}else
x = 1.0f;
}
*/
};
void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in);
void TransformPoint(CVuVector &out, const CMatrix &mat, const RwV3d &in);
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const RwV3d *in, int stride);
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const CVuVector *in);

View file

@ -1,9 +1,124 @@
#include "common.h"
#include "Quaternion.h"
#include "VuVector.h"
// TODO: move more stuff into here
void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in)
{
#ifdef GTA_PS2
__asm__ __volatile__("\n\
lqc2 vf01,0x0(%2)\n\
lqc2 vf02,0x0(%1)\n\
lqc2 vf03,0x10(%1)\n\
lqc2 vf04,0x20(%1)\n\
lqc2 vf05,0x30(%1)\n\
vmulax.xyz ACC, vf02,vf01\n\
vmadday.xyz ACC, vf03,vf01\n\
vmaddaz.xyz ACC, vf04,vf01\n\
vmaddw.xyz vf06,vf05,vf00\n\
sqc2 vf06,0x0(%0)\n\
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
#else
out = mat * in;
#endif
}
void TransformPoint(CVuVector &out, const CMatrix &mat, const RwV3d &in)
{
#ifdef GTA_PS2
__asm__ __volatile__("\n\
ldr $8,0x0(%2)\n\
ldl $8,0x7(%2)\n\
lw $9,0x8(%2)\n\
pcpyld $10,$9,$8\n\
qmtc2 $10,vf01\n\
lqc2 vf02,0x0(%1)\n\
lqc2 vf03,0x10(%1)\n\
lqc2 vf04,0x20(%1)\n\
lqc2 vf05,0x30(%1)\n\
vmulax.xyz ACC, vf02,vf01\n\
vmadday.xyz ACC, vf03,vf01\n\
vmaddaz.xyz ACC, vf04,vf01\n\
vmaddw.xyz vf06,vf05,vf00\n\
sqc2 vf06,0x0(%0)\n\
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
#else
out = mat * in;
#endif
}
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const RwV3d *in, int stride)
{
#ifdef GTA_PS3
__asm__ __volatile__("\n\
paddub $3,%4,$0\n\
lqc2 vf02,0x0(%2)\n\
lqc2 vf03,0x10(%2)\n\
lqc2 vf04,0x20(%2)\n\
lqc2 vf05,0x30(%2)\n\
ldr $8,0x0(%3)\n\
ldl $8,0x7(%3)\n\
lw $9,0x8(%3)\n\
pcpyld $10,$9,$8\n\
qmtc2 $10,vf01\n\
1: vmulax.xyz ACC, vf02,vf01\n\
vmadday.xyz ACC, vf03,vf01\n\
vmaddaz.xyz ACC, vf04,vf01\n\
vmaddw.xyz vf06,vf05,vf00\n\
add %3,%3,$3\n\
ldr $8,0x0(%3)\n\
ldl $8,0x7(%3)\n\
lw $9,0x8(%3)\n\
pcpyld $10,$9,$8\n\
qmtc2 $10,vf01\n\
addi %1,%1,-1\n\
addiu %0,%0,0x10\n\
sqc2 vf06,-0x10(%0)\n\
bnez %1,1b\n\
": : "r" (out) , "r" (n), "r" (&mat), "r" (in), "r" (stride): "memory");
#else
while(n--){
*out = mat * *in;
in = (RwV3d*)((uint8*)in + stride);
out++;
}
#endif
}
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const CVuVector *in)
{
#ifdef GTA_PS2
__asm__ __volatile__("\n\
lqc2 vf02,0x0(%2)\n\
lqc2 vf03,0x10(%2)\n\
lqc2 vf04,0x20(%2)\n\
lqc2 vf05,0x30(%2)\n\
lqc2 vf01,0x0(%3)\n\
nop\n\
1: vmulax.xyz ACC, vf02,vf01\n\
vmadday.xyz ACC, vf03,vf01\n\
vmaddaz.xyz ACC, vf04,vf01\n\
vmaddw.xyz vf06,vf05,vf00\n\
lqc2 vf01,0x10(%3)\n\
addiu %3,%3,0x10\n\
addi %1,%1,-1\n\
addiu %0,%0,0x10\n\
sqc2 vf06,-0x10(%0)\n\
bnez %1,1b\n\
": : "r" (out) , "r" (n), "r" (&mat) ,"r" (in): "memory");
#else
while(n--){
*out = mat * *in;
in++;
out++;
}
#endif
}
void
CMatrix::SetRotate(float xAngle, float yAngle, float zAngle)
{
@ -74,6 +189,7 @@ CMatrix::Reorthogonalise(void)
CMatrix&
Invert(const CMatrix &src, CMatrix &dst)
{
// TODO: VU0 code
// GTA handles this as a raw 4x4 orthonormal matrix
// and trashes the RW flags, let's not do that
// actual copy of librw code:
@ -104,6 +220,7 @@ Invert(const CMatrix &src, CMatrix &dst)
CVector
operator*(const CMatrix &mat, const CVector &vec)
{
// TODO: VU0 code
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z + mat.m_matrix.pos.x,
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z + mat.m_matrix.pos.y,
@ -113,6 +230,7 @@ operator*(const CMatrix &mat, const CVector &vec)
CMatrix
operator*(const CMatrix &m1, const CMatrix &m2)
{
// TODO: VU0 code
CMatrix out;
RwMatrix *dst = &out.m_matrix;
const RwMatrix *src1 = &m1.m_matrix;
@ -132,9 +250,18 @@ operator*(const CMatrix &m1, const CMatrix &m2)
return out;
}
CMatrix&
CMatrix::operator*=(CMatrix const &rhs)
{
// TODO: VU0 code
*this = *this * rhs;
return *this;
}
const CVector
Multiply3x3(const CMatrix &mat, const CVector &vec)
{
// TODO: VU0 code
return CVector(
mat.m_matrix.right.x * vec.x + mat.m_matrix.up.x * vec.y + mat.m_matrix.at.x * vec.z,
mat.m_matrix.right.y * vec.x + mat.m_matrix.up.y * vec.y + mat.m_matrix.at.y * vec.z,
@ -166,6 +293,7 @@ CQuaternion::Slerp(const CQuaternion &q1, const CQuaternion &q2, float theta, fl
w1 = Sin((1.0f - t) * theta) * invSin;
w2 = Sin(t * theta) * invSin;
}
// TODO: VU0 code
*this = w1*q1 + w2*q2;
}
}

View file

@ -11,7 +11,11 @@
#include "ModelIndices.h"
#include "Shadows.h"
#include "Timecycle.h"
#include "CutsceneShadow.h"
#include "CutsceneObject.h"
#include "ModelIndices.h"
#include "RpAnimBlend.h"
CCutsceneObject::CCutsceneObject(void)
{
@ -21,6 +25,19 @@ CCutsceneObject::CCutsceneObject(void)
ObjectCreatedBy = CUTSCENE_OBJECT;
m_fMass = 1.0f;
m_fTurnMass = 1.0f;
m_pAttachTo = nil;
m_pAttachmentObject = nil;
m_pShadow = nil;
}
CCutsceneObject::~CCutsceneObject(void)
{
if ( m_pShadow )
{
delete m_pShadow;
m_pShadow = nil;
}
}
void
@ -33,22 +50,38 @@ CCutsceneObject::SetModelIndex(uint32 id)
(*RPANIMBLENDCLUMPDATA(m_rwObject))->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION_3D;
}
void
CCutsceneObject::CreateShadow(void)
{
if ( IsPedModel(GetModelIndex()) )
{
m_pShadow = new CCutsceneShadow();
if (!m_pShadow->IsInitialized())
m_pShadow->Create(m_rwObject, 6, true, 4, true);
}
}
void
CCutsceneObject::ProcessControl(void)
{
CPhysical::ProcessControl();
if(CTimer::GetTimeStep() < 1/100.0f)
m_vecMoveSpeed *= 100.0f;
if ( m_pAttachTo )
{
if ( m_pAttachmentObject )
GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
else
GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
}
else
m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
ApplyMoveSpeed();
#ifdef PED_SKIN
if(IsClumpSkinned(GetClump()))
UpdateRpHAnim();
#endif
{
if(CTimer::GetTimeStep() < 1/100.0f)
m_vecMoveSpeed *= 100.0f;
else
m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
ApplyMoveSpeed();
}
}
static RpMaterial*
@ -61,14 +94,52 @@ MaterialSetAlpha(RpMaterial *material, void *data)
void
CCutsceneObject::PreRender(void)
{
if(IsPedModel(GetModelIndex())){
CShadows::StoreShadowForPedObject(this,
CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
if ( m_pAttachTo )
{
if ( m_pAttachmentObject )
{
m_pAttachmentObject->UpdateRpHAnim();
GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
}
else
GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
if ( RwObjectGetType(m_rwObject) == rpCLUMP && IsClumpSkinned(GetClump()) )
{
RpAtomic *atomic = GetFirstAtomic(GetClump());
atomic->boundingSphere.center = (*RPANIMBLENDCLUMPDATA(GetClump()))->frames[0].hanimFrame->t;
}
}
if ( RwObjectGetType(m_rwObject) == rpCLUMP )
UpdateRpHAnim();
if(IsPedModel(GetModelIndex()))
{
if ( m_pShadow == nil )
{
CShadows::StoreShadowForPedObject(this,
CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
}
else
{
if ( m_pShadow->IsInitialized() )
m_pShadow->UpdateForCutscene();
CShadows::StoreShadowForCutscenePedObject(this,
CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
}
// For some reason xbox/android limbs are transparent here...
RpGeometry *geometry = RpAtomicGetGeometry(GetFirstAtomic(GetClump()));
RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
@ -79,7 +150,9 @@ CCutsceneObject::PreRender(void)
void
CCutsceneObject::Render(void)
{
RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLNONE);
CObject::Render();
RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLBACK);
}
bool

View file

@ -2,12 +2,20 @@
#include "Object.h"
class CCutsceneShadow;
class CCutsceneObject : public CObject
{
public:
CCutsceneShadow *m_pShadow;
void *m_pAttachTo;
CObject *m_pAttachmentObject;
CCutsceneObject(void);
~CCutsceneObject(void);
void SetModelIndex(uint32 id);
void CreateShadow(void);
void ProcessControl(void);
void PreRender(void);
void Render(void);

View file

@ -124,8 +124,6 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
CParticleObject *pobj = pUnusedListHead;
ASSERT(pobj != nil);
if ( pobj == nil )
{
printf("Error: No particle objects available!\n");

View file

@ -64,6 +64,7 @@
#include "GameLogic.h"
#include "Bike.h"
#include "WindModifiers.h"
#include "CutsceneShadow.h"
#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
@ -147,6 +148,9 @@ void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((
// --MIAMI: Done
CPed::~CPed(void)
{
#ifdef USE_CUTSCENE_SHADOW_FOR_PED
if ( m_pRTShadow ) delete m_pRTShadow;
#endif
CWorld::Remove(this);
if (m_attractor)
GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
@ -204,6 +208,9 @@ CPed::FlagToDestroyWhenNextProcessed(void)
CPed::CPed(uint32 pedType) : m_pedIK(this)
{
#ifdef USE_CUTSCENE_SHADOW_FOR_PED
m_pRTShadow = nil;
#endif
m_type = ENTITY_TYPE_PED;
bPedPhysics = true;
bUseCollisionRecords = true;
@ -2782,12 +2789,16 @@ CPed::SetModelIndex(uint32 mi)
// This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D.
(*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta;
#ifdef PED_SKIN
if(modelInfo->GetHitColModel() == nil)
modelInfo->CreateHitColModelSkinned(GetClump());
if (IsClumpSkinned(GetClump())) // condition isn't there in VC
UpdateRpHAnim();
UpdateRpHAnim();
#ifdef USE_CUTSCENE_SHADOW_FOR_PED
if (!m_pRTShadow)
{
m_pRTShadow = new CCutsceneShadow;
m_pRTShadow->Create(m_rwObject, 10, 1, 1, 1);
}
#endif
}
@ -16421,16 +16432,16 @@ CPed::PreRender(void)
&& !CCullZones::PlayerNoRain() && GetPedState() != PED_DRIVING)
bIsWindModifierTurnedOn = true;
bool bIsPlayerDrivingBikeOrOpenTopCar = false;
bool bIsPedDrivingBikeOrOpenTopCar = false;
if (GetPedState() == PED_DRIVING && m_pMyVehicle) {
if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE
|| (m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR && m_pMyVehicle->IsOpenTopCar()))
bIsPlayerDrivingBikeOrOpenTopCar = true;
bIsPedDrivingBikeOrOpenTopCar = true;
}
if (bIsWindModifierTurnedOn || bIsPlayerDrivingBikeOrOpenTopCar) {
if (bIsWindModifierTurnedOn || bIsPedDrivingBikeOrOpenTopCar) {
float fWindMult = 0.0f;
if (bIsPlayerDrivingBikeOrOpenTopCar) {
if (bIsPedDrivingBikeOrOpenTopCar) {
fWindMult = DotProduct(m_pMyVehicle->m_vecMoveSpeed, GetForward());
if (fWindMult > 0.4f) {
float volume = (fWindMult - 0.4f) / 0.6f;

View file

@ -363,6 +363,9 @@ class CVehicle;
class CPed : public CPhysical
{
public:
#ifdef USE_CUTSCENE_SHADOW_FOR_PED
class CCutsceneShadow *m_pRTShadow;
#endif
// 0x128
CStoredCollPoly m_collPoly;
float m_fCollisionSpeed;

View file

@ -1004,7 +1004,11 @@ CPopulation::ManagePopulation(void)
}
int pedPoolSize = CPools::GetPedPool()->GetSize();
#ifndef SQUEEZE_PERFORMANCE
for (int poolIndex = pedPoolSize-1; poolIndex >= 0; poolIndex--) {
#else
for (int poolIndex = (pedPoolSize * (frameMod32 + 1) / 32) - 1; poolIndex >= pedPoolSize * frameMod32 / 32; poolIndex--) {
#endif
CPed *ped = CPools::GetPedPool()->GetSlot(poolIndex);
if (ped && !ped->IsPlayer() && ped->CanBeDeleted() && !ped->bInVehicle) {

View file

@ -2,6 +2,8 @@
#include "Antennas.h"
//--MIAMI: file done
CAntenna CAntennas::aAntennas[NUMANTENNAS];
void

View file

@ -2,6 +2,7 @@
#include "main.h"
#include "General.h"
#include "RenderBuffer.h"
#include "TxdStore.h"
#include "Camera.h"
#include "Sprite.h"
@ -12,6 +13,8 @@
#include "Timecycle.h"
#include "Coronas.h"
//--MIAMI: file done
struct FlareDef
{
float position;
@ -130,13 +133,21 @@ void
CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, RwTexture *tex,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
bool longDist, float nearDist)
bool useNearDist, float nearDist)
{
int i;
if(sq(drawDist) < (TheCamera.GetPosition() - coors).MagnitudeSqr2D())
return;
if(useNearDist){
float dist = (TheCamera.GetPosition() - coors).Magnitude();
if(dist < 35.0f)
return;
if(dist < 50.0f)
alpha *= (dist - 35.0f)/(50.0f - 35.0f);
}
for(i = 0; i < NUMCORONAS; i++)
if(aCoronas[i].id == id)
break;
@ -189,17 +200,19 @@ CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 al
aCoronas[i].reflection = reflection;
aCoronas[i].LOScheck = LOScheck;
aCoronas[i].drawStreak = drawStreak;
aCoronas[i].useNearDist = useNearDist;
aCoronas[i].nearDist = nearDist;
}
void
CCoronas::RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, uint8 type,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
bool longDist, float nearDist)
bool useNearDist, float nearDist)
{
RegisterCorona(id, red, green, blue, alpha, coors, size, drawDist,
gpCoronaTexture[type], flareType, reflection, LOScheck, drawStreak, someAngle,
longDist, nearDist);
useNearDist, nearDist);
}
void
@ -258,7 +271,10 @@ CCoronas::Render(void)
CVector spriteCoors;
float spritew, spriteh;
if(CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){
if(!CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){
aCoronas[i].offScreen = true;
aCoronas[i].sightClear = false;
}else{
aCoronas[i].offScreen = false;
if(spriteCoors.x < 0.0f || spriteCoors.y < 0.0f ||
@ -292,10 +308,7 @@ CCoronas::Render(void)
}
if(aCoronas[i].fadeAlpha == 0)
continue;
if(spriteCoors.z < aCoronas[i].drawDist){
if(aCoronas[i].fadeAlpha && spriteCoors.z < aCoronas[i].drawDist){
float recipz = 1.0f/spriteCoors.z;
float fadeDistance = aCoronas[i].drawDist / 2.0f;
float distanceFade = spriteCoors.z < fadeDistance ? 1.0f : 1.0f - (spriteCoors.z - fadeDistance)/fadeDistance;
@ -312,7 +325,7 @@ CCoronas::Render(void)
if(CCoronas::aCoronas[i].id == SUN_CORE)
spriteCoors.z = 0.95f * RwCameraGetFarClipPlane(Scene.camera);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(aCoronas[i].texture));
spriteCoors.z -= 1.5f;
spriteCoors.z -= aCoronas[i].nearDist;
if(aCoronas[i].texture == gpCoronaTexture[8]){
// what's this?
@ -370,14 +383,11 @@ CCoronas::Render(void)
recipz, 255);
}
}
}else{
aCoronas[i].offScreen = true;
aCoronas[i].sightClear = false;
}
}
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
@ -393,23 +403,24 @@ CCoronas::Render(void)
if(!aCoronas[i].hasValue[j] || !aCoronas[i].hasValue[j+1])
continue;
int mod1 = (float)(6 - j) / 6 * 128;
int mod2 = (float)(6 - (j+1)) / 6 * 128;
int alpha1 = (float)(6 - j) / 6 * 128;
int alpha2 = (float)(6 - (j+1)) / 6 * 128;
RwIm2DVertexSetScreenX(&vertexbufferX[0], aCoronas[i].prevX[j]);
RwIm2DVertexSetScreenY(&vertexbufferX[0], aCoronas[i].prevY[j]);
RwIm2DVertexSetIntRGBA(&vertexbufferX[0], aCoronas[i].prevRed[j] * mod1 / 256, aCoronas[i].prevGreen[j] * mod1 / 256, aCoronas[i].prevBlue[j] * mod1 / 256, 255);
RwIm2DVertexSetIntRGBA(&vertexbufferX[0], aCoronas[i].prevRed[j] * alpha1 / 256, aCoronas[i].prevGreen[j] * alpha1 / 256, aCoronas[i].prevBlue[j] * alpha1 / 256, 255);
RwIm2DVertexSetScreenX(&vertexbufferX[1], aCoronas[i].prevX[j+1]);
RwIm2DVertexSetScreenY(&vertexbufferX[1], aCoronas[i].prevY[j+1]);
RwIm2DVertexSetIntRGBA(&vertexbufferX[1], aCoronas[i].prevRed[j+1] * mod2 / 256, aCoronas[i].prevGreen[j+1] * mod2 / 256, aCoronas[i].prevBlue[j+1] * mod2 / 256, 255);
RwIm2DVertexSetIntRGBA(&vertexbufferX[1], aCoronas[i].prevRed[j+1] * alpha2 / 256, aCoronas[i].prevGreen[j+1] * alpha2 / 256, aCoronas[i].prevBlue[j+1] * alpha2 / 256, 255);
// BUG: game doesn't do this
#ifdef FIX_BUGS
RwIm2DVertexSetScreenZ(&vertexbufferX[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&vertexbufferX[0], RwCameraGetNearClipPlane(Scene.camera));
RwIm2DVertexSetRecipCameraZ(&vertexbufferX[0], 1.0f/RwCameraGetNearClipPlane(Scene.camera));
RwIm2DVertexSetScreenZ(&vertexbufferX[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetCameraZ(&vertexbufferX[1], RwCameraGetNearClipPlane(Scene.camera));
RwIm2DVertexSetRecipCameraZ(&vertexbufferX[1], 1.0f/RwCameraGetNearClipPlane(Scene.camera));
#endif
RwIm2DRenderLine(vertexbufferX, 2, 0, 1);
}
@ -428,6 +439,8 @@ CCoronas::RenderReflections(void)
CEntity *entity;
if(CWeather::WetRoads > 0.0f){
CSprite::InitSpriteBuffer();
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
@ -438,7 +451,8 @@ CCoronas::RenderReflections(void)
for(i = 0; i < NUMCORONAS; i++){
if(aCoronas[i].id == 0 ||
aCoronas[i].fadeAlpha == 0 && aCoronas[i].alpha == 0)
aCoronas[i].fadeAlpha == 0 && aCoronas[i].alpha == 0 ||
aCoronas[i].reflection == 0)
continue;
// check if we want a reflection on this corona
@ -453,11 +467,8 @@ CCoronas::RenderReflections(void)
}
}
if(!aCoronas[i].renderReflection)
continue;
// Don't draw if reflection is too high
if(aCoronas[i].heightAboveRoad < 20.0f){
if(aCoronas[i].renderReflection && aCoronas[i].heightAboveRoad < 20.0f){
// don't draw if camera is below road
if(CCoronas::aCoronas[i].coors.z - aCoronas[i].heightAboveRoad > TheCamera.GetPosition().z)
continue;
@ -469,13 +480,14 @@ CCoronas::RenderReflections(void)
float spritew, spriteh;
if(CSprite::CalcScreenCoors(coors, spriteCoors, &spritew, &spriteh, true)){
float drawDist = 0.75f * aCoronas[i].drawDist;
drawDist = Min(drawDist, 50.0f);
drawDist = Min(drawDist, 55.0f);
if(spriteCoors.z < drawDist){
float fadeDistance = drawDist / 2.0f;
float distanceFade = spriteCoors.z < fadeDistance ? 1.0f : 1.0f - (spriteCoors.z - fadeDistance)/fadeDistance;
distanceFade = clamp(distanceFade, 0.0f, 1.0f);
float recipz = 1.0f/RwCameraGetNearClipPlane(Scene.camera);
int intensity = (20.0f - aCoronas[i].heightAboveRoad) * 230.0 * distanceFade*CWeather::WetRoads * 0.05f;
float heightFade = (20.0f - aCoronas[i].heightAboveRoad)/20.0f;
int intensity = distanceFade*heightFade * 230.0 * CWeather::WetRoads;
CSprite::RenderBufferedOneXLUSprite(
spriteCoors.x, spriteCoors.y, RwIm2DGetNearScreenZ(),
@ -504,6 +516,130 @@ CCoronas::RenderReflections(void)
}
}
void
CCoronas::RenderSunReflection(void)
{
float sunZDir = CTimeCycle::GetSunDirection().z;
if(sunZDir > -0.05f){
float intensity = (0.3f - Abs(sunZDir - 0.25f))/0.3f *
(1.0f - CWeather::CloudCoverage) *
(1.0f - CWeather::Foggyness) *
(1.0f - CWeather::Wind);
if(intensity > 0.0f){
int r = (CTimeCycle::GetSunCoreRed() + CTimeCycle::GetSunCoronaRed())*intensity*0.25f;
int g = (CTimeCycle::GetSunCoreGreen() + CTimeCycle::GetSunCoronaGreen())*intensity*0.25f;
int b = (CTimeCycle::GetSunCoreBlue() + CTimeCycle::GetSunCoronaBlue())*intensity*0.25f;
CVector sunPos = 40.0f*CTimeCycle::GetSunDirection() + TheCamera.GetPosition();
sunPos.z = 0.5f*CWeather::Wind + 6.1f;
CVector sunDir = CTimeCycle::GetSunDirection();
sunDir.z = 0.0;
sunDir.Normalise();
TempBufferIndicesStored = 6;
TempBufferRenderIndexList[0] = 2;
TempBufferRenderIndexList[1] = 1;
TempBufferRenderIndexList[2] = 0;
TempBufferRenderIndexList[3] = 2;
TempBufferRenderIndexList[4] = 3;
TempBufferRenderIndexList[5] = 1;
// 60 unit square in sun direction
TempBufferVerticesStored = 4;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[0], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[0],
sunPos.x + 30.0f*sunDir.y,
sunPos.y - 30.0f*sunDir.x,
sunPos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[1], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[1],
sunPos.x - 30.0f*sunDir.y,
sunPos.y + 30.0f*sunDir.x,
sunPos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[2], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[2],
sunPos.x + 60.0f*sunDir.x + 30.0f*sunDir.y,
sunPos.y + 60.0f*sunDir.y - 30.0f*sunDir.x,
sunPos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[3], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[3],
sunPos.x + 60.0f*sunDir.x - 30.0f*sunDir.y,
sunPos.y + 60.0f*sunDir.y + 30.0f*sunDir.x,
sunPos.z);
RwIm3DVertexSetU(&TempBufferRenderVertices[0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[0], 1.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[1], 1.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[1], 1.0f);
RwIm3DVertexSetU(&TempBufferRenderVertices[2], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[2], 0.5f);
RwIm3DVertexSetU(&TempBufferRenderVertices[3], 1.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[3], 0.5f);
int timeInc = 0;
int sideInc = 0;
int fwdInc = 0;
for(int i = 0; i < 20; i++){
TempBufferRenderIndexList[TempBufferIndicesStored + 0] = TempBufferVerticesStored;
TempBufferRenderIndexList[TempBufferIndicesStored + 1] = TempBufferVerticesStored-1;
TempBufferRenderIndexList[TempBufferIndicesStored + 2] = TempBufferVerticesStored-2;
TempBufferRenderIndexList[TempBufferIndicesStored + 3] = TempBufferVerticesStored;
TempBufferRenderIndexList[TempBufferIndicesStored + 4] = TempBufferVerticesStored+1;
TempBufferRenderIndexList[TempBufferIndicesStored + 5] = TempBufferVerticesStored-1;
TempBufferIndicesStored += 6;
// What a weird way to do it...
float fwdLen = fwdInc/20 + 60;
float sideLen = sideInc/20 + 30;
sideLen += 10.0f*Sin((float)(CTimer::GetTimeInMilliseconds()+timeInc & 0x7FF)/0x800*TWOPI);
timeInc += 900;
sideInc += 970;
fwdInc += 1440;
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+0], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+0],
sunPos.x + fwdLen*sunDir.x + sideLen*sunDir.y,
sunPos.y + fwdLen*sunDir.y - sideLen*sunDir.x,
sunPos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[TempBufferVerticesStored+1], r, g, b, 255);
RwIm3DVertexSetPos(&TempBufferRenderVertices[TempBufferVerticesStored+1],
sunPos.x + fwdLen*sunDir.x - sideLen*sunDir.x,
sunPos.y + fwdLen*sunDir.y + sideLen*sunDir.y,
sunPos.z);
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+0], 0.5f);
RwIm3DVertexSetU(&TempBufferRenderVertices[TempBufferVerticesStored+1], 1.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[TempBufferVerticesStored+1], 0.5f);
TempBufferVerticesStored += 2;
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[4]));
if(RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStored, nil, rwIM3D_VERTEXUV)){
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStored);
RwIm3DEnd();
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
}
}
}
void
CCoronas::DoSunAndMoon(void)
{
@ -520,7 +656,7 @@ CCoronas::DoSunAndMoon(void)
255, sunCoors, size,
999999.88f, TYPE_STAR, FLARE_NONE, REFLECTION_OFF, LOSCHECK_OFF, STREAK_OFF, 0.0f);
if(CTimeCycle::GetSunDirection().z > 0.0f)
if(CTimeCycle::GetSunDirection().z > 0.0f && !CGame::IsInInterior())
RegisterCorona(SUN_CORONA,
CTimeCycle::GetSunCoronaRed(), CTimeCycle::GetSunCoronaGreen(), CTimeCycle::GetSunCoronaBlue(),
255, sunCoors, 25.0f * CTimeCycle::GetSunSize(),

View file

@ -4,19 +4,21 @@ extern RwTexture *gpCoronaTexture[9];
struct CRegisteredCorona
{
CVector coors;
uint32 id;
uint32 lastLOScheck;
RwTexture *texture;
float size;
float someAngle;
float drawDist;
float nearDist;
float heightAboveRoad;
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha; // alpha when fully visible
uint8 fadeAlpha; // actual value used for rendering, faded
CVector coors;
float size;
float someAngle;
bool registeredThisFrame;
float drawDist;
int8 flareType;
int8 reflection;
@ -25,12 +27,11 @@ struct CRegisteredCorona
uint8 firstUpdate : 1;
uint8 drawStreak : 1;
uint8 sightClear : 1;
uint8 useNearDist : 1;
uint8 renderReflection : 1;
bool renderReflection;
float heightAboveRoad;
float prevX[6];
float prevY[6];
int16 prevX[6];
int16 prevY[6];
uint8 prevRed[6];
uint8 prevGreen[6];
uint8 prevBlue[6];
@ -39,7 +40,7 @@ struct CRegisteredCorona
void Update(void);
};
VALIDATE_SIZE(CRegisteredCorona, 0x80);
VALIDATE_SIZE(CRegisteredCorona, 0x68);
class CCoronas
{
@ -91,13 +92,14 @@ public:
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, RwTexture *tex,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
bool longDist = false, float nearClip = 1.5f);
bool useNearDist = false, float nearDist = 1.5f);
static void RegisterCorona(uint32 id, uint8 red, uint8 green, uint8 blue, uint8 alpha,
const CVector &coors, float size, float drawDist, uint8 type,
int8 flareType, uint8 reflection, uint8 LOScheck, uint8 drawStreak, float someAngle,
bool longDist = false, float nearClip = 1.5f);
bool useNearDist = false, float nearDist = 1.5f);
static void UpdateCoronaCoors(uint32 id, const CVector &coors, float drawDist, float someAngle);
static void Render(void);
static void RenderReflections(void);
static void RenderSunReflection(void);
static void DoSunAndMoon(void);
};

View file

@ -0,0 +1,269 @@
#include "common.h"
#include "main.h"
#include "rwcore.h"
#include "rwplcore.h"
#include "CutsceneShadow.h"
#include "RwHelper.h"
#define DLIGHT_VALUE 0.8f /* Directional light intensity */
CCutsceneShadow::CCutsceneShadow()
{
m_pAtomic = nil;
m_nRwObjectType = -1;
m_pLight = nil;
m_nBlurPasses = 0;
m_bResample = false;
m_bGradient = false;
}
CCutsceneShadow::~CCutsceneShadow()
{
Destroy();
}
bool
CCutsceneShadow::Create(RwObject *object, int32 rasterSize, bool resample, int32 blurPasses, bool gradient)
{
ASSERT(object != nil);
RwRGBAReal color;
RwFrame *frame;
if (!object)
return false;
m_pLight = RpLightCreate(rpLIGHTDIRECTIONAL);
ASSERT(m_pLight != nil);
if (!m_pLight)
return false;
color.red = color.green = color.blue = DLIGHT_VALUE;
color.alpha = 0.0f;
RpLightSetColor(m_pLight, &color);
frame = RwFrameCreate();
ASSERT(frame != nil);
RpLightSetFrame(m_pLight, frame);
SetLightProperties(180.0f, 90.0f, false);
m_pObject = object;
m_nRwObjectType = RwObjectGetType(m_pObject);
switch ( m_nRwObjectType )
{
case rpCLUMP:
{
RpClumpGetBoundingSphere(m_pClump, &m_BoundingSphere, 1);
m_BaseSphere.radius = m_BoundingSphere.radius;
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpClumpGetFrame(m_pClump)));
break;
}
case rpATOMIC:
{
m_BoundingSphere = *RpAtomicGetBoundingSphere(m_pAtomic);
m_BaseSphere.radius = m_BoundingSphere.radius;
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
break;
}
default:
{
Destroy();
return false;
break;
}
}
if ( !m_Camera.Create(rasterSize) )
{
Destroy();
return false;
}
m_nBlurPasses = blurPasses;
m_bResample = resample;
m_bGradient = gradient;
if ( m_bResample && !m_ResampleCamera.Create(rasterSize - 1) )
{
Destroy();
return false;
}
if ( m_nBlurPasses != 0 )
{
if ( !m_BlurCamera.Create(resample ? rasterSize - 1 : rasterSize) )
{
Destroy();
return false;
}
}
if ( m_bGradient )
{
if ( !m_GradientCamera.Create(resample ? rasterSize - 1 : rasterSize) )
{
Destroy();
return false;
}
m_GradientCamera.MakeGradientRaster();
}
m_Camera.SetLight(m_pLight);
switch ( m_nRwObjectType )
{
case rpATOMIC:
m_Camera.SetFrustum(1.1f * m_BoundingSphere.radius);
break;
case rpCLUMP:
m_Camera.SetFrustum(1.1f * m_BoundingSphere.radius);
break;
}
m_Camera.SetCenter(&m_BaseSphere.center);
return true;
}
RwFrame *
CCutsceneShadow::SetLightProperties(float angleY, float angleX, bool setLight)
{
ASSERT(m_pLight != nil);
RwFrame *frame;
static RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
static RwV3d Yaxis = { 0.0f, 1.0f, 0.0f };
frame = RpLightGetFrame(m_pLight);
ASSERT(frame != nil);
if ( !frame )
return nil;
RwFrameRotate(frame, &Yaxis, angleY, rwCOMBINEREPLACE);
RwFrameRotate(frame, &Xaxis, angleX, rwCOMBINEPOSTCONCAT);
if ( setLight )
m_Camera.SetLight(m_pLight);
return frame;
}
bool
CCutsceneShadow::IsInitialized()
{
return m_pObject != nil;
}
void
CCutsceneShadow::Destroy()
{
m_Camera.Destroy();
m_ResampleCamera.Destroy();
m_BlurCamera.Destroy();
m_GradientCamera.Destroy();
m_pAtomic = nil;
m_nRwObjectType = -1;
if (m_pLight)
{
RwFrame *frame = RpLightGetFrame(m_pLight);
RpLightSetFrame(m_pLight, nil);
RwFrameDestroy(frame);
RpLightDestroy(m_pLight);
m_pLight = nil;
}
}
RwRaster *
CCutsceneShadow::Update()
{
switch ( m_nRwObjectType )
{
case rpCLUMP:
ASSERT(m_pClump != nil);
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpClumpGetFrame(m_pClump)));
break;
case rpATOMIC:
ASSERT(m_pAtomic != nil);
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
break;
}
m_Camera.SetCenter(&m_BaseSphere.center);
switch ( m_nRwObjectType )
{
case rpCLUMP:
m_Camera.Update(m_pClump);
break;
case rpATOMIC:
m_Camera.Update(m_pAtomic);
break;
}
RwRaster *raster = m_Camera.GetRwRenderRaster();
ASSERT(raster != nil);
if ( m_bResample )
return m_ResampleCamera.RasterResample(raster);
if ( m_nBlurPasses )
return m_BlurCamera.RasterBlur(raster, m_nBlurPasses);
if ( m_bGradient )
return m_GradientCamera.RasterGradient(raster);
return raster;
}
RwTexture *
CCutsceneShadow::UpdateForCutscene()
{
Update();
return GetShadowRwTexture();
}
CShadowCamera *
CCutsceneShadow::GetShadowCamera(int32 camType)
{
switch ( camType )
{
case RESAMPLE: return &m_ResampleCamera;
case BLUR: return &m_BlurCamera;
case GRADIENT: return &m_GradientCamera;
}
return &m_Camera;
}
RwTexture *
CCutsceneShadow::GetShadowRwTexture()
{
if ( m_bResample )
return m_ResampleCamera.GetRwRenderTexture();
else
return m_Camera.GetRwRenderTexture();
}
void
CCutsceneShadow::DrawBorderAroundTexture(RwRGBA const& color)
{
if ( m_bResample )
m_ResampleCamera.DrawOutlineBorder(color);
else
m_Camera.DrawOutlineBorder(color);
}

View file

@ -0,0 +1,52 @@
#pragma once
#include "ShadowCamera.h"
class CCutsceneShadow
{
public:
enum
{
RASTER = 0,
RESAMPLE,
BLUR,
GRADIENT,
};
CShadowCamera m_Camera;
bool m_bResample;
CShadowCamera m_ResampleCamera;
int32 m_nBlurPasses;
CShadowCamera m_BlurCamera;
bool m_bGradient;
CShadowCamera m_GradientCamera;
union
{
RwObject *m_pObject;
RpAtomic *m_pAtomic;
RpClump *m_pClump;
};
int32 m_nRwObjectType;
RpLight *m_pLight;
RwSphere m_BoundingSphere;
RwSphere m_BaseSphere;
CCutsceneShadow();
~CCutsceneShadow();
RwSphere GetBaseSphere()
{
return m_BaseSphere;
}
bool Create(RwObject *object, int32 rasterSize, bool resample, int32 blurPasses, bool gradient);
RwFrame *SetLightProperties(float angleY, float angleX, bool setLight);
bool IsInitialized();
void Destroy();
RwRaster *Update();
RwTexture *UpdateForCutscene();
CShadowCamera *GetShadowCamera(int32 camType = RASTER);
RwTexture *GetShadowRwTexture();
void DrawBorderAroundTexture(RwRGBA const& color);
};

View file

@ -7,6 +7,7 @@
#include "Camera.h"
#include "Sprite.h"
#include "Coronas.h"
#include "PointLights.h"
#include "Rubbish.h"
#include "Timecycle.h"
#include "General.h"
@ -391,7 +392,7 @@ void CMovingThings::Init()
CPlaneTrails::Init();
CSmokeTrails::Init();
CPlaneBanners::Init();
CEscalators::Init();
CPointLights::Init();
StartCloseList.m_pNext = &CMovingThings::EndCloseList;
StartCloseList.m_pPrev = nil;
@ -399,6 +400,8 @@ void CMovingThings::Init()
EndCloseList.m_pPrev = &CMovingThings::StartCloseList;
Num = 0;
CEscalators::Init();
#ifndef MIAMI // something is still used here actually
// Initialize scroll bars
aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0f, 0.5f, 0.5f, 255, 128, 0, 0.3f);

View file

@ -255,6 +255,11 @@ CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, u
#endif
}
static uint8 DrunkBlurRed = 128;
static uint8 DrunkBlurGreen = 128;
static uint8 DrunkBlurBlue = 128;
static int32 DrunkBlurIncrement = 1;
void
CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, int32 bluralpha)
{
@ -367,7 +372,36 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
}
}
// TODO(MIAMI): drunkness
int DrunkBlurAlpha = 175.0f * Drunkness;
if(DrunkBlurAlpha != 0){
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
if(BlurOn){
RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, DrunkBlurAlpha);
RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, DrunkBlurAlpha);
RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, DrunkBlurAlpha);
RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, DrunkBlurAlpha);
}else{
RwIm2DVertexSetIntRGBA(&Vertex[0], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
RwIm2DVertexSetIntRGBA(&Vertex[1], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
RwIm2DVertexSetIntRGBA(&Vertex[2], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
RwIm2DVertexSetIntRGBA(&Vertex[3], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha);
if(DrunkBlurIncrement){
if(DrunkBlurRed < 255) DrunkBlurRed++;
if(DrunkBlurGreen < 255) DrunkBlurGreen++;
if(DrunkBlurBlue < 255) DrunkBlurBlue++;
if(DrunkBlurRed == 255)
DrunkBlurIncrement = 0;
}else{
if(DrunkBlurRed > 128) DrunkBlurRed--;
if(DrunkBlurGreen > 128) DrunkBlurGreen--;
if(DrunkBlurBlue > 128) DrunkBlurBlue--;
if(DrunkBlurRed == 128)
DrunkBlurIncrement = 1;
}
}
RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
}
// TODO(MIAMI): OverlayRenderFx

View file

@ -1,6 +1,7 @@
#include "common.h"
#include "main.h"
#include "CutsceneMgr.h"
#include "Lights.h"
#include "Camera.h"
#include "Weather.h"
@ -10,8 +11,23 @@
#include "Timer.h"
#include "PointLights.h"
//--MIAMI: file done
int16 CPointLights::NumLights;
CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS];
CVector CPointLights::aCachedMapReads[32];
float CPointLights::aCachedMapReadResults[32];
int32 CPointLights::NextCachedValue;
void
CPointLights::Init(void)
{
for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++){
aCachedMapReads[i] = CVector(0.0f, 0.0f, 0.0f);
aCachedMapReadResults[i] = 0.0f;
}
NextCachedValue = 0;
}
void
CPointLights::InitPerFrame(void)
@ -86,12 +102,11 @@ CPointLights::GenerateLightsAffectingObject(Const CVector *objCoors)
ret *= distNorm;
}else{
float intensity;
// distance fade
if(distNorm < 0.5f)
// near enough
intensity = 1.0f;
else
// attenuate
intensity = 1.0f - (distNorm - 0.5f)*2.0f;
intensity = 1.0f - (distNorm - 0.5f)/(1.0f - 0.5f);
if(distance != 0.0f){
CVector dir = dist / distance;
@ -143,17 +158,22 @@ CPointLights::RenderFogEffect(void)
CVector spriteCoors;
float spritew, spriteh;
if(CCutsceneMgr::IsRunning())
return;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpPointlightRaster);
CSprite::InitSpriteBuffer();
for(i = 0; i < NumLights; i++){
if(aLights[i].fogType != FOG_NORMAL && aLights[i].fogType != FOG_ALWAYS)
continue;
fogginess = aLights[i].fogType == FOG_ALWAYS ? 1.0f : CWeather::Foggyness;
fogginess = aLights[i].fogType == FOG_NORMAL ? CWeather::Foggyness : 1.0f;
if(fogginess == 0.0f)
continue;
@ -198,7 +218,7 @@ CPointLights::RenderFogEffect(void)
float distsq = sq(dx) + sq(dy);
float linedistsq = distsq - sq(dot);
if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){
CVector fogcoors(xi, yi, aLights[i].coors.z + 1.0f);
CVector fogcoors(xi, yi, aLights[i].coors.z + 10.0f);
if(CWorld::ProcessVerticalLine(fogcoors, fogcoors.z - 20.0f,
point, entity, true, false, false, false, true, false, nil)){
// Now same check again in xyz
@ -220,9 +240,9 @@ CPointLights::RenderFogEffect(void)
intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH);
if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x1FFF;
float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000;
float size = FogSizes[r>>1];
CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255);
@ -234,9 +254,8 @@ CPointLights::RenderFogEffect(void)
}
}else if(aLights[i].type == LIGHT_POINT || aLights[i].type == LIGHT_FOGONLY || aLights[i].type == LIGHT_FOGONLY_ALWAYS){
if(CWorld::ProcessVerticalLine(aLights[i].coors, aLights[i].coors.z - 20.0f,
point, entity, true, false, false, false, true, false, nil)){
float groundZ;
if(ProcessVerticalLineUsingCache(aLights[i].coors, &groundZ)){
xmin = aLights[i].coors.x - FOG_AREA_RADIUS;
ymin = aLights[i].coors.y - FOG_AREA_RADIUS;
xmax = aLights[i].coors.x + FOG_AREA_RADIUS;
@ -267,11 +286,11 @@ CPointLights::RenderFogEffect(void)
// more intensity the closer to light source
intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS);
CVector fogcoors(xi, yi, point.point.z + 1.6f);
CVector fogcoors(xi, yi, groundZ + 1.6f);
if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x3FFF;
float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000;
float size = FogSizes[r>>1];
CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255);
@ -283,4 +302,27 @@ CPointLights::RenderFogEffect(void)
}
}
}
CSprite::FlushSpriteBuffer();
}
bool
CPointLights::ProcessVerticalLineUsingCache(CVector coors, float *groundZ)
{
for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++)
if(aCachedMapReads[i] == coors){
*groundZ = aCachedMapReadResults[i];
return true;
}
CColPoint point;
CEntity *entity;
if(CWorld::ProcessVerticalLine(coors, coors.z - 20.0f, point, entity, true, false, false, false, true, false, nil)){
aCachedMapReads[NextCachedValue] = coors;
aCachedMapReadResults[NextCachedValue] = point.point.z;
NextCachedValue = (NextCachedValue+1) % ARRAY_SIZE(aCachedMapReads);
*groundZ = point.point.z;
return true;
}
return false;
}

View file

@ -20,6 +20,9 @@ class CPointLights
public:
static int16 NumLights;
static CRegisteredPointLight aLights[NUMPOINTLIGHTS];
static CVector aCachedMapReads[32];
static float aCachedMapReadResults[32];
static int32 NextCachedValue;
enum {
LIGHT_POINT,
@ -37,9 +40,11 @@ public:
FOG_ALWAYS
};
static void Init(void);
static void InitPerFrame(void);
static void AddLight(uint8 type, CVector coors, CVector dir, float radius, float red, float green, float blue, uint8 fogType, bool castExtraShadows);
static float GenerateLightsAffectingObject(Const CVector *objCoors);
static void RemoveLightsAffectingObject(void);
static void RenderFogEffect(void);
static bool ProcessVerticalLineUsingCache(CVector coors, float *groundZ);
};

View file

@ -74,8 +74,12 @@ CRenderer::PreRender(void)
for(i = 0; i < ms_nNoOfVisibleEntities; i++)
ms_aVisibleEntityPtrs[i]->PreRender();
for(i = 0; i < ms_nNoOfInVisibleEntities; i++)
for (i = 0; i < ms_nNoOfInVisibleEntities; i++) {
#ifdef SQUEEZE_PERFORMANCE
if (ms_aInVisibleEntityPtrs[i]->IsVehicle() && ((CVehicle*)ms_aInVisibleEntityPtrs[i])->IsHeli())
#endif
ms_aInVisibleEntityPtrs[i]->PreRender();
}
for(node = CVisibilityPlugins::m_alphaEntityList.head.next;
node != &CVisibilityPlugins::m_alphaEntityList.tail;

View file

@ -8,17 +8,18 @@
#include "World.h"
#include "Vehicle.h"
#include "ZoneCull.h"
#include "Stats.h"
#include "TxdStore.h"
#include "RenderBuffer.h"
#include "Rubbish.h"
#define RUBBISH_MAX_DIST (18.0f)
#define RUBBISH_FADE_DIST (16.5f)
//--MIAMI: file done
#define RUBBISH_MAX_DIST (23.0f)
#define RUBBISH_FADE_DIST (20.0f)
RwTexture *gpRubbishTexture[4];
RwImVertexIndex RubbishIndexList[6];
RwImVertexIndex RubbishIndexList2[6]; // unused
RwIm3DVertex RubbishVertices[4];
bool CRubbish::bRubbishInvisible;
int CRubbish::RubbishVisibility;
COneSheet CRubbish::aSheets[NUM_RUBBISH_SHEETS];
@ -52,12 +53,16 @@ CRubbish::Render(void)
{
int type;
if(RubbishVisibility == 0)
return;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
for(type = 0; type < 4; type++){
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
if(type < 3 || CStats::PamphletMissionPassed)
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRubbishTexture[type]));
TempBufferIndicesStored = 0;
TempBufferVerticesStored = 0;
@ -69,7 +74,7 @@ CRubbish::Render(void)
if(sheet->m_state == 0)
continue;
uint32 alpha = 128;
uint32 alpha = 100;
CVector pos;
if(sheet->m_state == 1){
pos = sheet->m_basePos;
@ -82,7 +87,7 @@ CRubbish::Render(void)
float t = (float)(CTimer::GetTimeInMilliseconds() - sheet->m_moveStart)/sheet->m_moveDuration;
float f1 = sheet->m_isVisible ? 1.0f-t : 0.0f;
float f2 = sheet->m_targetIsVisible ? t : 0.0f;
alpha = 128 * (f1+f2);
alpha = 100 * (f1+f2);
}
}
@ -92,17 +97,27 @@ CRubbish::Render(void)
alpha -= alpha*(camDist-RUBBISH_FADE_DIST)/(RUBBISH_MAX_DIST-RUBBISH_FADE_DIST);
alpha = (RubbishVisibility*alpha)/256;
float vx = Sin(sheet->m_angle) * 0.4f;
float vy = Cos(sheet->m_angle) * 0.4f;
float vx1, vy1, vx2, vy2;
if(type == 0 || type == 1){
vx1 = 0.9f*Sin(sheet->m_angle);
vy1 = 0.9f*Cos(sheet->m_angle);
vx2 = 0.3f*Cos(sheet->m_angle);
vy2 = -0.3f*Sin(sheet->m_angle);
}else{
vx1 = 0.3f*Sin(sheet->m_angle);
vy1 = 0.3f*Cos(sheet->m_angle);
vx2 = 0.3f*Cos(sheet->m_angle);
vy2 = -0.3f*Sin(sheet->m_angle);
}
int v = TempBufferVerticesStored;
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx, pos.y + vy, pos.z);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+0], pos.x + vx1 + vx2, pos.y + vy1 + vy2, pos.z);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x + vx1 - vx2, pos.y + vy1 - vy2, pos.z);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x - vx1 + vx2, pos.y - vy1 + vy2, pos.z);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx1 - vx2, pos.y - vy1 - vy2, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+0], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+1], pos.x - vy, pos.y + vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+1], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+2], pos.x + vy, pos.y - vx, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+2], 255, 255, 255, alpha);
RwIm3DVertexSetPos(&TempBufferRenderVertices[v+3], pos.x - vx, pos.y - vy, pos.z);
RwIm3DVertexSetRGBA(&TempBufferRenderVertices[v+3], 255, 255, 255, alpha);
RwIm3DVertexSetU(&TempBufferRenderVertices[v+0], 0.0f);
RwIm3DVertexSetV(&TempBufferRenderVertices[v+0], 0.0f);
@ -373,24 +388,6 @@ CRubbish::Init(void)
EndMoversList.m_next = nil;
EndMoversList.m_prev = &StartMoversList;
// unused
RwIm3DVertexSetU(&RubbishVertices[0], 0.0f);
RwIm3DVertexSetV(&RubbishVertices[0], 0.0f);
RwIm3DVertexSetU(&RubbishVertices[1], 1.0f);
RwIm3DVertexSetV(&RubbishVertices[1], 0.0f);
RwIm3DVertexSetU(&RubbishVertices[2], 0.0f);
RwIm3DVertexSetV(&RubbishVertices[2], 1.0f);
RwIm3DVertexSetU(&RubbishVertices[3], 1.0f);
RwIm3DVertexSetV(&RubbishVertices[3], 1.0f);
// unused
RubbishIndexList2[0] = 0;
RubbishIndexList2[1] = 2;
RubbishIndexList2[2] = 1;
RubbishIndexList2[3] = 1;
RubbishIndexList2[4] = 2;
RubbishIndexList2[5] = 3;
RubbishIndexList[0] = 0;
RubbishIndexList[1] = 1;
RubbishIndexList[2] = 2;
@ -414,19 +411,11 @@ void
CRubbish::Shutdown(void)
{
RwTextureDestroy(gpRubbishTexture[0]);
#ifdef GTA3_1_1_PATCH
gpRubbishTexture[0] = nil;
#endif
RwTextureDestroy(gpRubbishTexture[1]);
#ifdef GTA3_1_1_PATCH
gpRubbishTexture[1] = nil;
#endif
RwTextureDestroy(gpRubbishTexture[2]);
#ifdef GTA3_1_1_PATCH
gpRubbishTexture[2] = nil;
#endif
RwTextureDestroy(gpRubbishTexture[3]);
#ifdef GTA3_1_1_PATCH
gpRubbishTexture[3] = nil;
#endif
}

View file

@ -4,7 +4,11 @@ class CVehicle;
enum {
// NB: not all values are allowed, check the code
#ifdef SQUEEZE_PERFORMANCE
NUM_RUBBISH_SHEETS = 32
#else
NUM_RUBBISH_SHEETS = 64
#endif
};
class COneSheet

549
src/render/ShadowCamera.cpp Normal file
View file

@ -0,0 +1,549 @@
#include "common.h"
#include "rwcore.h"
#include "ShadowCamera.h"
#include "RwHelper.h"
#define TEXELOFFSET 0.5f
RpAtomic *ShadowRenderCallBack(RpAtomic *atomic, void *data)
{
RpAtomicCallBackRender savedCB = RpAtomicGetRenderCallBack(atomic);
RpAtomicSetRenderCallBack(atomic, AtomicDefaultRenderCallBack);
RpAtomicRender(atomic);
RpAtomicSetRenderCallBack(atomic, savedCB);
return atomic;
}
CShadowCamera::CShadowCamera()
{
m_pCamera = nil;
m_pTexture = nil;
}
CShadowCamera::~CShadowCamera()
{
Destroy();
}
void
CShadowCamera::Destroy()
{
if ( m_pCamera )
{
RwRaster *raster;
RwFrame *frame;
frame = RwCameraGetFrame(m_pCamera);
if ( frame )
{
RwCameraSetFrame(m_pCamera, nil);
RwFrameDestroy(frame);
}
raster = RwCameraGetZRaster(m_pCamera);
if ( raster )
{
RwCameraSetZRaster(m_pCamera, nil);
RwRasterDestroy(raster);
}
raster = RwCameraGetRaster(m_pCamera);
if ( raster )
{
RwCameraSetRaster(m_pCamera, nil);
RwRasterDestroy(raster);
}
if ( m_pTexture )
{
RwTextureSetRaster(m_pTexture, nil);
RwTextureDestroy(m_pTexture);
m_pTexture = nil;
}
RwCameraDestroy(m_pCamera);
m_pCamera = nil;
}
return;
}
RwCamera *
CShadowCamera::Create(int32 rasterSize)
{
int32 size = 1 << rasterSize;
m_pCamera = RwCameraCreate();
ASSERT(m_pCamera != nil);
if ( m_pCamera )
{
RwCameraSetFrame(m_pCamera, RwFrameCreate());
if( RwCameraGetFrame(m_pCamera) )
{
RwRaster *zRaster = RwRasterCreate(size, size, 0, rwRASTERTYPEZBUFFER);
ASSERT(zRaster != nil);
if ( zRaster )
{
RwCameraSetZRaster(m_pCamera, zRaster);
RwRaster *raster = RwRasterCreate(size, size, 0, rwRASTERTYPECAMERATEXTURE);
ASSERT(raster != nil);
if ( raster )
{
RwCameraSetRaster(m_pCamera, raster);
m_pTexture = RwTextureCreate(raster);
ASSERT(m_pTexture != nil);
if ( m_pTexture )
{
RwTextureSetAddressing(m_pTexture, rwTEXTUREADDRESSCLAMP);
RwTextureSetFilterMode(m_pTexture, rwFILTERLINEAR);
RwCameraSetProjection(m_pCamera, rwPARALLEL);
return (m_pCamera);
}
}
}
}
}
Destroy();
return (nil);
}
RwCamera *
CShadowCamera::SetFrustum(float objectRadius)
{
ASSERT(m_pCamera != nil);
RwV2d vw;
RwCameraSetFarClipPlane (m_pCamera, 2.0f * objectRadius);
RwCameraSetNearClipPlane(m_pCamera, 0.001f * objectRadius);
vw.x = objectRadius;
vw.y = objectRadius;
RwCameraSetViewWindow(m_pCamera, &vw);
return m_pCamera;
}
RwCamera *
CShadowCamera::SetLight(RpLight *light)
{
ASSERT(light != nil);
ASSERT(m_pCamera != nil);
RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
RwFrame *lightFrame = RpLightGetFrame(light);
RwMatrix *lightMatrix = RwFrameGetMatrix(lightFrame);
*RwMatrixGetRight(camMatrix) = *RwMatrixGetRight(lightMatrix);
*RwMatrixGetUp(camMatrix) = *RwMatrixGetUp(lightMatrix);
*RwMatrixGetAt(camMatrix) = *RwMatrixGetAt(lightMatrix);
RwMatrixUpdate(camMatrix);
RwFrameUpdateObjects(camFrame);
return m_pCamera;
}
RwCamera *
CShadowCamera::SetCenter(RwV3d *center)
{
ASSERT(center != nil);
ASSERT(m_pCamera != nil);
RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
*RwMatrixGetPos(camMatrix) = *center;
RwV3dIncrementScaled(RwMatrixGetPos(camMatrix), RwMatrixGetAt(camMatrix), -0.5f * RwCameraGetFarClipPlane(m_pCamera));
RwMatrixUpdate(camMatrix);
RwFrameUpdateObjects(camFrame);
RwFrameOrthoNormalize(camFrame);
return m_pCamera;
}
RwCamera *
CShadowCamera::Update(RpClump *clump)
{
ASSERT(clump != nil);
ASSERT(m_pCamera != nil);
RwUInt32 flags;
RpGeometry *geometry;
RwRGBA bgColor = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
if ( RwCameraBeginUpdate(m_pCamera) )
{
geometry = GetFirstAtomic(clump)->geometry;
ASSERT(geometry != nil);
flags = RpGeometryGetFlags(geometry);
RpGeometrySetFlags(geometry, flags & ~(rpGEOMETRYPRELIT|rpGEOMETRYLIGHT
|rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2|rpGEOMETRYMODULATEMATERIALCOLOR));
RpClumpForAllAtomics(clump, ShadowRenderCallBack, nil);
RpGeometrySetFlags(geometry, flags);
InvertRaster();
RwCameraEndUpdate(m_pCamera);
}
return m_pCamera;
}
RwCamera *
CShadowCamera::Update(RpAtomic *atomic)
{
ASSERT(atomic != nil);
ASSERT(m_pCamera != nil);
RwUInt32 flags;
RpGeometry *geometry;
RwRGBA bgColor = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
if ( RwCameraBeginUpdate(m_pCamera) )
{
geometry = RpAtomicGetGeometry(atomic);
ASSERT(geometry != nil);
flags = RpGeometryGetFlags(geometry);
RpGeometrySetFlags(geometry, flags & ~(rpGEOMETRYPRELIT|rpGEOMETRYLIGHT
|rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYNORMALS));
ShadowRenderCallBack(atomic, nil);
RpGeometrySetFlags(geometry, flags);
InvertRaster();
RwCameraEndUpdate(m_pCamera);
}
return m_pCamera;
}
void
CShadowCamera::InvertRaster()
{
ASSERT(m_pCamera != nil);
RwIm2DVertex vx[4];
float crw, crh;
RwRaster *raster;
float recipZ;
raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != nil);
crw = (float)RwRasterGetWidth(raster);
crh = (float)RwRasterGetHeight(raster);
recipZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwIm2DVertexSetScreenX (&vx[0], 0.0f);
RwIm2DVertexSetScreenY (&vx[0], 0.0f);
RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[0], recipZ);
RwIm2DVertexSetIntRGBA (&vx[0], 255, 255, 255, 255);
RwIm2DVertexSetScreenX (&vx[1], 0.0f);
RwIm2DVertexSetScreenY (&vx[1], crh);
RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[1], recipZ);
RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255);
RwIm2DVertexSetScreenX (&vx[2], crw);
RwIm2DVertexSetScreenY (&vx[2], 0.0f);
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ);
RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255);
RwIm2DVertexSetScreenX (&vx[3], crw);
RwIm2DVertexSetScreenY (&vx[3], crh);
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ);
RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)nil);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
}
RwRaster *
CShadowCamera::MakeGradientRaster()
{
ASSERT(m_pCamera != nil);
RwIm2DVertex vx[2];
if ( !m_pCamera )
return nil;
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != nil);
float width = (float)RwRasterGetWidth(raster);
float height = (float)RwRasterGetHeight(raster);
if ( height < 1 )
return nil;
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)rwFILTERNAFILTERMODE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void *)rwSHADEMODEFLAT);
float color = 255.0f;
float step = (-191.0f / height);
for ( int32 i = 0; i < height; i++ )
{
RwIm2DVertexSetScreenX (&vx[0], 0.0f);
RwIm2DVertexSetScreenY (&vx[0], i);
RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
RwIm2DVertexSetIntRGBA (&vx[0], (uint32)color, (uint32)color, (uint32)color, (uint32)color);
RwIm2DVertexSetScreenX (&vx[1], width - 1);
RwIm2DVertexSetScreenY (&vx[1], i);
RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
RwIm2DVertexSetIntRGBA (&vx[1], (uint32)color, (uint32)color, (uint32)color, (uint32)color);
RwIm2DRenderLine(vx, 2, 0, 1);
color += step;
}
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void *)rwSHADEMODEGOURAUD);
RwCameraEndUpdate(m_pCamera);
}
return raster;
}
RwRaster *
CShadowCamera::RasterResample(RwRaster *dstRaster)
{
ASSERT(dstRaster != nil);
ASSERT(m_pCamera != nil);
if ( !m_pCamera )
return nil;
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != nil);
float size = (float) RwRasterGetWidth(raster);
float uvOffset = TEXELOFFSET / size;
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)dstRaster);
Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, uvOffset);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
RwCameraEndUpdate(m_pCamera);
}
return raster;
}
RwRaster *
CShadowCamera::RasterBlur(RwRaster *dstRaster, int32 numPasses)
{
ASSERT(dstRaster != nil);
ASSERT(m_pCamera != nil);
if ( !m_pCamera )
return nil;
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != nil);
float size = (float) RwRasterGetWidth(dstRaster);
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
for (int i = 0; i < numPasses; i++ )
{
RwCameraSetRaster(m_pCamera, raster);
if ( RwCameraBeginUpdate(m_pCamera) )
{
if ( i == 0 )
{
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
}
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)dstRaster);
Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 1.0f / size);
RwCameraEndUpdate(m_pCamera);
}
RwCameraSetRaster(m_pCamera, dstRaster);
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)raster);
Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 0);
if ( i == numPasses - 1 )
{
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
}
RwCameraEndUpdate(m_pCamera);
}
}
RwCameraSetRaster(m_pCamera, raster);
return dstRaster;
}
RwRaster *
CShadowCamera::RasterGradient(RwRaster *dstRaster)
{
ASSERT(dstRaster != nil);
ASSERT(m_pCamera != nil);
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != nil);
float size = (float)RwRasterGetWidth(dstRaster);
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwCameraSetRaster(m_pCamera, dstRaster);
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDSRCCOLOR);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)raster);
Im2DRenderQuad(0, 0, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 0);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
RwCameraEndUpdate(m_pCamera);
}
RwCameraSetRaster(m_pCamera, raster);
return dstRaster;
}
RwRaster *CShadowCamera::DrawOutlineBorder(RwRGBA const& color)
{
ASSERT(m_pCamera != nil);
RwIm2DVertex vx[4];
RwImVertexIndex ix[5];
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != nil);
float size = (float)RwRasterGetWidth(raster) - 1.0f;
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwIm2DVertexSetScreenX (&vx[0], 0.0f);
RwIm2DVertexSetScreenY (&vx[0], 0.0f);
RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[0], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
RwIm2DVertexSetScreenX (&vx[1], size);
RwIm2DVertexSetScreenY (&vx[1], 0.0f);
RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[1], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
RwIm2DVertexSetScreenX (&vx[2], size);
RwIm2DVertexSetScreenY (&vx[2], size);
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[2], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
RwIm2DVertexSetScreenX (&vx[3], 0.0f);
RwIm2DVertexSetScreenY (&vx[3], size);
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[3], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
ix[0] = 0;
ix[4] = 0;
ix[1] = 1;
ix[2] = 2;
ix[3] = 3;
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)nil);
RwIm2DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, vx, 4, ix, 5);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
RwCameraEndUpdate(m_pCamera);
}
return raster;
}

54
src/render/ShadowCamera.h Normal file
View file

@ -0,0 +1,54 @@
#pragma once
class CShadowCamera
{
public:
RwCamera *m_pCamera;
RwTexture *m_pTexture;
CShadowCamera();
~CShadowCamera();
RwCamera *Create(int32 rasterSize);
void Destroy();
RwCamera *SetFrustum(float objectRadius);
RwCamera *SetLight(RpLight *light);
RwCamera *SetCenter(RwV3d *center);
RwCamera *Update(RpClump *clump);
RwCamera *Update(RpAtomic *atomic);
void InvertRaster();
RwRaster* GetRwRenderRaster()
{
return RwCameraGetRaster(m_pCamera);
}
// ShadowRasterRender(RwV2d *)
// ApplyAlphaMapToRaster(void)
RwRaster *MakeGradientRaster();
RwTexture *GetRwRenderTexture()
{
return m_pTexture;
}
RwRaster* GetRwZRaster()
{
return RwCameraGetZRaster(m_pCamera);
}
RwRaster *RasterResample(RwRaster *dstRaster);
RwRaster *RasterBlur(RwRaster *dstRaster, int32 numPasses);
RwRaster *RasterGradient(RwRaster *dstRaster);
RwRaster *DrawOutlineBorder(RwRGBA const& color);
RwCamera *GetRwCamera()
{
return m_pCamera;
}
};

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,19 @@
#pragma once
#define MAX_STOREDSHADOWS 48
#define MAX_POLYBUNCHES 300
#define MAX_STATICSHADOWS 64
#define MAX_POLYBUNCHES 380
#define MAX_STATICSHADOWS 48
#define MAX_PERMAMENTSHADOWS 48
class CEntity;
class CPtrList;
class CAutomobile;
class CVehicle;
class CPed;
class CCutsceneShadow;
class CCutsceneObject;
enum eShadowType
{
@ -27,6 +34,16 @@ enum eShadowTextureType
SHADOWTEX_BLOOD
};
enum VEH_SHD_TYPE
{
VEH_SHD_TYPE_CAR = 0,
VEH_SHD_TYPE_BIKE,
VEH_SHD_TYPE_HELI,
VEH_SHD_TYPE_SEAPLANE,
VEH_SHD_TYPE_RCPLANE,
};
class CStoredShadow
{
public:
@ -35,6 +52,8 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
RwTexture *m_pTexture;
CCutsceneShadow *m_pCutsceneShadow;
int16 m_nIntensity;
uint8 m_ShadowType;
uint8 m_nRed;
@ -44,9 +63,9 @@ public:
{
uint8 bDrawOnWater : 1;
uint8 bRendered : 1;
//uint8 bDrawOnBuildings : 1;
uint8 bDrawOnBuildings : 1;
} m_nFlags;
RwTexture *m_pTexture;
CStoredShadow()
{ }
@ -57,11 +76,11 @@ VALIDATE_SIZE(CStoredShadow, 0x30);
class CPolyBunch
{
public:
int16 m_nNumVerts;
CVector m_aVerts[7];
CPolyBunch *m_pNext;
int16 m_nNumVerts;
uint8 m_aU[7];
uint8 m_aV[7];
CPolyBunch *m_pNext;
CPolyBunch()
{ }
@ -80,15 +99,16 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
uint8 m_nType;
RwTexture *m_pTexture;
int16 m_nIntensity; // unsigned ?
uint8 m_nType;
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
bool m_bJustCreated;
bool m_bRendered;
bool m_bTemp;
RwTexture *m_pTexture;
CStaticShadow()
{ }
@ -106,14 +126,14 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
uint32 m_nTimeCreated;
uint32 m_nLifeTime;
RwTexture *m_pTexture;
int16 m_nIntensity;
uint8 m_nType; // eShadowType
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
uint32 m_nTimeCreated;
uint32 m_nLifeTime;
RwTexture *m_pTexture;
CPermanentShadow()
{ }
@ -121,60 +141,62 @@ public:
VALIDATE_SIZE(CPermanentShadow, 0x38);
class CPtrList;
class CAutomobile;
class CPed;
class CShadows
{
public:
#if 1
static int16 ShadowsStoredToBeRendered;
static CStoredShadow asShadowsStored [MAX_STOREDSHADOWS];
static CPolyBunch aPolyBunches [MAX_POLYBUNCHES];
static CStaticShadow aStaticShadows [MAX_STATICSHADOWS];
static CPolyBunch *pEmptyBunchList;
static CPermanentShadow aPermanentShadows[MAX_PERMAMENTSHADOWS];
#else
static int16 &ShadowsStoredToBeRendered;
static CStoredShadow (&asShadowsStored) [MAX_STOREDSHADOWS];
static CPolyBunch (&aPolyBunches) [MAX_POLYBUNCHES];
static CStaticShadow (&aStaticShadows) [MAX_STATICSHADOWS];
static CPolyBunch *&pEmptyBunchList;
static CPermanentShadow (&aPermanentShadows)[MAX_PERMAMENTSHADOWS];
#endif
static void Init (void);
static void Shutdown (void);
static void AddPermanentShadow ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, uint32 nTime, float fScale);
static void StoreStaticShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance);
static void StoreShadowToBeRendered ( uint8 ShadowType, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue);
static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale);
static void StoreShadowForCar (CAutomobile *pCar);
static void StoreCarLightShadow (CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
static void StoreShadowForPed (CPed *pPed, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForPedObject (CEntity *pPedObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForTree (CEntity *pTree);
static void StoreShadowForPole (CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ, float fPoleHeight, float fPoleWidth, uint32 nID);
static void SetRenderModeForShadowType (uint8 ShadowType);
static void RenderStoredShadows (void);
static void RenderStaticShadows (void);
static void GeneratePolysForStaticShadow (int16 nStaticShadowID);
static void CastShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
static void Init (void);
static void Shutdown (void);
static void AddPermanentShadow ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, uint32 nTime, float fScale);
static bool StoreStaticShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance);
static void StoreShadowToBeRendered ( uint8 ShadowType, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue);
static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale, CCutsceneShadow *pShadow, bool bDrawOnBuildings);
static void StoreShadowForVehicle (CVehicle *pCar, VEH_SHD_TYPE type);
static void StoreCarLightShadow (CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
static void StoreShadowForPed (CPed *pPed, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForPedObject (CEntity *pPedObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForCutscenePedObject(CCutsceneObject *pObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForTree (CEntity *pTree);
static void StoreShadowForPole (CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ, float fPoleHeight, float fPoleWidth, uint32 nID);
static void SetRenderModeForShadowType (uint8 ShadowType);
static void RenderStoredShadows (void);
static void RenderStaticShadows (void);
static void GeneratePolysForStaticShadow (int16 nStaticShadowID);
static void CastShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
static void CastShadowEntity (CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY,
static void CastPlayerShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
static void CastCutsceneShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow);
static void CastShadowEntityXY (CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
static void UpdateStaticShadows (void);
static void UpdatePermanentShadows (void);
static void CalcPedShadowValues (CVector vecLightDir, float *pfDisplacementX, float *pfDisplacementY, float *pfFrontX, float *pfFrontY, float *pfSideX, float *pfSideY);
static void RenderExtraPlayerShadows (void);
static void TidyUpShadows (void);
static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
static void CastShadowEntityXYZ (CEntity *pEntity, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow);
static void UpdateStaticShadows (void);
static void UpdatePermanentShadows (void);
static void CalcPedShadowValues (CVector vecLightDir, float *pfFrontX, float *pfFrontY, float *pfSideX, float *pfSideY, float *pfDisplacementX, float *pfDisplacementY);
static void RenderExtraPlayerShadows (void);
static void TidyUpShadows (void);
static void RenderIndicatorShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity);
};
extern RwTexture *gpShadowCarTex;
extern RwTexture *gpShadowPedTex;
extern RwTexture *gpShadowHeliTex;
extern RwTexture *gpShadowBikeTex;
extern RwTexture *gpShadowBaronTex;
extern RwTexture *gpShadowExplosionTex;
extern RwTexture *gpShadowHeadLightsTex;
extern RwTexture *gpOutline1Tex;
@ -182,7 +204,6 @@ extern RwTexture *gpOutline2Tex;
extern RwTexture *gpOutline3Tex;
extern RwTexture *gpBloodPoolTex;
extern RwTexture *gpReflectionTex;
extern RwTexture *gpGoalMarkerTex;
extern RwTexture *gpWalkDontTex;
extern RwTexture *gpCrackedGlassTex;
extern RwTexture *gpPostShadowTex;

View file

@ -6,6 +6,8 @@
#include "Replay.h"
#include "Skidmarks.h"
//--MIAMI: file done
CSkidmark CSkidmarks::aSkidmarks[NUMSKIDMARKS];
RwImVertexIndex SkidmarkIndexList[SKIDMARK_LENGTH * 6];
@ -37,13 +39,6 @@ CSkidmarks::Init(void)
SkidmarkIndexList[i*6+5] = ix+3;
ix += 2;
}
for(i = 0; i < SKIDMARK_LENGTH; i++){
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 0], 0.0f);
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 0], i*5.01f);
RwIm3DVertexSetU(&SkidmarkVertices[i*2 + 1], 1.0f);
RwIm3DVertexSetV(&SkidmarkVertices[i*2 + 1], i*5.01f);
}
}
void
@ -141,8 +136,12 @@ CSkidmarks::Render(void)
p2.y -= aSkidmarks[i].m_sideY[j];
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+0], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+0], p1.x, p1.y, p1.z+0.1f);
RwIm3DVertexSetU(&SkidmarkVertices[j*2+0], 0.0f);
RwIm3DVertexSetV(&SkidmarkVertices[j*2+0], j*5.01f);
RwIm3DVertexSetRGBA(&SkidmarkVertices[j*2+1], color.red, color.green, color.blue, alpha);
RwIm3DVertexSetPos(&SkidmarkVertices[j*2+1], p2.x, p2.y, p2.z+0.1f);
RwIm3DVertexSetU(&SkidmarkVertices[j*2+1], 1.0f);
RwIm3DVertexSetV(&SkidmarkVertices[j*2+1], j*5.01f);
}
LittleTest();

View file

@ -10,60 +10,60 @@
#include "FileMgr.h"
#include "Timecycle.h"
// TODO(MIAMI): change some of the types here
//--MIAMI: done
int CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fSunSize[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
short CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
short CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
short CTimeCycle::m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
int CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fWaterRed[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fWaterGreen[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fWaterBlue[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
int8 CTimeCycle::m_fSunSize[NUMHOURS][NUMWEATHERS];
int8 CTimeCycle::m_fSpriteSize[NUMHOURS][NUMWEATHERS];
int8 CTimeCycle::m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nShadowStrength[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
int16 CTimeCycle::m_fFogStart[NUMHOURS][NUMWEATHERS];
int16 CTimeCycle::m_fFarClip[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fBlurRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fBlurGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fBlurBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fWaterRed[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fWaterGreen[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fWaterBlue[NUMHOURS][NUMWEATHERS];
uint8 CTimeCycle::m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
float CTimeCycle::m_fCurrentAmbientRed;
@ -81,36 +81,36 @@ float CTimeCycle::m_fCurrentAmbientBlue_Obj_Bl;
float CTimeCycle::m_fCurrentDirectionalRed;
float CTimeCycle::m_fCurrentDirectionalGreen;
float CTimeCycle::m_fCurrentDirectionalBlue;
int CTimeCycle::m_nCurrentSkyTopRed;
int CTimeCycle::m_nCurrentSkyTopGreen;
int CTimeCycle::m_nCurrentSkyTopBlue;
int CTimeCycle::m_nCurrentSkyBottomRed;
int CTimeCycle::m_nCurrentSkyBottomGreen;
int CTimeCycle::m_nCurrentSkyBottomBlue;
int CTimeCycle::m_nCurrentSunCoreRed;
int CTimeCycle::m_nCurrentSunCoreGreen;
int CTimeCycle::m_nCurrentSunCoreBlue;
int CTimeCycle::m_nCurrentSunCoronaRed;
int CTimeCycle::m_nCurrentSunCoronaGreen;
int CTimeCycle::m_nCurrentSunCoronaBlue;
int32 CTimeCycle::m_nCurrentSkyTopRed;
int32 CTimeCycle::m_nCurrentSkyTopGreen;
int32 CTimeCycle::m_nCurrentSkyTopBlue;
int32 CTimeCycle::m_nCurrentSkyBottomRed;
int32 CTimeCycle::m_nCurrentSkyBottomGreen;
int32 CTimeCycle::m_nCurrentSkyBottomBlue;
int32 CTimeCycle::m_nCurrentSunCoreRed;
int32 CTimeCycle::m_nCurrentSunCoreGreen;
int32 CTimeCycle::m_nCurrentSunCoreBlue;
int32 CTimeCycle::m_nCurrentSunCoronaRed;
int32 CTimeCycle::m_nCurrentSunCoronaGreen;
int32 CTimeCycle::m_nCurrentSunCoronaBlue;
float CTimeCycle::m_fCurrentSunSize;
float CTimeCycle::m_fCurrentSpriteSize;
float CTimeCycle::m_fCurrentSpriteBrightness;
int CTimeCycle::m_nCurrentShadowStrength;
int CTimeCycle::m_nCurrentLightShadowStrength;
int CTimeCycle::m_nCurrentPoleShadowStrength;
int32 CTimeCycle::m_nCurrentShadowStrength;
int32 CTimeCycle::m_nCurrentLightShadowStrength;
int32 CTimeCycle::m_nCurrentPoleShadowStrength;
float CTimeCycle::m_fCurrentFogStart;
float CTimeCycle::m_fCurrentFarClip;
float CTimeCycle::m_fCurrentLightsOnGroundBrightness;
int CTimeCycle::m_nCurrentLowCloudsRed;
int CTimeCycle::m_nCurrentLowCloudsGreen;
int CTimeCycle::m_nCurrentLowCloudsBlue;
int CTimeCycle::m_nCurrentFluffyCloudsTopRed;
int CTimeCycle::m_nCurrentFluffyCloudsTopGreen;
int CTimeCycle::m_nCurrentFluffyCloudsTopBlue;
int CTimeCycle::m_nCurrentFluffyCloudsBottomRed;
int CTimeCycle::m_nCurrentFluffyCloudsBottomGreen;
int CTimeCycle::m_nCurrentFluffyCloudsBottomBlue;
int32 CTimeCycle::m_nCurrentLowCloudsRed;
int32 CTimeCycle::m_nCurrentLowCloudsGreen;
int32 CTimeCycle::m_nCurrentLowCloudsBlue;
int32 CTimeCycle::m_nCurrentFluffyCloudsTopRed;
int32 CTimeCycle::m_nCurrentFluffyCloudsTopGreen;
int32 CTimeCycle::m_nCurrentFluffyCloudsTopBlue;
int32 CTimeCycle::m_nCurrentFluffyCloudsBottomRed;
int32 CTimeCycle::m_nCurrentFluffyCloudsBottomGreen;
int32 CTimeCycle::m_nCurrentFluffyCloudsBottomBlue;
float CTimeCycle::m_fCurrentBlurRed;
float CTimeCycle::m_fCurrentBlurGreen;
float CTimeCycle::m_fCurrentBlurBlue;
@ -118,13 +118,16 @@ float CTimeCycle::m_fCurrentWaterRed;
float CTimeCycle::m_fCurrentWaterGreen;
float CTimeCycle::m_fCurrentWaterBlue;
float CTimeCycle::m_fCurrentWaterAlpha;
int CTimeCycle::m_nCurrentFogColourRed;
int CTimeCycle::m_nCurrentFogColourGreen;
int CTimeCycle::m_nCurrentFogColourBlue;
int32 CTimeCycle::m_nCurrentFogColourRed;
int32 CTimeCycle::m_nCurrentFogColourGreen;
int32 CTimeCycle::m_nCurrentFogColourBlue;
int CTimeCycle::m_FogReduction;
int32 CTimeCycle::m_FogReduction;
bool CTimeCycle::m_bExtraColourOn;
int32 CTimeCycle::m_ExtraColour;
float CTimeCycle::m_ExtraColourInter;
int CTimeCycle::m_CurrentStoredValue;
int32 CTimeCycle::m_CurrentStoredValue;
CVector CTimeCycle::m_VectorToSun[16];
float CTimeCycle::m_fShadowFrontX[16];
float CTimeCycle::m_fShadowFrontY[16];
@ -133,7 +136,6 @@ float CTimeCycle::m_fShadowSideY[16];
float CTimeCycle::m_fShadowDisplacementX[16];
float CTimeCycle::m_fShadowDisplacementY[16];
void
CTimeCycle::Initialise(void)
{
@ -233,15 +235,15 @@ CTimeCycle::Initialise(void)
m_nSunCoronaRed[h][w] = sunCoronaR;
m_nSunCoronaGreen[h][w] = sunCoronaG;
m_nSunCoronaBlue[h][w] = sunCoronaB;
m_fSunSize[h][w] = sunSz;
m_fSpriteSize[h][w] = sprSz;
m_fSpriteBrightness[h][w] = sprBght;
m_fSunSize[h][w] = sunSz * 10.0f;
m_fSpriteSize[h][w] = sprSz * 10.0f;
m_fSpriteBrightness[h][w] = sprBght * 10.0f;
m_nShadowStrength[h][w] = shad;
m_nLightShadowStrength[h][w] = lightShad;
m_nPoleShadowStrength[h][w] = poleShad;
m_fFarClip[h][w] = farClp;
m_fFogStart[h][w] = fogSt;
m_fLightsOnGroundBrightness[h][w] = lightGnd;
m_fLightsOnGroundBrightness[h][w] = lightGnd * 10.0f;
m_nLowCloudsRed[h][w] = cloudR;
m_nLowCloudsGreen[h][w] = cloudG;
m_nLowCloudsBlue[h][w] = cloudB;
@ -265,6 +267,51 @@ CTimeCycle::Initialise(void)
debug("CTimeCycle ready\n");
}
static float interp_c0, interp_c1, interp_c2, interp_c3;
float CTimeCycle::Interpolate(int8 *a, int8 *b)
{
return a[CWeather::OldWeatherType] * interp_c0 +
b[CWeather::OldWeatherType] * interp_c1 +
a[CWeather::NewWeatherType] * interp_c2 +
b[CWeather::NewWeatherType] * interp_c3;
}
float CTimeCycle::Interpolate(uint8 *a, uint8 *b)
{
return a[CWeather::OldWeatherType] * interp_c0 +
b[CWeather::OldWeatherType] * interp_c1 +
a[CWeather::NewWeatherType] * interp_c2 +
b[CWeather::NewWeatherType] * interp_c3;
}
float CTimeCycle::Interpolate(int16 *a, int16 *b)
{
return a[CWeather::OldWeatherType] * interp_c0 +
b[CWeather::OldWeatherType] * interp_c1 +
a[CWeather::NewWeatherType] * interp_c2 +
b[CWeather::NewWeatherType] * interp_c3;
}
void
CTimeCycle::StartExtraColour(int32 c, bool fade)
{
m_bExtraColourOn = true;
m_ExtraColour = c;
if(fade)
m_ExtraColourInter = 0.0f;
else
m_ExtraColourInter = 1.0f;
}
void
CTimeCycle::StopExtraColour(bool fade)
{
m_bExtraColourOn = false;
if(!fade)
m_ExtraColourInter = 0.0f;
}
void
CTimeCycle::Update(void)
{
@ -274,12 +321,12 @@ CTimeCycle::Update(void)
int w2 = CWeather::NewWeatherType;
float timeInterp = (CClock::GetMinutes() + CClock::GetSeconds()/60.0f)/60.0f;
// coefficients for a bilinear interpolation
float c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
float c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
float c2 = (1.0f-timeInterp) * CWeather::InterpolationValue;
float c3 = timeInterp * CWeather::InterpolationValue;
interp_c0 = (1.0f-timeInterp) * (1.0f-CWeather::InterpolationValue);
interp_c1 = timeInterp * (1.0f-CWeather::InterpolationValue);
interp_c2 = (1.0f-timeInterp) * CWeather::InterpolationValue;
interp_c3 = timeInterp * CWeather::InterpolationValue;
#define INTERP(v) v[h1][w1]*c0 + v[h2][w1]*c1 + v[h1][w2]*c2 + v[h2][w2]*c3;
#define INTERP(v) Interpolate(v[h1], v[h2])
m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed);
m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen);
@ -317,15 +364,15 @@ CTimeCycle::Update(void)
m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen);
m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue);
m_fCurrentSunSize = INTERP(m_fSunSize);
m_fCurrentSpriteSize = INTERP(m_fSpriteSize);
m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness);
m_fCurrentSunSize = INTERP(m_fSunSize)/10.0f;
m_fCurrentSpriteSize = INTERP(m_fSpriteSize)/10.0f;
m_fCurrentSpriteBrightness = INTERP(m_fSpriteBrightness)/10.0f;
m_nCurrentShadowStrength = INTERP(m_nShadowStrength);
m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength);
m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength);
m_fCurrentFarClip = INTERP(m_fFarClip);
m_fCurrentFogStart = INTERP(m_fFogStart);
m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness);
m_fCurrentLightsOnGroundBrightness = INTERP(m_fLightsOnGroundBrightness)/10.0f;
m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed);
m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen);
@ -347,6 +394,7 @@ CTimeCycle::Update(void)
m_fCurrentWaterGreen = INTERP(m_fWaterGreen);
m_fCurrentWaterBlue = INTERP(m_fWaterBlue);
m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha);
#undef INTERP
if(m_FogReduction != 0)
m_fCurrentFarClip = Max(m_fCurrentFarClip, m_FogReduction/64.0f * 650.0f);
@ -360,7 +408,88 @@ CTimeCycle::Update(void)
sunPos.z = 0.2f - Cos(sunAngle);
sunPos.Normalise();
// TODO(MIAMI): extra colours
if(m_bExtraColourOn)
m_ExtraColourInter = Min(1.0f, m_ExtraColourInter + CTimer::GetTimeStep()/120.0f);
else
m_ExtraColourInter = Max(-.0f, m_ExtraColourInter - CTimer::GetTimeStep()/120.0f);
if(m_ExtraColourInter > 0.0f){
#define INTERP(extra,cur) (m_ExtraColourInter*extra[m_ExtraColour][WEATHER_EXTRACOLOURS] + (1.0f-m_ExtraColourInter)*cur)
#define INTERPscl(extra,scl,cur) (m_ExtraColourInter*extra[m_ExtraColour][WEATHER_EXTRACOLOURS]/scl + (1.0f-m_ExtraColourInter)*cur)
if(m_nSkyTopRed[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0 ||
m_nSkyTopGreen[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0 ||
m_nSkyTopBlue[m_ExtraColour][WEATHER_EXTRACOLOURS] != 0){
m_nCurrentSkyTopRed = INTERP(m_nSkyTopRed,m_nCurrentSkyTopRed);
m_nCurrentSkyTopGreen = INTERP(m_nSkyTopGreen,m_nCurrentSkyTopGreen);
m_nCurrentSkyTopBlue = INTERP(m_nSkyTopBlue,m_nCurrentSkyTopBlue);
m_nCurrentSkyBottomRed = INTERP(m_nSkyBottomRed,m_nCurrentSkyBottomRed);
m_nCurrentSkyBottomGreen = INTERP(m_nSkyBottomGreen,m_nCurrentSkyBottomGreen);
m_nCurrentSkyBottomBlue = INTERP(m_nSkyBottomBlue,m_nCurrentSkyBottomBlue);
m_nCurrentSunCoreRed = INTERP(m_nSunCoreRed,m_nCurrentSunCoreRed);
m_nCurrentSunCoreGreen = INTERP(m_nSunCoreGreen,m_nCurrentSunCoreGreen);
m_nCurrentSunCoreBlue = INTERP(m_nSunCoreBlue,m_nCurrentSunCoreBlue);
m_nCurrentSunCoronaRed = INTERP(m_nSunCoronaRed,m_nCurrentSunCoronaRed);
m_nCurrentSunCoronaGreen = INTERP(m_nSunCoronaGreen,m_nCurrentSunCoronaGreen);
m_nCurrentSunCoronaBlue = INTERP(m_nSunCoronaBlue,m_nCurrentSunCoronaBlue);
m_fCurrentSunSize = INTERPscl(m_fSunSize,10.0f,m_fCurrentSunSize);
m_nCurrentLowCloudsRed = INTERP(m_nLowCloudsRed,m_nCurrentLowCloudsRed);
m_nCurrentLowCloudsGreen = INTERP(m_nLowCloudsGreen,m_nCurrentLowCloudsGreen);
m_nCurrentLowCloudsBlue = INTERP(m_nLowCloudsBlue,m_nCurrentLowCloudsBlue);
m_nCurrentFluffyCloudsTopRed = INTERP(m_nFluffyCloudsTopRed,m_nCurrentFluffyCloudsTopRed);
m_nCurrentFluffyCloudsTopGreen = INTERP(m_nFluffyCloudsTopGreen,m_nCurrentFluffyCloudsTopGreen);
m_nCurrentFluffyCloudsTopBlue = INTERP(m_nFluffyCloudsTopBlue,m_nCurrentFluffyCloudsTopBlue);
m_nCurrentFluffyCloudsBottomRed = INTERP(m_nFluffyCloudsBottomRed,m_nCurrentFluffyCloudsBottomRed);
m_nCurrentFluffyCloudsBottomGreen = INTERP(m_nFluffyCloudsBottomGreen,m_nCurrentFluffyCloudsBottomGreen);
m_nCurrentFluffyCloudsBottomBlue = INTERP(m_nFluffyCloudsBottomBlue,m_nCurrentFluffyCloudsBottomBlue);
m_fCurrentWaterRed = INTERP(m_fWaterRed,m_fCurrentWaterRed);
m_fCurrentWaterGreen = INTERP(m_fWaterGreen,m_fCurrentWaterGreen);
m_fCurrentWaterBlue = INTERP(m_fWaterBlue,m_fCurrentWaterBlue);
m_fCurrentWaterAlpha = INTERP(m_fWaterAlpha,m_fCurrentWaterAlpha);
}
m_fCurrentAmbientRed = INTERP(m_nAmbientRed,m_fCurrentAmbientRed);
m_fCurrentAmbientGreen = INTERP(m_nAmbientGreen,m_fCurrentAmbientGreen);
m_fCurrentAmbientBlue = INTERP(m_nAmbientBlue,m_fCurrentAmbientBlue);
m_fCurrentAmbientRed_Obj = INTERP(m_nAmbientRed_Obj,m_fCurrentAmbientRed_Obj);
m_fCurrentAmbientGreen_Obj = INTERP(m_nAmbientGreen_Obj,m_fCurrentAmbientGreen_Obj);
m_fCurrentAmbientBlue_Obj = INTERP(m_nAmbientBlue_Obj,m_fCurrentAmbientBlue_Obj);
m_fCurrentAmbientRed_Bl = INTERP(m_nAmbientRed_Bl,m_fCurrentAmbientRed_Bl);
m_fCurrentAmbientGreen_Bl = INTERP(m_nAmbientGreen_Bl,m_fCurrentAmbientGreen_Bl);
m_fCurrentAmbientBlue_Bl = INTERP(m_nAmbientBlue_Bl,m_fCurrentAmbientBlue_Bl);
m_fCurrentAmbientRed_Obj_Bl = INTERP(m_nAmbientRed_Obj_Bl,m_fCurrentAmbientRed_Obj_Bl);
m_fCurrentAmbientGreen_Obj_Bl = INTERP(m_nAmbientGreen_Obj_Bl,m_fCurrentAmbientGreen_Obj_Bl);
m_fCurrentAmbientBlue_Obj_Bl = INTERP(m_nAmbientBlue_Obj_Bl,m_fCurrentAmbientBlue_Obj_Bl);
m_fCurrentDirectionalRed = INTERP(m_nDirectionalRed,m_fCurrentDirectionalRed);
m_fCurrentDirectionalGreen = INTERP(m_nDirectionalGreen,m_fCurrentDirectionalGreen);
m_fCurrentDirectionalBlue = INTERP(m_nDirectionalBlue,m_fCurrentDirectionalBlue);
m_fCurrentSpriteSize = INTERPscl(m_fSpriteSize,10.0f,m_fCurrentSpriteSize);
m_fCurrentSpriteBrightness = INTERPscl(m_fSpriteBrightness,10.0f,m_fCurrentSpriteBrightness);
m_nCurrentShadowStrength = INTERP(m_nShadowStrength,m_nCurrentShadowStrength);
m_nCurrentLightShadowStrength = INTERP(m_nLightShadowStrength,m_nCurrentLightShadowStrength);
m_nCurrentPoleShadowStrength = INTERP(m_nPoleShadowStrength,m_nCurrentPoleShadowStrength);
m_fCurrentFarClip = INTERP(m_fFarClip,m_fCurrentFarClip);
m_fCurrentFogStart = INTERP(m_fFogStart,m_fCurrentFogStart);
m_fCurrentLightsOnGroundBrightness = INTERPscl(m_fLightsOnGroundBrightness,10.0f,m_fCurrentLightsOnGroundBrightness);
m_fCurrentBlurRed = INTERP(m_fBlurRed,m_fCurrentBlurRed);
m_fCurrentBlurGreen = INTERP(m_fBlurGreen,m_fCurrentBlurGreen);
m_fCurrentBlurBlue = INTERP(m_fBlurBlue,m_fCurrentBlurBlue);
#undef INTERP
#undef INTERPscl
}
if(TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE)
TheCamera.SetMotionBlur(m_fCurrentBlurRed, m_fCurrentBlurGreen, m_fCurrentBlurBlue, 5, MOTION_BLUR_LIGHT_SCENE);

View file

@ -2,58 +2,58 @@
class CTimeCycle
{
static int m_nAmbientRed[NUMHOURS][NUMWEATHERS];
static int m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
static int m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
static int m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
static int m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
static int m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
static int m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
static int m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
static int m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
static int m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
static int m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
static int m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
static int m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
static int m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
static int m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
static int m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
static int m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
static int m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
static int m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
static int m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
static int m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
static int m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
static int m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
static int m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
static int m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
static int m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
static int m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
static float m_fSunSize[NUMHOURS][NUMWEATHERS];
static float m_fSpriteSize[NUMHOURS][NUMWEATHERS];
static float m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
static short m_nShadowStrength[NUMHOURS][NUMWEATHERS];
static short m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
static short m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
static float m_fFogStart[NUMHOURS][NUMWEATHERS];
static float m_fFarClip[NUMHOURS][NUMWEATHERS];
static float m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
static int m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
static int m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
static int m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
static int m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
static int m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
static int m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
static int m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
static int m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
static int m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
static float m_fBlurRed[NUMHOURS][NUMWEATHERS];
static float m_fBlurGreen[NUMHOURS][NUMWEATHERS];
static float m_fBlurBlue[NUMHOURS][NUMWEATHERS];
static float m_fWaterRed[NUMHOURS][NUMWEATHERS];
static float m_fWaterGreen[NUMHOURS][NUMWEATHERS];
static float m_fWaterBlue[NUMHOURS][NUMWEATHERS];
static float m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS];
static uint8 m_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS];
static uint8 m_nDirectionalRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nDirectionalGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nDirectionalBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nSkyTopRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nSkyTopGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nSkyTopBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nSkyBottomRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nSkyBottomGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nSkyBottomBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nSunCoreRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nSunCoreGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nSunCoreBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nSunCoronaRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nSunCoronaGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nSunCoronaBlue[NUMHOURS][NUMWEATHERS];
static int8 m_fSunSize[NUMHOURS][NUMWEATHERS];
static int8 m_fSpriteSize[NUMHOURS][NUMWEATHERS];
static int8 m_fSpriteBrightness[NUMHOURS][NUMWEATHERS];
static uint8 m_nShadowStrength[NUMHOURS][NUMWEATHERS];
static uint8 m_nLightShadowStrength[NUMHOURS][NUMWEATHERS];
static uint8 m_nPoleShadowStrength[NUMHOURS][NUMWEATHERS];
static int16 m_fFogStart[NUMHOURS][NUMWEATHERS];
static int16 m_fFarClip[NUMHOURS][NUMWEATHERS];
static uint8 m_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS];
static uint8 m_nLowCloudsRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nLowCloudsGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nLowCloudsBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS];
static uint8 m_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_fBlurRed[NUMHOURS][NUMWEATHERS];
static uint8 m_fBlurGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_fBlurBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_fWaterRed[NUMHOURS][NUMWEATHERS];
static uint8 m_fWaterGreen[NUMHOURS][NUMWEATHERS];
static uint8 m_fWaterBlue[NUMHOURS][NUMWEATHERS];
static uint8 m_fWaterAlpha[NUMHOURS][NUMWEATHERS];
static float m_fCurrentAmbientRed;
static float m_fCurrentAmbientGreen;
@ -70,36 +70,36 @@ class CTimeCycle
static float m_fCurrentDirectionalRed;
static float m_fCurrentDirectionalGreen;
static float m_fCurrentDirectionalBlue;
static int m_nCurrentSkyTopRed;
static int m_nCurrentSkyTopGreen;
static int m_nCurrentSkyTopBlue;
static int m_nCurrentSkyBottomRed;
static int m_nCurrentSkyBottomGreen;
static int m_nCurrentSkyBottomBlue;
static int m_nCurrentSunCoreRed;
static int m_nCurrentSunCoreGreen;
static int m_nCurrentSunCoreBlue;
static int m_nCurrentSunCoronaRed;
static int m_nCurrentSunCoronaGreen;
static int m_nCurrentSunCoronaBlue;
static int32 m_nCurrentSkyTopRed;
static int32 m_nCurrentSkyTopGreen;
static int32 m_nCurrentSkyTopBlue;
static int32 m_nCurrentSkyBottomRed;
static int32 m_nCurrentSkyBottomGreen;
static int32 m_nCurrentSkyBottomBlue;
static int32 m_nCurrentSunCoreRed;
static int32 m_nCurrentSunCoreGreen;
static int32 m_nCurrentSunCoreBlue;
static int32 m_nCurrentSunCoronaRed;
static int32 m_nCurrentSunCoronaGreen;
static int32 m_nCurrentSunCoronaBlue;
static float m_fCurrentSunSize;
static float m_fCurrentSpriteSize;
static float m_fCurrentSpriteBrightness;
static int m_nCurrentShadowStrength;
static int m_nCurrentLightShadowStrength;
static int m_nCurrentPoleShadowStrength;
static int32 m_nCurrentShadowStrength;
static int32 m_nCurrentLightShadowStrength;
static int32 m_nCurrentPoleShadowStrength;
static float m_fCurrentFogStart;
static float m_fCurrentFarClip;
static float m_fCurrentLightsOnGroundBrightness;
static int m_nCurrentLowCloudsRed;
static int m_nCurrentLowCloudsGreen;
static int m_nCurrentLowCloudsBlue;
static int m_nCurrentFluffyCloudsTopRed;
static int m_nCurrentFluffyCloudsTopGreen;
static int m_nCurrentFluffyCloudsTopBlue;
static int m_nCurrentFluffyCloudsBottomRed;
static int m_nCurrentFluffyCloudsBottomGreen;
static int m_nCurrentFluffyCloudsBottomBlue;
static int32 m_nCurrentLowCloudsRed;
static int32 m_nCurrentLowCloudsGreen;
static int32 m_nCurrentLowCloudsBlue;
static int32 m_nCurrentFluffyCloudsTopRed;
static int32 m_nCurrentFluffyCloudsTopGreen;
static int32 m_nCurrentFluffyCloudsTopBlue;
static int32 m_nCurrentFluffyCloudsBottomRed;
static int32 m_nCurrentFluffyCloudsBottomGreen;
static int32 m_nCurrentFluffyCloudsBottomBlue;
static float m_fCurrentBlurRed;
static float m_fCurrentBlurGreen;
static float m_fCurrentBlurBlue;
@ -107,14 +107,17 @@ class CTimeCycle
static float m_fCurrentWaterGreen;
static float m_fCurrentWaterBlue;
static float m_fCurrentWaterAlpha;
static int m_nCurrentFogColourRed;
static int m_nCurrentFogColourGreen;
static int m_nCurrentFogColourBlue;
static int32 m_nCurrentFogColourRed;
static int32 m_nCurrentFogColourGreen;
static int32 m_nCurrentFogColourBlue;
static int m_FogReduction;
static int32 m_FogReduction;
public:
static int m_CurrentStoredValue;
static bool m_bExtraColourOn;
static int32 m_ExtraColour;
static float m_ExtraColourInter;
static int32 m_CurrentStoredValue;
static CVector m_VectorToSun[16];
static float m_fShadowFrontX[16];
static float m_fShadowFrontY[16];
@ -138,51 +141,56 @@ public:
static float GetDirectionalRed(void) { return m_fCurrentDirectionalRed; }
static float GetDirectionalGreen(void) { return m_fCurrentDirectionalGreen; }
static float GetDirectionalBlue(void) { return m_fCurrentDirectionalBlue; }
static int GetSkyTopRed(void) { return m_nCurrentSkyTopRed; }
static int GetSkyTopGreen(void) { return m_nCurrentSkyTopGreen; }
static int GetSkyTopBlue(void) { return m_nCurrentSkyTopBlue; }
static int GetSkyBottomRed(void) { return m_nCurrentSkyBottomRed; }
static int GetSkyBottomGreen(void) { return m_nCurrentSkyBottomGreen; }
static int GetSkyBottomBlue(void) { return m_nCurrentSkyBottomBlue; }
static int GetSunCoreRed(void) { return m_nCurrentSunCoreRed; }
static int GetSunCoreGreen(void) { return m_nCurrentSunCoreGreen; }
static int GetSunCoreBlue(void) { return m_nCurrentSunCoreBlue; }
static int GetSunCoronaRed(void) { return m_nCurrentSunCoronaRed; }
static int GetSunCoronaGreen(void) { return m_nCurrentSunCoronaGreen; }
static int GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
static int32 GetSkyTopRed(void) { return m_nCurrentSkyTopRed; }
static int32 GetSkyTopGreen(void) { return m_nCurrentSkyTopGreen; }
static int32 GetSkyTopBlue(void) { return m_nCurrentSkyTopBlue; }
static int32 GetSkyBottomRed(void) { return m_nCurrentSkyBottomRed; }
static int32 GetSkyBottomGreen(void) { return m_nCurrentSkyBottomGreen; }
static int32 GetSkyBottomBlue(void) { return m_nCurrentSkyBottomBlue; }
static int32 GetSunCoreRed(void) { return m_nCurrentSunCoreRed; }
static int32 GetSunCoreGreen(void) { return m_nCurrentSunCoreGreen; }
static int32 GetSunCoreBlue(void) { return m_nCurrentSunCoreBlue; }
static int32 GetSunCoronaRed(void) { return m_nCurrentSunCoronaRed; }
static int32 GetSunCoronaGreen(void) { return m_nCurrentSunCoronaGreen; }
static int32 GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
static float GetSunSize(void) { return m_fCurrentSunSize; }
static float GetSpriteBrightness(void) { return m_fCurrentSpriteBrightness; }
static float GetSpriteSize(void) { return m_fCurrentSpriteSize; }
static int GetShadowStrength(void) { return m_nCurrentShadowStrength; }
static int GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
static int32 GetShadowStrength(void) { return m_nCurrentShadowStrength; }
static int32 GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
static float GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; }
static float GetFarClip(void) { return m_fCurrentFarClip; }
static float GetFogStart(void) { return m_fCurrentFogStart; }
static int GetLowCloudsRed(void) { return m_nCurrentLowCloudsRed; }
static int GetLowCloudsGreen(void) { return m_nCurrentLowCloudsGreen; }
static int GetLowCloudsBlue(void) { return m_nCurrentLowCloudsBlue; }
static int GetFluffyCloudsTopRed(void) { return m_nCurrentFluffyCloudsTopRed; }
static int GetFluffyCloudsTopGreen(void) { return m_nCurrentFluffyCloudsTopGreen; }
static int GetFluffyCloudsTopBlue(void) { return m_nCurrentFluffyCloudsTopBlue; }
static int GetFluffyCloudsBottomRed(void) { return m_nCurrentFluffyCloudsBottomRed; }
static int GetFluffyCloudsBottomGreen(void) { return m_nCurrentFluffyCloudsBottomGreen; }
static int GetFluffyCloudsBottomBlue(void) { return m_nCurrentFluffyCloudsBottomBlue; }
static int GetFogRed(void) { return m_nCurrentFogColourRed; }
static int GetFogGreen(void) { return m_nCurrentFogColourGreen; }
static int GetFogBlue(void) { return m_nCurrentFogColourBlue; }
static int GetFogReduction(void) { return m_FogReduction; }
static int32 GetLowCloudsRed(void) { return m_nCurrentLowCloudsRed; }
static int32 GetLowCloudsGreen(void) { return m_nCurrentLowCloudsGreen; }
static int32 GetLowCloudsBlue(void) { return m_nCurrentLowCloudsBlue; }
static int32 GetFluffyCloudsTopRed(void) { return m_nCurrentFluffyCloudsTopRed; }
static int32 GetFluffyCloudsTopGreen(void) { return m_nCurrentFluffyCloudsTopGreen; }
static int32 GetFluffyCloudsTopBlue(void) { return m_nCurrentFluffyCloudsTopBlue; }
static int32 GetFluffyCloudsBottomRed(void) { return m_nCurrentFluffyCloudsBottomRed; }
static int32 GetFluffyCloudsBottomGreen(void) { return m_nCurrentFluffyCloudsBottomGreen; }
static int32 GetFluffyCloudsBottomBlue(void) { return m_nCurrentFluffyCloudsBottomBlue; }
static int32 GetFogRed(void) { return m_nCurrentFogColourRed; }
static int32 GetFogGreen(void) { return m_nCurrentFogColourGreen; }
static int32 GetFogBlue(void) { return m_nCurrentFogColourBlue; }
static int32 GetFogReduction(void) { return m_FogReduction; }
static int GetBlurRed(void) { return m_fCurrentBlurRed; }
static int GetBlurGreen(void) { return m_fCurrentBlurGreen; }
static int GetBlurBlue(void) { return m_fCurrentBlurBlue; }
static int GetWaterRed(void) { return m_fCurrentWaterRed; }
static int GetWaterGreen(void) { return m_fCurrentWaterGreen; }
static int GetWaterBlue(void) { return m_fCurrentWaterBlue; }
static int GetWaterAlpha(void) { return m_fCurrentWaterAlpha; }
static int32 GetBlurRed(void) { return m_fCurrentBlurRed; }
static int32 GetBlurGreen(void) { return m_fCurrentBlurGreen; }
static int32 GetBlurBlue(void) { return m_fCurrentBlurBlue; }
static int32 GetWaterRed(void) { return m_fCurrentWaterRed; }
static int32 GetWaterGreen(void) { return m_fCurrentWaterGreen; }
static int32 GetWaterBlue(void) { return m_fCurrentWaterBlue; }
static int32 GetWaterAlpha(void) { return m_fCurrentWaterAlpha; }
static void Initialise(void);
static void Update(void);
static float Interpolate(int8 *a, int8 *b);
static float Interpolate(uint8 *a, uint8 *b);
static float Interpolate(int16 *a, int16 *b);
static void StartExtraColour(int32 c, bool fade);
static void StopExtraColour(bool fade);
static CVector &GetSunDirection(void) { return m_VectorToSun[m_CurrentStoredValue]; }
static float GetShadowFrontX(void) { return m_fShadowFrontX[m_CurrentStoredValue]; }
static float GetShadowFrontY(void) { return m_fShadowFrontY[m_CurrentStoredValue]; }

View file

@ -6,7 +6,9 @@ enum {
WEATHER_FOGGY,
WEATHER_EXTRA_SUNNY,
WEATHER_HURRICANE,
WEATHER_TOTAL
WEATHER_TOTAL,
WEATHER_EXTRACOLOURS = 6
};
class CWeather

View file

@ -399,6 +399,125 @@ RenderSkeleton(RpHAnimHierarchy *hier)
}
#endif
RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset)
{
RwIm2DVertex vx[4];
/*
* Render an opaque white 2D quad at the given coordinates and
* spanning a whole texture.
*/
RwIm2DVertexSetScreenX(&vx[0], x1);
RwIm2DVertexSetScreenY(&vx[0], y1);
RwIm2DVertexSetScreenZ(&vx[0], z);
RwIm2DVertexSetIntRGBA(&vx[0], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
RwIm2DVertexSetU(&vx[0], uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[0], uvOffset, recipCamZ);
RwIm2DVertexSetScreenX(&vx[1], x1);
RwIm2DVertexSetScreenY(&vx[1], y2);
RwIm2DVertexSetScreenZ(&vx[1], z);
RwIm2DVertexSetIntRGBA(&vx[1], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
RwIm2DVertexSetScreenX(&vx[2], x2);
RwIm2DVertexSetScreenY(&vx[2], y1);
RwIm2DVertexSetScreenZ(&vx[2], z);
RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ);
RwIm2DVertexSetScreenX(&vx[3], x2);
RwIm2DVertexSetScreenY(&vx[3], y2);
RwIm2DVertexSetScreenZ(&vx[3], z);
RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ);
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
return TRUE;
}
bool b_cbsUseLTM = true;
RpAtomic *cbsCalcMeanBSphereRadiusCB(RpAtomic *atomic, void *data)
{
RwV3d atomicPos;
if ( b_cbsUseLTM )
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
else
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
RwV3d temp;
RwV3dSub(&temp, &atomicPos, &((RwSphere *)data)->center);
RwReal radius = RwV3dLength(&temp) + RpAtomicGetBoundingSphere(atomic)->radius;
if ( ((RwSphere *)data)->radius < radius )
((RwSphere *)data)->radius = radius;
return atomic;
}
RpAtomic *cbsCalcMeanBSphereCenterCB(RpAtomic *atomic, void *data)
{
RwV3d atomicPos;
if ( b_cbsUseLTM )
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
else
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
RwV3dAdd(&((RwSphere *)data)->center, &((RwSphere *)data)->center, &atomicPos);
return atomic;
}
RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM)
{
RwMatrix matrix;
RwSphere result = { 0.0f, 0.0f, 0.0f, 0.0f };
b_cbsUseLTM = useLTM;
if ( clump == nil || sphere == nil )
return nil;
sphere->radius = 0.0f;
sphere->center.x = 0.0f;
sphere->center.y = 0.0f;
sphere->center.z = 0.0f;
RwInt32 numAtomics = RpClumpGetNumAtomics(clump);
if ( numAtomics < 1.0f )
return nil;
RpClumpForAllAtomics(clump, cbsCalcMeanBSphereCenterCB, &result);
RwV3dScale(&result.center, &result.center, 1.0f/numAtomics);
RpClumpForAllAtomics(clump, cbsCalcMeanBSphereRadiusCB, &result);
if ( b_cbsUseLTM )
RwMatrixInvert(&matrix, RwFrameGetLTM(RpClumpGetFrame(clump)));
else
RwMatrixInvert(&matrix, RwFrameGetMatrix(RpClumpGetFrame(clump)));
RwV3dTransformPoints(&result.center, &result.center, 1, &matrix);
*sphere = result;
return clump;
}
void
CameraSize(RwCamera * camera, RwRect * rect,
RwReal viewWindow, RwReal aspectRatio)

View file

@ -29,6 +29,9 @@ RpAtomic *AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data);
void RenderSkeleton(RpHAnimHierarchy *hier);
#endif
RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset);
RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM);
RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead1(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict);

View file

@ -2505,8 +2505,12 @@ CAutomobile::PreRender(void)
// end of lights
}
//TODO(MIAMI): StoreShadowForVehicle once we have it
CShadows::StoreShadowForCar(this);
if (IsRealHeli())
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_HELI);
else if ( GetModelIndex() == MI_RCBARON)
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_RCPLANE);
else
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_CAR);
DoSunGlare();

View file

@ -1546,7 +1546,7 @@ CBike::PreRender(void)
}
AddDamagedVehicleParticles();
//TODO(MIAMI): StoreShadowForVehicle once we have it
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_BIKE);
CMatrix mat;
CVector pos;

View file

@ -557,6 +557,7 @@ CHeli::PreRender(void)
{
float radius = (GetPosition().z - FindPlayerCoors().z - 10.0f - 1.0f) * 0.3f + 10.0f;
HeliDustGenerate(this, radius, FindPlayerCoors().z, Max(16.0f - 4.0f*CTimer::GetTimeStep(), 2.0f));
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_HELI);
}
void
@ -592,7 +593,7 @@ CHeli::PreRenderAlways(void)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &shadowPos,
6.0f, 0.0f, 0.0f, -6.0f,
80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity,
50.0f, true, 1.0f);
50.0f, true, 1.0f, nil, false);
CVector front = GetMatrix() * CVector(0.0f, 7.0f, 0.0f);
CVector toPlayer = FindPlayerCoors() - front;

View file

@ -24,6 +24,10 @@
#include "World.h"
#include "SurfaceTable.h"
#ifdef SQUEEZE_PERFORMANCE
uint32 bulletInfoInUse;
#endif
#define BULLET_LIFETIME (1000)
#define NUM_PED_BLOOD_PARTICLES (8)
#define BLOOD_PARTICLE_OFFSET (CVector(0.0f, 0.0f, 0.0f))
@ -47,6 +51,9 @@ void CBulletInfo::Initialise(void)
gaBulletInfo[i].m_pSource = nil;
}
debug("CBulletInfo ready\n");
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse = 0;
#endif
}
void CBulletInfo::Shutdown(void)
@ -71,11 +78,19 @@ bool CBulletInfo::AddBullet(CEntity* pSource, eWeaponType type, CVector vecPosit
gaBulletInfo[i].m_vecSpeed = vecSpeed;
gaBulletInfo[i].m_fTimer = CTimer::GetTimeInMilliseconds() + BULLET_LIFETIME;
gaBulletInfo[i].m_bInUse = true;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse++;
#endif
return true;
}
void CBulletInfo::Update(void)
{
#ifdef SQUEEZE_PERFORMANCE
if (bulletInfoInUse == 0)
return;
#endif
bPlayerSniperBullet = false;
for (int i = 0; i < NUM_BULLETS; i++) {
CBulletInfo* pBullet = &gaBulletInfo[i];
@ -83,8 +98,12 @@ void CBulletInfo::Update(void)
pBullet->m_pSource = nil;
if (!pBullet->m_bInUse)
continue;
if (CTimer::GetTimeInMilliseconds() > pBullet->m_fTimer)
if (CTimer::GetTimeInMilliseconds() > pBullet->m_fTimer) {
pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse--;
#endif
}
CVector vecOldPos = pBullet->m_vecPosition;
CVector vecNewPos = pBullet->m_vecPosition + pBullet->m_vecSpeed * CTimer::GetTimeStep() * 0.5f;
CWorld::bIncludeCarTyres = true;
@ -108,6 +127,9 @@ void CBulletInfo::Update(void)
pPed->InflictDamage(pBullet->m_pSource, pBullet->m_eWeaponType, pBullet->m_nDamage, (ePedPieceTypes)point.pieceB, pPed->GetLocalDirection(pPed->GetPosition() - point.point));
CEventList::RegisterEvent(pPed->m_nPedType == PEDTYPE_COP ? EVENT_SHOOT_COP : EVENT_SHOOT_PED, EVENT_ENTITY_PED, pPed, (CPed*)pBullet->m_pSource, 1000);
pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse--;
#endif
vecNewPos = point.point;
}
if (CGame::nastyGame) {
@ -130,6 +152,9 @@ void CBulletInfo::Update(void)
}
}
pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse--;
#endif
vecNewPos = point.point;
}
}
@ -144,6 +169,9 @@ void CBulletInfo::Update(void)
}
#ifdef FIX_BUGS
pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse--;
#endif
vecNewPos = point.point;
#endif
}
@ -163,6 +191,9 @@ void CBulletInfo::Update(void)
}
#ifdef FIX_BUGS
pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse--;
#endif
vecNewPos = point.point;
#endif
}
@ -213,8 +244,12 @@ void CBulletInfo::Update(void)
}
pBullet->m_vecPosition = vecNewPos;
if (pBullet->m_vecPosition.x < -MAP_BORDER || pBullet->m_vecPosition.x > MAP_BORDER ||
pBullet->m_vecPosition.y < -MAP_BORDER || pBullet->m_vecPosition.y > MAP_BORDER)
pBullet->m_vecPosition.y < -MAP_BORDER || pBullet->m_vecPosition.y > MAP_BORDER) {
pBullet->m_bInUse = false;
#ifdef SQUEEZE_PERFORMANCE
bulletInfoInUse--;
#endif
}
}
}

View file

@ -13,6 +13,10 @@
#include "Weapon.h"
#include "World.h"
#ifdef SQUEEZE_PERFORMANCE
uint32 projectileInUse;
#endif
CProjectileInfo gaProjectileInfo[NUM_PROJECTILES];
CProjectile *CProjectileInfo::ms_apProjectile[NUM_PROJECTILES];
@ -30,6 +34,10 @@ CProjectileInfo::Initialise()
}
debug("CProjectileInfo ready\n");
#ifdef SQUEEZE_PERFORMANCE
projectileInUse = 0;
#endif
}
void
@ -163,6 +171,10 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
ms_apProjectile[i]->m_fElasticity = elasticity;
ms_apProjectile[i]->m_nSpecialCollisionResponseCases = SpecialCollisionResponseCase;
#ifdef SQUEEZE_PERFORMANCE
projectileInUse++;
#endif
gaProjectileInfo[i].m_bInUse = true;
CWorld::Add(ms_apProjectile[i]);
@ -178,6 +190,9 @@ void
CProjectileInfo::RemoveProjectile(CProjectileInfo *info, CProjectile *projectile)
{
RemoveNotAdd(info->m_pSource, info->m_eWeaponType, projectile->GetPosition());
#ifdef SQUEEZE_PERFORMANCE
projectileInUse--;
#endif
info->m_bInUse = false;
CWorld::Remove(projectile);
@ -205,6 +220,11 @@ CProjectileInfo::RemoveNotAdd(CEntity *entity, eWeaponType weaponType, CVector p
void
CProjectileInfo::Update()
{
#ifdef SQUEEZE_PERFORMANCE
if (projectileInUse == 0)
return;
#endif
for (int i = 0; i < ARRAY_SIZE(gaProjectileInfo); i++) {
if (!gaProjectileInfo[i].m_bInUse) continue;
@ -213,6 +233,10 @@ CProjectileInfo::Update()
gaProjectileInfo[i].m_pSource = nil;
if (ms_apProjectile[i] == nil) {
#ifdef SQUEEZE_PERFORMANCE
projectileInUse--;
#endif
gaProjectileInfo[i].m_bInUse = false;
continue;
}
@ -276,6 +300,10 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo
if (pos.x >= x1 && pos.x <= x2 && pos.y >= y1 && pos.y <= y2 && pos.z >= z1 && pos.z <= z2) {
result = true;
if (remove) {
#ifdef SQUEEZE_PERFORMANCE
projectileInUse--;
#endif
gaProjectileInfo[i].m_bInUse = false;
CWorld::Remove(ms_apProjectile[i]);
delete ms_apProjectile[i];
@ -304,8 +332,17 @@ CProjectileInfo::RemoveDetonatorProjectiles()
void
CProjectileInfo::RemoveAllProjectiles()
{
#ifdef SQUEEZE_PERFORMANCE
if (projectileInUse == 0)
return;
#endif
for (int i = 0; i < ARRAY_SIZE(ms_apProjectile); i++) {
if (gaProjectileInfo[i].m_bInUse) {
#ifdef SQUEEZE_PERFORMANCE
projectileInUse--;
#endif
gaProjectileInfo[i].m_bInUse = false;
CWorld::Remove(ms_apProjectile[i]);
delete ms_apProjectile[i];
@ -316,12 +353,21 @@ CProjectileInfo::RemoveAllProjectiles()
bool
CProjectileInfo::RemoveIfThisIsAProjectile(CObject *object)
{
#ifdef SQUEEZE_PERFORMANCE
if (projectileInUse == 0)
return false;
#endif
int i = 0;
while (ms_apProjectile[i++] != object) {
if (i >= ARRAY_SIZE(ms_apProjectile))
return false;
}
#ifdef SQUEEZE_PERFORMANCE
projectileInUse--;
#endif
gaProjectileInfo[i].m_bInUse = false;
CWorld::Remove(ms_apProjectile[i]);
delete ms_apProjectile[i];

View file

@ -13,6 +13,9 @@
CShotInfo gaShotInfo[NUMSHOTINFOS];
float CShotInfo::ms_afRandTable[20];
#ifdef SQUEEZE_PERFORMANCE
uint32 shotInfoInUse;
#endif
/*
Used for flamethrower. I don't know why it's name is CShotInfo.
@ -41,6 +44,9 @@ CShotInfo::Initialise()
nextVal += 0.005f;
}
debug("CShotInfo ready\n");
#ifdef SQUEEZE_PERFORMANCE
shotInfoInUse = 0;
#endif
}
bool
@ -54,6 +60,10 @@ CShotInfo::AddShot(CEntity *sourceEntity, eWeaponType weapon, CVector startPos,
if (slot == ARRAY_SIZE(gaShotInfo))
return false;
#ifdef SQUEEZE_PERFORMANCE
shotInfoInUse++;
#endif
gaShotInfo[slot].m_inUse = true;
gaShotInfo[slot].m_weapon = weapon;
gaShotInfo[slot].m_startPos = startPos;
@ -87,6 +97,10 @@ CShotInfo::Shutdown()
void
CShotInfo::Update()
{
#ifdef SQUEEZE_PERFORMANCE
if (shotInfoInUse == 0)
return;
#endif
for (int slot = 0; slot < ARRAY_SIZE(gaShotInfo); slot++) {
CShotInfo &shot = gaShotInfo[slot];
if (shot.m_sourceEntity && shot.m_sourceEntity->IsPed() && !((CPed*)shot.m_sourceEntity)->IsPointerValid())
@ -96,8 +110,12 @@ CShotInfo::Update()
continue;
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(shot.m_weapon);
if (CTimer::GetTimeInMilliseconds() > shot.m_timeout)
if (CTimer::GetTimeInMilliseconds() > shot.m_timeout) {
#ifdef SQUEEZE_PERFORMANCE
shotInfoInUse--;
#endif
shot.m_inUse = false;
}
if (weaponInfo->m_bSlowsDown)
shot.m_areaAffected *= pow(0.96, CTimer::GetTimeStep()); // FRAMERATE