summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio/eax/eax-util.cpp706
-rw-r--r--src/audio/eax/eax-util.h765
-rw-r--r--src/audio/eax/eax.h536
-rw-r--r--src/audio/oal/stream.cpp7
-rw-r--r--src/control/RoadBlocks.cpp4
-rw-r--r--src/core/Accident.cpp4
-rw-r--r--src/core/Accident.h1
-rw-r--r--src/core/Collision.cpp1118
-rw-r--r--src/core/Collision.h81
-rw-r--r--src/core/EventList.cpp8
-rw-r--r--src/core/Game.cpp3
-rw-r--r--src/core/Pad.cpp2
-rw-r--r--src/core/SurfaceTable.h5
-rw-r--r--src/core/World.cpp5
-rw-r--r--src/core/Zones.cpp5
-rw-r--r--src/core/common.h10
-rw-r--r--src/core/config.h17
-rw-r--r--src/core/main.cpp2
-rw-r--r--src/core/re3.cpp2
-rw-r--r--src/core/vu0Collision.dsm21
-rw-r--r--src/core/vu0Collision_1.s610
-rw-r--r--src/core/vu0Collision_2.s191
-rw-r--r--src/math/Matrix.h1
-rw-r--r--src/math/VuVector.h41
-rw-r--r--src/math/math.cpp128
-rw-r--r--src/peds/CopPed.cpp4
-rw-r--r--src/peds/Population.cpp11
-rw-r--r--src/render/Fluff.cpp5
-rw-r--r--src/render/Font.h2
-rw-r--r--src/render/Renderer.cpp6
-rw-r--r--src/render/Rubbish.h4
-rw-r--r--src/render/Shadows.cpp63
-rw-r--r--src/render/Shadows.h11
-rw-r--r--src/render/Sprite2d.cpp9
-rw-r--r--src/weapons/BulletInfo.cpp39
-rw-r--r--src/weapons/ProjectileInfo.cpp46
-rw-r--r--src/weapons/ShotInfo.cpp20
37 files changed, 4414 insertions, 79 deletions
diff --git a/src/audio/eax/eax-util.cpp b/src/audio/eax/eax-util.cpp
new file mode 100644
index 00000000..42eef738
--- /dev/null
+++ b/src/audio/eax/eax-util.cpp
@@ -0,0 +1,706 @@
+/***********************************************************************************************\
+* *
+* EAX-UTIL.CPP - utilities for EAX 3.0 *
+* Function declaration for EAX Morphing *
+* String names of the all the presets defined in eax-util.h *
+* Arrays grouping together all the EAX presets in a scenario *
+* *
+************************************************************************************************/
+
+#include "eax-util.h"
+#include <math.h>
+
+// Function prototypes used by EAX3ListenerInterpolate
+void Clamp(EAXVECTOR *eaxVector);
+bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP);
+
+
+/***********************************************************************************************\
+*
+* Definition of the EAXMorph function - EAX3ListenerInterpolate
+*
+\***********************************************************************************************/
+
+/*
+ EAX3ListenerInterpolate
+ lpStart - Initial EAX 3 Listener parameters
+ lpFinish - Final EAX 3 Listener parameters
+ flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination)
+ lpResult - Interpolated EAX 3 Listener parameters
+ bCheckValues - Check EAX 3.0 parameters are in range, default = false (no checking)
+*/
+bool EAX3ListenerInterpolate(LPEAXLISTENERPROPERTIES lpStart, LPEAXLISTENERPROPERTIES lpFinish,
+ float flRatio, LPEAXLISTENERPROPERTIES lpResult, bool bCheckValues)
+{
+ EAXVECTOR StartVector, FinalVector;
+
+ float flInvRatio;
+
+ if (bCheckValues)
+ {
+ if (!CheckEAX3LP(lpStart))
+ return false;
+
+ if (!CheckEAX3LP(lpFinish))
+ return false;
+ }
+
+ if (flRatio >= 1.0f)
+ {
+ memcpy(lpResult, lpFinish, sizeof(EAXLISTENERPROPERTIES));
+ return true;
+ }
+ else if (flRatio <= 0.0f)
+ {
+ memcpy(lpResult, lpStart, sizeof(EAXLISTENERPROPERTIES));
+ return true;
+ }
+
+ flInvRatio = (1.0f - flRatio);
+
+ // Environment
+ lpResult->ulEnvironment = 26; // (UNDEFINED environment)
+
+ // Environment Size
+ if (lpStart->flEnvironmentSize == lpFinish->flEnvironmentSize)
+ lpResult->flEnvironmentSize = lpStart->flEnvironmentSize;
+ else
+ lpResult->flEnvironmentSize = (float)exp( (log(lpStart->flEnvironmentSize) * flInvRatio) + (log(lpFinish->flEnvironmentSize) * flRatio) );
+
+ // Environment Diffusion
+ if (lpStart->flEnvironmentDiffusion == lpFinish->flEnvironmentDiffusion)
+ lpResult->flEnvironmentDiffusion = lpStart->flEnvironmentDiffusion;
+ else
+ lpResult->flEnvironmentDiffusion = (lpStart->flEnvironmentDiffusion * flInvRatio) + (lpFinish->flEnvironmentDiffusion * flRatio);
+
+ // Room
+ if (lpStart->lRoom == lpFinish->lRoom)
+ lpResult->lRoom = lpStart->lRoom;
+ else
+ lpResult->lRoom = (int)( ((float)lpStart->lRoom * flInvRatio) + ((float)lpFinish->lRoom * flRatio) );
+
+ // Room HF
+ if (lpStart->lRoomHF == lpFinish->lRoomHF)
+ lpResult->lRoomHF = lpStart->lRoomHF;
+ else
+ lpResult->lRoomHF = (int)( ((float)lpStart->lRoomHF * flInvRatio) + ((float)lpFinish->lRoomHF * flRatio) );
+
+ // Room LF
+ if (lpStart->lRoomLF == lpFinish->lRoomLF)
+ lpResult->lRoomLF = lpStart->lRoomLF;
+ else
+ lpResult->lRoomLF = (int)( ((float)lpStart->lRoomLF * flInvRatio) + ((float)lpFinish->lRoomLF * flRatio) );
+
+ // Decay Time
+ if (lpStart->flDecayTime == lpFinish->flDecayTime)
+ lpResult->flDecayTime = lpStart->flDecayTime;
+ else
+ lpResult->flDecayTime = (float)exp( (log(lpStart->flDecayTime) * flInvRatio) + (log(lpFinish->flDecayTime) * flRatio) );
+
+ // Decay HF Ratio
+ if (lpStart->flDecayHFRatio == lpFinish->flDecayHFRatio)
+ lpResult->flDecayHFRatio = lpStart->flDecayHFRatio;
+ else
+ lpResult->flDecayHFRatio = (float)exp( (log(lpStart->flDecayHFRatio) * flInvRatio) + (log(lpFinish->flDecayHFRatio) * flRatio) );
+
+ // Decay LF Ratio
+ if (lpStart->flDecayLFRatio == lpFinish->flDecayLFRatio)
+ lpResult->flDecayLFRatio = lpStart->flDecayLFRatio;
+ else
+ lpResult->flDecayLFRatio = (float)exp( (log(lpStart->flDecayLFRatio) * flInvRatio) + (log(lpFinish->flDecayLFRatio) * flRatio) );
+
+ // Reflections
+ if (lpStart->lReflections == lpFinish->lReflections)
+ lpResult->lReflections = lpStart->lReflections;
+ else
+ lpResult->lReflections = (int)( ((float)lpStart->lReflections * flInvRatio) + ((float)lpFinish->lReflections * flRatio) );
+
+ // Reflections Delay
+ if (lpStart->flReflectionsDelay == lpFinish->flReflectionsDelay)
+ lpResult->flReflectionsDelay = lpStart->flReflectionsDelay;
+ else
+ lpResult->flReflectionsDelay = (float)exp( (log(lpStart->flReflectionsDelay+0.0001f) * flInvRatio) + (log(lpFinish->flReflectionsDelay+0.0001f) * flRatio) );
+
+ // Reflections Pan
+
+ // To interpolate the vector correctly we need to ensure that both the initial and final vectors vectors are clamped to a length of 1.0f
+ StartVector = lpStart->vReflectionsPan;
+ FinalVector = lpFinish->vReflectionsPan;
+
+ Clamp(&StartVector);
+ Clamp(&FinalVector);
+
+ if (lpStart->vReflectionsPan.x == lpFinish->vReflectionsPan.x)
+ lpResult->vReflectionsPan.x = lpStart->vReflectionsPan.x;
+ else
+ lpResult->vReflectionsPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x));
+
+ if (lpStart->vReflectionsPan.y == lpFinish->vReflectionsPan.y)
+ lpResult->vReflectionsPan.y = lpStart->vReflectionsPan.y;
+ else
+ lpResult->vReflectionsPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y));
+
+ if (lpStart->vReflectionsPan.z == lpFinish->vReflectionsPan.z)
+ lpResult->vReflectionsPan.z = lpStart->vReflectionsPan.z;
+ else
+ lpResult->vReflectionsPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z));
+
+ // Reverb
+ if (lpStart->lReverb == lpFinish->lReverb)
+ lpResult->lReverb = lpStart->lReverb;
+ else
+ lpResult->lReverb = (int)( ((float)lpStart->lReverb * flInvRatio) + ((float)lpFinish->lReverb * flRatio) );
+
+ // Reverb Delay
+ if (lpStart->flReverbDelay == lpFinish->flReverbDelay)
+ lpResult->flReverbDelay = lpStart->flReverbDelay;
+ else
+ lpResult->flReverbDelay = (float)exp( (log(lpStart->flReverbDelay+0.0001f) * flInvRatio) + (log(lpFinish->flReverbDelay+0.0001f) * flRatio) );
+
+ // Reverb Pan
+
+ // To interpolate the vector correctly we need to ensure that both the initial and final vectors are clamped to a length of 1.0f
+ StartVector = lpStart->vReverbPan;
+ FinalVector = lpFinish->vReverbPan;
+
+ Clamp(&StartVector);
+ Clamp(&FinalVector);
+
+ if (lpStart->vReverbPan.x == lpFinish->vReverbPan.x)
+ lpResult->vReverbPan.x = lpStart->vReverbPan.x;
+ else
+ lpResult->vReverbPan.x = FinalVector.x + (flInvRatio * (StartVector.x - FinalVector.x));
+
+ if (lpStart->vReverbPan.y == lpFinish->vReverbPan.y)
+ lpResult->vReverbPan.y = lpStart->vReverbPan.y;
+ else
+ lpResult->vReverbPan.y = FinalVector.y + (flInvRatio * (StartVector.y - FinalVector.y));
+
+ if (lpStart->vReverbPan.z == lpFinish->vReverbPan.z)
+ lpResult->vReverbPan.z = lpStart->vReverbPan.z;
+ else
+ lpResult->vReverbPan.z = FinalVector.z + (flInvRatio * (StartVector.z - FinalVector.z));
+
+ // Echo Time
+ if (lpStart->flEchoTime == lpFinish->flEchoTime)
+ lpResult->flEchoTime = lpStart->flEchoTime;
+ else
+ lpResult->flEchoTime = (float)exp( (log(lpStart->flEchoTime) * flInvRatio) + (log(lpFinish->flEchoTime) * flRatio) );
+
+ // Echo Depth
+ if (lpStart->flEchoDepth == lpFinish->flEchoDepth)
+ lpResult->flEchoDepth = lpStart->flEchoDepth;
+ else
+ lpResult->flEchoDepth = (lpStart->flEchoDepth * flInvRatio) + (lpFinish->flEchoDepth * flRatio);
+
+ // Modulation Time
+ if (lpStart->flModulationTime == lpFinish->flModulationTime)
+ lpResult->flModulationTime = lpStart->flModulationTime;
+ else
+ lpResult->flModulationTime = (float)exp( (log(lpStart->flModulationTime) * flInvRatio) + (log(lpFinish->flModulationTime) * flRatio) );
+
+ // Modulation Depth
+ if (lpStart->flModulationDepth == lpFinish->flModulationDepth)
+ lpResult->flModulationDepth = lpStart->flModulationDepth;
+ else
+ lpResult->flModulationDepth = (lpStart->flModulationDepth * flInvRatio) + (lpFinish->flModulationDepth * flRatio);
+
+ // Air Absorption HF
+ if (lpStart->flAirAbsorptionHF == lpFinish->flAirAbsorptionHF)
+ lpResult->flAirAbsorptionHF = lpStart->flAirAbsorptionHF;
+ else
+ lpResult->flAirAbsorptionHF = (lpStart->flAirAbsorptionHF * flInvRatio) + (lpFinish->flAirAbsorptionHF * flRatio);
+
+ // HF Reference
+ if (lpStart->flHFReference == lpFinish->flHFReference)
+ lpResult->flHFReference = lpStart->flHFReference;
+ else
+ lpResult->flHFReference = (float)exp( (log(lpStart->flHFReference) * flInvRatio) + (log(lpFinish->flHFReference) * flRatio) );
+
+ // LF Reference
+ if (lpStart->flLFReference == lpFinish->flLFReference)
+ lpResult->flLFReference = lpStart->flLFReference;
+ else
+ lpResult->flLFReference = (float)exp( (log(lpStart->flLFReference) * flInvRatio) + (log(lpFinish->flLFReference) * flRatio) );
+
+ // Room Rolloff Factor
+ if (lpStart->flRoomRolloffFactor == lpFinish->flRoomRolloffFactor)
+ lpResult->flRoomRolloffFactor = lpStart->flRoomRolloffFactor;
+ else
+ lpResult->flRoomRolloffFactor = (lpStart->flRoomRolloffFactor * flInvRatio) + (lpFinish->flRoomRolloffFactor * flRatio);
+
+ // Flags
+ lpResult->ulFlags = (lpStart->ulFlags & lpFinish->ulFlags);
+
+ // Clamp Delays
+ if (lpResult->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY)
+ lpResult->flReflectionsDelay = EAXLISTENER_MAXREFLECTIONSDELAY;
+
+ if (lpResult->flReverbDelay > EAXLISTENER_MAXREVERBDELAY)
+ lpResult->flReverbDelay = EAXLISTENER_MAXREVERBDELAY;
+
+ return true;
+}
+
+
+/*
+ CheckEAX3LP
+ Checks that the parameters in the EAX 3 Listener Properties structure are in-range
+*/
+bool CheckEAX3LP(LPEAXLISTENERPROPERTIES lpEAX3LP)
+{
+ if ( (lpEAX3LP->lRoom < EAXLISTENER_MINROOM) || (lpEAX3LP->lRoom > EAXLISTENER_MAXROOM) )
+ return false;
+
+ if ( (lpEAX3LP->lRoomHF < EAXLISTENER_MINROOMHF) || (lpEAX3LP->lRoomHF > EAXLISTENER_MAXROOMHF) )
+ return false;
+
+ if ( (lpEAX3LP->lRoomLF < EAXLISTENER_MINROOMLF) || (lpEAX3LP->lRoomLF > EAXLISTENER_MAXROOMLF) )
+ return false;
+
+ if ( (lpEAX3LP->ulEnvironment < EAXLISTENER_MINENVIRONMENT) || (lpEAX3LP->ulEnvironment > EAXLISTENER_MAXENVIRONMENT) )
+ return false;
+
+ if ( (lpEAX3LP->flEnvironmentSize < EAXLISTENER_MINENVIRONMENTSIZE) || (lpEAX3LP->flEnvironmentSize > EAXLISTENER_MAXENVIRONMENTSIZE) )
+ return false;
+
+ if ( (lpEAX3LP->flEnvironmentDiffusion < EAXLISTENER_MINENVIRONMENTDIFFUSION) || (lpEAX3LP->flEnvironmentDiffusion > EAXLISTENER_MAXENVIRONMENTDIFFUSION) )
+ return false;
+
+ if ( (lpEAX3LP->flDecayTime < EAXLISTENER_MINDECAYTIME) || (lpEAX3LP->flDecayTime > EAXLISTENER_MAXDECAYTIME) )
+ return false;
+
+ if ( (lpEAX3LP->flDecayHFRatio < EAXLISTENER_MINDECAYHFRATIO) || (lpEAX3LP->flDecayHFRatio > EAXLISTENER_MAXDECAYHFRATIO) )
+ return false;
+
+ if ( (lpEAX3LP->flDecayLFRatio < EAXLISTENER_MINDECAYLFRATIO) || (lpEAX3LP->flDecayLFRatio > EAXLISTENER_MAXDECAYLFRATIO) )
+ return false;
+
+ if ( (lpEAX3LP->lReflections < EAXLISTENER_MINREFLECTIONS) || (lpEAX3LP->lReflections > EAXLISTENER_MAXREFLECTIONS) )
+ return false;
+
+ if ( (lpEAX3LP->flReflectionsDelay < EAXLISTENER_MINREFLECTIONSDELAY) || (lpEAX3LP->flReflectionsDelay > EAXLISTENER_MAXREFLECTIONSDELAY) )
+ return false;
+
+ if ( (lpEAX3LP->lReverb < EAXLISTENER_MINREVERB) || (lpEAX3LP->lReverb > EAXLISTENER_MAXREVERB) )
+ return false;
+
+ if ( (lpEAX3LP->flReverbDelay < EAXLISTENER_MINREVERBDELAY) || (lpEAX3LP->flReverbDelay > EAXLISTENER_MAXREVERBDELAY) )
+ return false;
+
+ if ( (lpEAX3LP->flEchoTime < EAXLISTENER_MINECHOTIME) || (lpEAX3LP->flEchoTime > EAXLISTENER_MAXECHOTIME) )
+ return false;
+
+ if ( (lpEAX3LP->flEchoDepth < EAXLISTENER_MINECHODEPTH) || (lpEAX3LP->flEchoDepth > EAXLISTENER_MAXECHODEPTH) )
+ return false;
+
+ if ( (lpEAX3LP->flModulationTime < EAXLISTENER_MINMODULATIONTIME) || (lpEAX3LP->flModulationTime > EAXLISTENER_MAXMODULATIONTIME) )
+ return false;
+
+ if ( (lpEAX3LP->flModulationDepth < EAXLISTENER_MINMODULATIONDEPTH) || (lpEAX3LP->flModulationDepth > EAXLISTENER_MAXMODULATIONDEPTH) )
+ return false;
+
+ if ( (lpEAX3LP->flAirAbsorptionHF < EAXLISTENER_MINAIRABSORPTIONHF) || (lpEAX3LP->flAirAbsorptionHF > EAXLISTENER_MAXAIRABSORPTIONHF) )
+ return false;
+
+ if ( (lpEAX3LP->flHFReference < EAXLISTENER_MINHFREFERENCE) || (lpEAX3LP->flHFReference > EAXLISTENER_MAXHFREFERENCE) )
+ return false;
+
+ if ( (lpEAX3LP->flLFReference < EAXLISTENER_MINLFREFERENCE) || (lpEAX3LP->flLFReference > EAXLISTENER_MAXLFREFERENCE) )
+ return false;
+
+ if ( (lpEAX3LP->flRoomRolloffFactor < EAXLISTENER_MINROOMROLLOFFFACTOR) || (lpEAX3LP->flRoomRolloffFactor > EAXLISTENER_MAXROOMROLLOFFFACTOR) )
+ return false;
+
+ if (lpEAX3LP->ulFlags & EAXLISTENERFLAGS_RESERVED)
+ return false;
+
+ return true;
+}
+
+/*
+ Clamp
+ Clamps the length of the vector to 1.0f
+*/
+void Clamp(EAXVECTOR *eaxVector)
+{
+ float flMagnitude;
+ float flInvMagnitude;
+
+ flMagnitude = (float)sqrt((eaxVector->x*eaxVector->x) + (eaxVector->y*eaxVector->y) + (eaxVector->z*eaxVector->z));
+
+ if (flMagnitude <= 1.0f)
+ return;
+
+ flInvMagnitude = 1.0f / flMagnitude;
+
+ eaxVector->x *= flInvMagnitude;
+ eaxVector->y *= flInvMagnitude;
+ eaxVector->z *= flInvMagnitude;
+}
+
+
+/***********************************************************************************************\
+*
+* To assist those developers wishing to add EAX effects to their level editors, each of the
+
+* List of string names of the various EAX 3.0 presets defined in eax-util.h
+* Arrays to group together presets of the same scenario
+*
+\***********************************************************************************************/
+
+
+//////////////////////////////////////////////////////
+// Array of scenario names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_SCENARIO_NAMES[] =
+{
+ "Castle",
+ "Factory",
+ "IcePalace",
+ "SpaceStation",
+ "WoodenShip",
+ "Sports",
+ "Prefab",
+ "Domes and Pipes",
+ "Outdoors",
+ "Mood",
+ "Driving",
+ "City",
+ "Miscellaneous",
+ "Original"
+};
+
+//////////////////////////////////////////////////////
+// Array of standardised location names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_LOCATION_NAMES[] =
+{
+ "Hall",
+ "Large Room",
+ "Medium Room",
+ "Small Room",
+ "Cupboard",
+ "Alcove",
+ "Long Passage",
+ "Short Passage",
+ "Courtyard"
+};
+
+//////////////////////////////////////////////////////
+// Standardised Location effects can be accessed //
+// from a matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_STANDARD_PRESETS[EAX30_NUM_STANDARD_SCENARIOS][EAX30_NUM_LOCATIONS]=
+{
+ {EAX30_PRESET_CASTLE_HALL, EAX30_PRESET_CASTLE_LARGEROOM, EAX30_PRESET_CASTLE_MEDIUMROOM, EAX30_PRESET_CASTLE_SMALLROOM, EAX30_PRESET_CASTLE_CUPBOARD, EAX30_PRESET_CASTLE_ALCOVE, EAX30_PRESET_CASTLE_LONGPASSAGE, EAX30_PRESET_CASTLE_SHORTPASSAGE, EAX30_PRESET_CASTLE_COURTYARD},
+ {EAX30_PRESET_FACTORY_HALL, EAX30_PRESET_FACTORY_LARGEROOM, EAX30_PRESET_FACTORY_MEDIUMROOM, EAX30_PRESET_FACTORY_SMALLROOM, EAX30_PRESET_FACTORY_CUPBOARD, EAX30_PRESET_FACTORY_ALCOVE, EAX30_PRESET_FACTORY_LONGPASSAGE, EAX30_PRESET_FACTORY_SHORTPASSAGE, EAX30_PRESET_FACTORY_COURTYARD},
+ {EAX30_PRESET_ICEPALACE_HALL, EAX30_PRESET_ICEPALACE_LARGEROOM, EAX30_PRESET_ICEPALACE_MEDIUMROOM, EAX30_PRESET_ICEPALACE_SMALLROOM, EAX30_PRESET_ICEPALACE_CUPBOARD, EAX30_PRESET_ICEPALACE_ALCOVE, EAX30_PRESET_ICEPALACE_LONGPASSAGE, EAX30_PRESET_ICEPALACE_SHORTPASSAGE, EAX30_PRESET_ICEPALACE_COURTYARD},
+ {EAX30_PRESET_SPACESTATION_HALL,EAX30_PRESET_SPACESTATION_LARGEROOM,EAX30_PRESET_SPACESTATION_MEDIUMROOM, EAX30_PRESET_SPACESTATION_SMALLROOM,EAX30_PRESET_SPACESTATION_CUPBOARD, EAX30_PRESET_SPACESTATION_ALCOVE, EAX30_PRESET_SPACESTATION_LONGPASSAGE, EAX30_PRESET_SPACESTATION_SHORTPASSAGE, EAX30_PRESET_SPACESTATION_HALL},
+ {EAX30_PRESET_WOODEN_HALL, EAX30_PRESET_WOODEN_LARGEROOM, EAX30_PRESET_WOODEN_MEDIUMROOM, EAX30_PRESET_WOODEN_SMALLROOM, EAX30_PRESET_WOODEN_CUPBOARD, EAX30_PRESET_WOODEN_ALCOVE, EAX30_PRESET_WOODEN_LONGPASSAGE, EAX30_PRESET_WOODEN_SHORTPASSAGE, EAX30_PRESET_WOODEN_COURTYARD},
+};
+
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of original environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_ORIGINAL_PRESET_NAMES[] =
+{
+ "Generic",
+ "Padded Cell",
+ "Room",
+ "Bathroom",
+ "Living Room",
+ "Stone Room",
+ "Auditorium",
+ "Concert Hall",
+ "Cave",
+ "Arena",
+ "Hangar",
+ "Carpetted Hallway",
+ "Hallway",
+ "Stone Corridor",
+ "Alley",
+ "Forest",
+ "City",
+ "Mountains",
+ "Quarry",
+ "Plain",
+ "Parking Lot",
+ "Sewer Pipe",
+ "Underwater",
+ "Drugged",
+ "Dizzy",
+ "Psychotic"
+};
+
+//////////////////////////////////////////////////////
+// Sports effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_ORIGINAL_PRESETS[] =
+{
+ EAX30_PRESET_GENERIC,
+ EAX30_PRESET_PADDEDCELL,
+ EAX30_PRESET_ROOM,
+ EAX30_PRESET_BATHROOM,
+ EAX30_PRESET_LIVINGROOM,
+ EAX30_PRESET_STONEROOM,
+ EAX30_PRESET_AUDITORIUM,
+ EAX30_PRESET_CONCERTHALL,
+ EAX30_PRESET_CAVE,
+ EAX30_PRESET_ARENA,
+ EAX30_PRESET_HANGAR,
+ EAX30_PRESET_CARPETTEDHALLWAY,
+ EAX30_PRESET_HALLWAY,
+ EAX30_PRESET_STONECORRIDOR,
+ EAX30_PRESET_ALLEY,
+ EAX30_PRESET_FOREST,
+ EAX30_PRESET_CITY,
+ EAX30_PRESET_MOUNTAINS,
+ EAX30_PRESET_QUARRY,
+ EAX30_PRESET_PLAIN,
+ EAX30_PRESET_PARKINGLOT,
+ EAX30_PRESET_SEWERPIPE,
+ EAX30_PRESET_UNDERWATER,
+ EAX30_PRESET_DRUGGED,
+ EAX30_PRESET_DIZZY,
+ EAX30_PRESET_PSYCHOTIC
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of sport environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_SPORTS_PRESET_NAMES[] =
+{
+ "Empty Stadium",
+ "Full Stadium",
+ "Stadium Tannoy",
+ "Squash Court",
+ "Small Swimming Pool",
+ "Large Swimming Pool",
+ "Gymnasium"
+};
+
+//////////////////////////////////////////////////////
+// Sports effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_SPORTS_PRESETS[] =
+{
+ EAX30_PRESET_SPORT_EMPTYSTADIUM,
+ EAX30_PRESET_SPORT_FULLSTADIUM,
+ EAX30_PRESET_SPORT_STADIUMTANNOY,
+ EAX30_PRESET_SPORT_SQUASHCOURT,
+ EAX30_PRESET_SPORT_SMALLSWIMMINGPOOL,
+ EAX30_PRESET_SPORT_LARGESWIMMINGPOOL,
+ EAX30_PRESET_SPORT_GYMNASIUM
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of prefab environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_PREFAB_PRESET_NAMES[] =
+{
+ "Workshop",
+ "School Room",
+ "Practise Room",
+ "Outhouse",
+ "Caravan"
+};
+
+//////////////////////////////////////////////////////
+// Prefab effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_PREFAB_PRESETS[] =
+{
+ EAX30_PRESET_PREFAB_WORKSHOP,
+ EAX30_PRESET_PREFAB_SCHOOLROOM,
+ EAX30_PRESET_PREFAB_PRACTISEROOM,
+ EAX30_PRESET_PREFAB_OUTHOUSE,
+ EAX30_PRESET_PREFAB_CARAVAN
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of Domes & Pipes environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_DOMESNPIPES_PRESET_NAMES[] =
+{
+ "Domed Tomb",
+ "Saint Paul's Dome",
+ "Small Pipe",
+ "Long Thin Pipe",
+ "Large Pipe",
+ "Resonant Pipe"
+};
+
+//////////////////////////////////////////////////////
+// Domes & Pipes effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_DOMESNPIPES_PRESETS[] =
+{
+ EAX30_PRESET_DOME_TOMB,
+ EAX30_PRESET_DOME_SAINTPAULS,
+ EAX30_PRESET_PIPE_SMALL,
+ EAX30_PRESET_PIPE_LONGTHIN,
+ EAX30_PRESET_PIPE_LARGE,
+ EAX30_PRESET_PIPE_RESONANT
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of Outdoors environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_OUTDOORS_PRESET_NAMES[] =
+{
+ "Backyard",
+ "Rolling Plains",
+ "Deep Canyon",
+ "Creek",
+ "Valley"
+};
+
+//////////////////////////////////////////////////////
+// Outdoors effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_OUTDOORS_PRESETS[] =
+{
+ EAX30_PRESET_OUTDOORS_BACKYARD,
+ EAX30_PRESET_OUTDOORS_ROLLINGPLAINS,
+ EAX30_PRESET_OUTDOORS_DEEPCANYON,
+ EAX30_PRESET_OUTDOORS_CREEK,
+ EAX30_PRESET_OUTDOORS_VALLEY
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of Mood environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_MOOD_PRESET_NAMES[] =
+{
+ "Heaven",
+ "Hell",
+ "Memory"
+};
+
+//////////////////////////////////////////////////////
+// Mood effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_MOOD_PRESETS[] =
+{
+ EAX30_PRESET_MOOD_HEAVEN,
+ EAX30_PRESET_MOOD_HELL,
+ EAX30_PRESET_MOOD_MEMORY
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of driving environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_DRIVING_PRESET_NAMES[] =
+{
+ "Race Commentator",
+ "Pit Garage",
+ "In-car (Stripped out racer)",
+ "In-car (Sportscar)",
+ "In-car (Luxury)",
+ "Full Grandstand",
+ "Empty Grandstand",
+ "Tunnel"
+};
+
+//////////////////////////////////////////////////////
+// Driving effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_DRIVING_PRESETS[] =
+{
+ EAX30_PRESET_DRIVING_COMMENTATOR,
+ EAX30_PRESET_DRIVING_PITGARAGE,
+ EAX30_PRESET_DRIVING_INCAR_RACER,
+ EAX30_PRESET_DRIVING_INCAR_SPORTS,
+ EAX30_PRESET_DRIVING_INCAR_LUXURY,
+ EAX30_PRESET_DRIVING_FULLGRANDSTAND,
+ EAX30_PRESET_DRIVING_EMPTYGRANDSTAND,
+ EAX30_PRESET_DRIVING_TUNNEL
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of City environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_CITY_PRESET_NAMES[] =
+{
+ "City Streets",
+ "Subway",
+ "Museum",
+ "Library",
+ "Underpass",
+ "Abandoned City"
+};
+
+//////////////////////////////////////////////////////
+// City effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_CITY_PRESETS[] =
+{
+ EAX30_PRESET_CITY_STREETS,
+ EAX30_PRESET_CITY_SUBWAY,
+ EAX30_PRESET_CITY_MUSEUM,
+ EAX30_PRESET_CITY_LIBRARY,
+ EAX30_PRESET_CITY_UNDERPASS,
+ EAX30_PRESET_CITY_ABANDONED
+};
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Array of Misc environment names //
+//////////////////////////////////////////////////////
+
+const char* EAX30_MISC_PRESET_NAMES[] =
+{
+ "Dusty Box Room",
+ "Chapel",
+ "Small Water Room"
+};
+
+//////////////////////////////////////////////////////
+// Misc effects matrix //
+//////////////////////////////////////////////////////
+
+EAXLISTENERPROPERTIES EAX30_MISC_PRESETS[] =
+{
+ EAX30_PRESET_DUSTYROOM,
+ EAX30_PRESET_CHAPEL,
+ EAX30_PRESET_SMALLWATERROOM
+};
+
diff --git a/src/audio/eax/eax-util.h b/src/audio/eax/eax-util.h
new file mode 100644
index 00000000..441f0115
--- /dev/null
+++ b/src/audio/eax/eax-util.h
@@ -0,0 +1,765 @@
+/*******************************************************************\
+* *
+* EAX-UTIL.H - utilities for Environmental Audio Extensions v. 3.0 *
+* Definitions of the Original 26 EAX Presets *
+* Definitions for some new EAX Presets *
+* Definitions of some Material Presets *
+* Function declaration for EAX Morphing *
+* *
+\*******************************************************************/
+
+#ifndef EAXUTIL_INCLUDED
+#define EAXUTIL_INCLUDED
+
+#include <eax.h>
+
+/***********************************************************************************************
+* Function : EAX3ListenerInterpolate
+* Params : lpStart - Initial EAX 3 Listener parameters
+* : lpFinish - Final EAX 3 Listener parameters
+* : flRatio - Ratio Destination : Source (0.0 == Source, 1.0 == Destination)
+* : lpResult - Interpolated EAX 3 Listener parameters
+* : bCheckValues - Check EAX 3.0 parameters are in range,
+ - default == false (no checking)
+************************************************************************************************/
+bool EAX3ListenerInterpolate(EAXLISTENERPROPERTIES *lpStartEAX3LP, EAXLISTENERPROPERTIES *lpFinishEAX3LP,
+ float flRatio, EAXLISTENERPROPERTIES *lpResultEAX3LP, bool bCheckValues = false);
+
+
+/***********************************************************************************************\
+*
+* Legacy environment presets for use with DSPROPERTY_EAXLISTENER_ALLPARAMETERS.
+* Each array conforms to the DSPROPSETID_EAX30_ListenerProperties structure defined in EAX.H.
+*
+************************************************************************************************/
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_GENERIC \
+ {0, 7.5f, 1.000f, -1000, -100, 0, 1.49f, 0.83f, 1.00f, -2602, 0.007f, 0.00f,0.00f,0.00f, 200, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_PADDEDCELL \
+ {1, 1.4f, 1.000f, -1000, -6000, 0, 0.17f, 0.10f, 1.00f, -1204, 0.001f, 0.00f,0.00f,0.00f, 207, 0.002f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_ROOM \
+ {2, 1.9f, 1.000f, -1000, -454, 0, 0.40f, 0.83f, 1.00f, -1646, 0.002f, 0.00f,0.00f,0.00f, 53, 0.003f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_BATHROOM \
+ {3, 1.4f, 1.000f, -1000, -1200, 0, 1.49f, 0.54f, 1.00f, -370, 0.007f, 0.00f,0.00f,0.00f, 1030, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_LIVINGROOM \
+ {4, 2.5f, 1.000f, -1000, -6000, 0, 0.50f, 0.10f, 1.00f, -1376, 0.003f, 0.00f,0.00f,0.00f, -1104, 0.004f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_STONEROOM \
+ {5, 11.6f, 1.000f, -1000, -300, 0, 2.31f, 0.64f, 1.00f, -711, 0.012f, 0.00f,0.00f,0.00f, 83, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_AUDITORIUM \
+ {6, 21.6f, 1.000f, -1000, -476, 0, 4.32f, 0.59f, 1.00f, -789, 0.020f, 0.00f,0.00f,0.00f, -289, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_CONCERTHALL \
+ {7, 19.6f, 1.000f, -1000, -500, 0, 3.92f, 0.70f, 1.00f, -1230, 0.020f, 0.00f,0.00f,0.00f, -02, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_CAVE \
+ {8, 14.6f, 1.000f, -1000, 0, 0, 2.91f, 1.30f, 1.00f, -602, 0.015f, 0.00f,0.00f,0.00f, -302, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_ARENA \
+ {9, 36.2f, 1.000f, -1000, -698, 0, 7.24f, 0.33f, 1.00f, -1166, 0.020f, 0.00f,0.00f,0.00f, 16, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_HANGAR \
+ {10, 50.3f, 1.000f, -1000, -1000, 0, 10.05f, 0.23f, 1.00f, -602, 0.020f, 0.00f,0.00f,0.00f, 198, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_CARPETTEDHALLWAY \
+ {11, 1.9f, 1.000f, -1000, -4000, 0, 0.30f, 0.10f, 1.00f, -1831, 0.002f, 0.00f,0.00f,0.00f, -1630, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_HALLWAY \
+ {12, 1.8f, 1.000f, -1000, -300, 0, 1.49f, 0.59f, 1.00f, -1219, 0.007f, 0.00f,0.00f,0.00f, 441, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_STONECORRIDOR \
+ {13, 13.5f, 1.000f, -1000, -237, 0, 2.70f, 0.79f, 1.00f, -1214, 0.013f, 0.00f,0.00f,0.00f, 395, 0.020f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_ALLEY \
+ {14, 7.5f, 0.300f, -1000, -270, 0, 1.49f, 0.86f, 1.00f, -1204, 0.007f, 0.00f,0.00f,0.00f, -4, 0.011f, 0.00f,0.00f,0.00f, 0.125f, 0.950f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_FOREST \
+ {15, 38.0f, 0.300f, -1000, -3300, 0, 1.49f, 0.54f, 1.00f, -2560, 0.162f, 0.00f,0.00f,0.00f, -229, 0.088f, 0.00f,0.00f,0.00f, 0.125f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_CITY \
+ {16, 7.5f, 0.500f, -1000, -800, 0, 1.49f, 0.67f, 1.00f, -2273, 0.007f, 0.00f,0.00f,0.00f, -1691, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_MOUNTAINS \
+ {17, 100.0f, 0.270f, -1000, -2500, 0, 1.49f, 0.21f, 1.00f, -2780, 0.300f, 0.00f,0.00f,0.00f, -1434, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_QUARRY \
+ {18, 17.5f, 1.000f, -1000, -1000, 0, 1.49f, 0.83f, 1.00f, -10000, 0.061f, 0.00f,0.00f,0.00f, 500, 0.025f, 0.00f,0.00f,0.00f, 0.125f, 0.700f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_PLAIN \
+ {19, 42.5f, 0.210f, -1000, -2000, 0, 1.49f, 0.50f, 1.00f, -2466, 0.179f, 0.00f,0.00f,0.00f, -1926, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_PARKINGLOT \
+ {20, 8.3f, 1.000f, -1000, 0, 0, 1.65f, 1.50f, 1.00f, -1363, 0.008f, 0.00f,0.00f,0.00f, -1153, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_SEWERPIPE \
+ {21, 1.7f, 0.800f, -1000, -1000, 0, 2.81f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_UNDERWATER \
+ {22, 1.8f, 1.000f, -1000, -4000, 0, 1.49f, 0.10f, 1.00f, -449, 0.007f, 0.00f,0.00f,0.00f, 1700, 0.011f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 1.180f, 0.348f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_DRUGGED \
+ {23, 1.9f, 0.500f, -1000, 0, 0, 8.39f, 1.39f, 1.00f, -115, 0.002f, 0.00f,0.00f,0.00f, 985, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_DIZZY \
+ {24, 1.8f, 0.600f, -1000, -400, 0, 17.23f, 0.56f, 1.00f, -1713, 0.020f, 0.00f,0.00f,0.00f, -613, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.810f, 0.310f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_PSYCHOTIC \
+ {25, 1.0f, 0.500f, -1000, -151, 0, 7.56f, 0.91f, 1.00f, -626, 0.020f, 0.00f,0.00f,0.00f, 774, 0.030f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 4.000f, 1.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+
+
+/***********************************************************************************************\
+*
+* New environment presets for use with DSPROPERTY_EAXLISTENER_ALLPARAMETERS.
+* Each array conforms to the DSPROPSETID_EAX30_ListenerProperties structure defined in EAX.H.
+*
+************************************************************************************************/
+
+// STANDARDISED-LOCATION SCENARIOS
+
+// CASTLE PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_CASTLE_SMALLROOM \
+ { 26, 8.3f, 0.890f, -1100, -800, -2000, 1.22f, 0.83f, 0.31f, -100, 0.022f, 0.00f,0.00f,0.00f, 0, 0.011f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_SHORTPASSAGE \
+ { 26, 8.3f, 0.890f, -1000, -1000, -2000, 2.32f, 0.83f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, -500, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_MEDIUMROOM \
+ { 26, 8.3f, 0.930f, -1000, -1100, -2000, 2.04f, 0.83f, 0.46f, -300, 0.022f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.155f, 0.030f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_LONGPASSAGE \
+ { 26, 8.3f, 0.890f, -1000, -800, -2000, 3.42f, 0.83f, 0.31f, -200, 0.007f, 0.00f,0.00f,0.00f, -600, 0.023f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_LARGEROOM \
+ { 26, 8.3f, 0.820f, -1000, -1100, -1800, 2.53f, 0.83f, 0.50f, -900, 0.034f, 0.00f,0.00f,0.00f, -400, 0.016f, 0.00f,0.00f,0.00f, 0.185f, 0.070f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_HALL \
+ { 26, 8.3f, 0.810f, -1000, -1100, -1500, 3.14f, 0.79f, 0.62f, -1300, 0.056f, 0.00f,0.00f,0.00f, -500, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_CUPBOARD \
+ { 26, 8.3f, 0.890f, -1000, -1100, -2000, 0.67f, 0.87f, 0.31f, 300, 0.010f, 0.00f,0.00f,0.00f, 300, 0.007f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_CASTLE_COURTYARD \
+ { 26, 8.3f, 0.420f, -1100, -700, -900, 2.13f, 0.61f, 0.23f, -2300, 0.112f, 0.00f,0.00f,0.00f, -1500, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.370f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_CASTLE_ALCOVE \
+ { 26, 8.3f, 0.890f, -1000, -600, -2000, 1.64f, 0.87f, 0.31f, -100, 0.007f, 0.00f,0.00f,0.00f, -500, 0.034f, 0.00f,0.00f,0.00f, 0.138f, 0.080f, 0.250f, 0.000f, -5.0f, 5168.6f, 139.5f, 0.00f, 0x20 }
+
+
+// FACTORY PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_FACTORY_ALCOVE \
+ { 26, 1.8f, 0.590f, -1200, -200, -600, 3.14f, 0.65f, 1.31f, 300, 0.010f, 0.00f,0.00f,0.00f, -1200, 0.038f, 0.00f,0.00f,0.00f, 0.114f, 0.100f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_SHORTPASSAGE \
+ { 26, 1.8f, 0.640f, -1200, -200, -600, 2.53f, 0.65f, 1.31f, 0, 0.010f, 0.00f,0.00f,0.00f, -600, 0.038f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_MEDIUMROOM \
+ { 26, 1.9f, 0.820f, -1200, -200, -600, 2.76f, 0.65f, 1.31f, -1100, 0.022f, 0.00f,0.00f,0.00f, -400, 0.023f, 0.00f,0.00f,0.00f, 0.174f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_LONGPASSAGE \
+ { 26, 1.8f, 0.640f, -1200, -200, -600, 4.06f, 0.65f, 1.31f, 0, 0.020f, 0.00f,0.00f,0.00f, -900, 0.037f, 0.00f,0.00f,0.00f, 0.135f, 0.230f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_LARGEROOM \
+ { 26, 1.9f, 0.750f, -1200, -300, -400, 4.24f, 0.51f, 1.31f, -1500, 0.039f, 0.00f,0.00f,0.00f, -600, 0.023f, 0.00f,0.00f,0.00f, 0.231f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_HALL \
+ { 26, 1.9f, 0.750f, -1000, -300, -400, 7.43f, 0.51f, 1.31f, -2400, 0.073f, 0.00f,0.00f,0.00f, -500, 0.027f, 0.00f,0.00f,0.00f, 0.250f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_CUPBOARD \
+ { 26, 1.7f, 0.630f, -1200, -200, -600, 0.49f, 0.65f, 1.31f, 200, 0.010f, 0.00f,0.00f,0.00f, 200, 0.032f, 0.00f,0.00f,0.00f, 0.107f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_COURTYARD \
+ { 26, 1.7f, 0.570f, -1000, -1000, -400, 2.32f, 0.29f, 0.56f, -2400, 0.090f, 0.00f,0.00f,0.00f, -2000, 0.039f, 0.00f,0.00f,0.00f, 0.250f, 0.290f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+#define EAX30_PRESET_FACTORY_SMALLROOM \
+ { 26, 1.8f, 0.820f, -1200, -200, -600, 1.72f, 0.65f, 1.31f, -300, 0.010f, 0.00f,0.00f,0.00f, -200, 0.024f, 0.00f,0.00f,0.00f, 0.119f, 0.070f, 0.250f, 0.000f, -0.0f, 3762.6f, 362.5f, 0.00f, 0x20 }
+
+// ICE PALACE PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_ICEPALACE_ALCOVE \
+ { 26, 2.7f, 0.840f, -1000, -500, -1100, 2.76f, 1.46f, 0.28f, 100, 0.010f, 0.00f,0.00f,0.00f, -1200, 0.030f, 0.00f,0.00f,0.00f, 0.161f, 0.090f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_SHORTPASSAGE \
+ { 26, 2.7f, 0.750f, -1000, -500, -1100, 1.79f, 1.46f, 0.28f, -600, 0.010f, 0.00f,0.00f,0.00f, -700, 0.019f, 0.00f,0.00f,0.00f, 0.177f, 0.090f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_MEDIUMROOM \
+ { 26, 2.7f, 0.870f, -1000, -500, -700, 2.22f, 1.53f, 0.32f, -800, 0.039f, 0.00f,0.00f,0.00f, -1200, 0.027f, 0.00f,0.00f,0.00f, 0.186f, 0.120f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_LONGPASSAGE \
+ { 26, 2.7f, 0.770f, -1000, -500, -800, 3.01f, 1.46f, 0.28f, -200, 0.012f, 0.00f,0.00f,0.00f, -800, 0.025f, 0.00f,0.00f,0.00f, 0.186f, 0.040f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_LARGEROOM \
+ { 26, 2.9f, 0.810f, -1000, -500, -700, 3.14f, 1.53f, 0.32f, -1200, 0.039f, 0.00f,0.00f,0.00f, -1300, 0.027f, 0.00f,0.00f,0.00f, 0.214f, 0.110f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_HALL \
+ { 26, 2.9f, 0.760f, -1000, -700, -500, 5.49f, 1.53f, 0.38f, -1900, 0.054f, 0.00f,0.00f,0.00f, -1400, 0.052f, 0.00f,0.00f,0.00f, 0.226f, 0.110f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_CUPBOARD \
+ { 26, 2.7f, 0.830f, -1000, -600, -1300, 0.76f, 1.53f, 0.26f, 100, 0.012f, 0.00f,0.00f,0.00f, 100, 0.016f, 0.00f,0.00f,0.00f, 0.143f, 0.080f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_COURTYARD \
+ { 26, 2.9f, 0.590f, -1000, -1100, -1000, 2.04f, 1.20f, 0.38f, -2000, 0.073f, 0.00f,0.00f,0.00f, -2200, 0.043f, 0.00f,0.00f,0.00f, 0.235f, 0.480f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+#define EAX30_PRESET_ICEPALACE_SMALLROOM \
+ { 26, 2.7f, 0.840f, -1000, -500, -1100, 1.51f, 1.53f, 0.27f, -100, 0.010f, 0.00f,0.00f,0.00f, -900, 0.011f, 0.00f,0.00f,0.00f, 0.164f, 0.140f, 0.250f, 0.000f, -0.0f, 12428.5f, 99.6f, 0.00f, 0x20 }
+
+// SPACE STATION PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_SPACESTATION_ALCOVE \
+ { 26, 1.5f, 0.780f, -1100, -300, -100, 1.16f, 0.81f, 0.55f, 300, 0.007f, 0.00f,0.00f,0.00f, -500, 0.018f, 0.00f,0.00f,0.00f, 0.192f, 0.210f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_MEDIUMROOM \
+ { 26, 1.5f, 0.750f, -1000, -400, -100, 3.01f, 0.50f, 0.55f, -1000, 0.034f, 0.00f,0.00f,0.00f, -700, 0.035f, 0.00f,0.00f,0.00f, 0.209f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_SHORTPASSAGE \
+ { 26, 1.5f, 0.870f, -1000, -400, -100, 3.57f, 0.50f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, -600, 0.016f, 0.00f,0.00f,0.00f, 0.172f, 0.200f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_LONGPASSAGE \
+ { 26, 1.9f, 0.820f, -1000, -400, -100, 4.62f, 0.62f, 0.55f, 0, 0.012f, 0.00f,0.00f,0.00f, -800, 0.031f, 0.00f,0.00f,0.00f, 0.250f, 0.230f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_LARGEROOM \
+ { 26, 1.8f, 0.810f, -1000, -400, -100, 3.89f, 0.38f, 0.61f, -1200, 0.056f, 0.00f,0.00f,0.00f, -800, 0.035f, 0.00f,0.00f,0.00f, 0.233f, 0.280f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_HALL \
+ { 26, 1.9f, 0.870f, -1000, -400, -100, 7.11f, 0.38f, 0.61f, -1500, 0.100f, 0.00f,0.00f,0.00f, -1000, 0.047f, 0.00f,0.00f,0.00f, 0.250f, 0.250f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_CUPBOARD \
+ { 26, 1.4f, 0.560f, -1000, -300, -100, 0.79f, 0.81f, 0.55f, 200, 0.007f, 0.00f,0.00f,0.00f, 400, 0.018f, 0.00f,0.00f,0.00f, 0.181f, 0.310f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPACESTATION_SMALLROOM \
+ { 26, 1.5f, 0.700f, -1000, -300, -100, 1.72f, 0.82f, 0.55f, -400, 0.007f, 0.00f,0.00f,0.00f, -500, 0.013f, 0.00f,0.00f,0.00f, 0.188f, 0.260f, 0.250f, 0.000f, -5.0f, 3316.1f, 458.2f, 0.00f, 0x20 }
+
+// WOODEN GALLEON PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_WOODEN_ALCOVE \
+ { 26, 7.5f, 1.000f, -1100, -1800, -1000, 1.22f, 0.62f, 0.91f, -100, 0.012f, 0.00f,0.00f,0.00f, -600, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_SHORTPASSAGE \
+ { 26, 7.5f, 1.000f, -1100, -1800, -1000, 1.45f, 0.50f, 0.87f, -300, 0.012f, 0.00f,0.00f,0.00f, -700, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_MEDIUMROOM \
+ { 26, 7.5f, 1.000f, -1200, -2000, -1100, 1.07f, 0.42f, 0.82f, -300, 0.039f, 0.00f,0.00f,0.00f, -400, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_LONGPASSAGE \
+ { 26, 7.5f, 1.000f, -1100, -2000, -1000, 1.79f, 0.40f, 0.79f, -200, 0.020f, 0.00f,0.00f,0.00f, -1000, 0.036f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_LARGEROOM \
+ { 26, 7.5f, 1.000f, -1200, -2100, -1100, 1.45f, 0.33f, 0.82f, -300, 0.056f, 0.00f,0.00f,0.00f, -500, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_HALL \
+ { 26, 7.5f, 1.000f, -1200, -2200, -1100, 1.95f, 0.30f, 0.82f, -300, 0.068f, 0.00f,0.00f,0.00f, -500, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_CUPBOARD \
+ { 26, 7.5f, 1.000f, -1000, -1700, -1000, 0.56f, 0.46f, 0.91f, -100, 0.012f, 0.00f,0.00f,0.00f, -100, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_SMALLROOM \
+ { 26, 7.5f, 1.000f, -1200, -1900, -1000, 0.79f, 0.32f, 0.87f, -200, 0.032f, 0.00f,0.00f,0.00f, -300, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+#define EAX30_PRESET_WOODEN_COURTYARD \
+ { 26, 7.5f, 0.650f, -1700, -2200, -1000, 1.79f, 0.35f, 0.79f, -700, 0.063f, 0.00f,0.00f,0.00f, -2300, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 4705.0f, 99.6f, 0.00f, 0x3f }
+
+
+// OTHER SCENARIOS
+
+// SPORTS PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_SPORT_EMPTYSTADIUM \
+ { 26, 7.2f, 1.000f, -1300, -700, -200, 6.26f, 0.51f, 1.10f, -2400, 0.183f, 0.00f,0.00f,0.00f, -1100, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPORT_SQUASHCOURT \
+ { 26, 7.5f, 0.750f, -1100, -1000, -200, 2.22f, 0.91f, 1.16f, -700, 0.007f, 0.00f,0.00f,0.00f, -300, 0.011f, 0.00f,0.00f,0.00f, 0.126f, 0.190f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPORT_SMALLSWIMMINGPOOL \
+ { 26, 36.2f, 0.700f, -1400, -200, -100, 2.76f, 1.25f, 1.14f, -400, 0.020f, 0.00f,0.00f,0.00f, -300, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 }
+#define EAX30_PRESET_SPORT_LARGESWIMMINGPOOL\
+ { 26, 36.2f, 0.820f, -1200, -200, 0, 5.49f, 1.31f, 1.14f, -700, 0.039f, 0.00f,0.00f,0.00f, -800, 0.049f, 0.00f,0.00f,0.00f, 0.222f, 0.550f, 1.159f, 0.210f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 }
+#define EAX30_PRESET_SPORT_GYMNASIUM \
+ { 26, 7.5f, 0.810f, -1200, -700, -100, 3.14f, 1.06f, 1.35f, -800, 0.029f, 0.00f,0.00f,0.00f, -700, 0.045f, 0.00f,0.00f,0.00f, 0.146f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPORT_FULLSTADIUM \
+ { 26, 7.2f, 1.000f, -1300, -2300, -200, 5.25f, 0.17f, 0.80f, -2000, 0.188f, 0.00f,0.00f,0.00f, -1300, 0.038f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_SPORT_STADIUMTANNOY \
+ { 26, 3.0f, 0.780f, -900, -500, -600, 2.53f, 0.88f, 0.68f, -1100, 0.230f, 0.00f,0.00f,0.00f, -600, 0.063f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+
+// PREFAB PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_PREFAB_WORKSHOP \
+ { 26, 1.9f, 1.000f, -1000, -1700, -800, 0.76f, 1.00f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, -200, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 }
+#define EAX30_PRESET_PREFAB_SCHOOLROOM \
+ { 26, 1.86f, 0.690f, -1100, -400, -600, 0.98f, 0.45f, 0.18f, 300, 0.017f, 0.00f,0.00f,0.00f, 0, 0.015f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_PREFAB_PRACTISEROOM \
+ { 26, 1.86f, 0.870f, -1000, -800, -600, 1.12f, 0.56f, 0.18f, 200, 0.010f, 0.00f,0.00f,0.00f, -200, 0.011f, 0.00f,0.00f,0.00f, 0.095f, 0.140f, 0.250f, 0.000f, -0.0f, 7176.9f, 211.2f, 0.00f, 0x20 }
+#define EAX30_PRESET_PREFAB_OUTHOUSE \
+ { 26, 80.3f, 0.820f, -1100, -1900, -1600, 1.38f, 0.38f, 0.35f, -100, 0.024f, 0.00f,0.00f,-0.00f, -800, 0.044f, 0.00f,0.00f,0.00f, 0.121f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 }
+#define EAX30_PRESET_PREFAB_CARAVAN \
+ { 26, 8.3f, 1.000f, -1000, -2100, -1800, 0.43f, 1.50f, 1.00f, 0, 0.012f, 0.00f,0.00f,0.00f, 400, 0.012f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x1f }
+ // for US developers, a caravan is the same as a trailer =o)
+
+
+// DOME AND PIPE PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_DOME_TOMB \
+ { 26, 51.8f, 0.790f, -1000, -900, -1300, 4.18f, 0.21f, 0.10f, -825, 0.030f, 0.00f,0.00f,0.00f, -125, 0.022f, 0.00f,0.00f,0.00f, 0.177f, 0.190f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 }
+#define EAX30_PRESET_PIPE_SMALL \
+ { 26, 50.3f, 1.000f, -1000, -900, -1300, 5.04f, 0.10f, 0.10f, -600, 0.032f, 0.00f,0.00f,0.00f, 400, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_DOME_SAINTPAULS \
+ { 26, 50.3f, 0.870f, -1000, -900, -1300, 10.48f, 0.19f, 0.10f, -1500, 0.090f, 0.00f,0.00f,0.00f, -500, 0.042f, 0.00f,0.00f,0.00f, 0.250f, 0.120f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_PIPE_LONGTHIN \
+ { 26, 1.6f, 0.910f, -1200, -700, -1100, 9.21f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -1000, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 }
+#define EAX30_PRESET_PIPE_LARGE \
+ { 26, 50.3f, 1.000f, -1000, -900, -1300, 8.45f, 0.10f, 0.10f, -800, 0.046f, 0.00f,0.00f,0.00f, 0, 0.032f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_PIPE_RESONANT \
+ { 26, 1.3f, 0.910f, -1200, -700, -1100, 6.81f, 0.18f, 0.10f, -300, 0.010f, 0.00f,0.00f,0.00f, -700, 0.022f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2854.4f, 20.0f, 0.00f, 0x0 }
+
+// OUTDOORS PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_OUTDOORS_BACKYARD \
+ { 26, 80.3f, 0.450f, -1100, -1200, -600, 1.12f, 0.34f, 0.46f, -1100, 0.049f, 0.00f,0.00f,-0.00f, -1300, 0.023f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 }
+#define EAX30_PRESET_OUTDOORS_ROLLINGPLAINS \
+ { 26, 80.3f, 0.000f, -1100, -3900, -400, 2.13f, 0.21f, 0.46f, -2000, 0.300f, 0.00f,0.00f,-0.00f, -1500, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 }
+#define EAX30_PRESET_OUTDOORS_DEEPCANYON \
+ { 26, 80.3f, 0.740f, -1100, -1500, -400, 3.89f, 0.21f, 0.46f, -2000, 0.193f, 0.00f,0.00f,-0.00f, -1100, 0.019f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 }
+#define EAX30_PRESET_OUTDOORS_CREEK \
+ { 26, 80.3f, 0.350f, -1100, -1500, -600, 2.13f, 0.21f, 0.46f, -1700, 0.115f, 0.00f,0.00f,-0.00f, -1100, 0.031f, 0.00f,0.00f,0.00f, 0.218f, 0.340f, 0.250f, 0.000f, -5.0f, 4399.1f, 242.9f, 0.00f, 0x0 }
+#define EAX30_PRESET_OUTDOORS_VALLEY \
+ { 26, 80.3f, 0.280f, -1100, -3100, -1600, 2.88f, 0.26f, 0.35f, -3200, 0.163f, 0.00f,0.00f,-0.00f, -1000, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 0.340f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 }
+
+
+// MOOD PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_MOOD_HEAVEN \
+ { 26, 19.6f, 0.940f, -1000, -200, -700, 5.04f, 1.12f, 0.56f, -1230, 0.020f, 0.00f,0.00f,0.00f, -200, 0.029f, 0.00f,0.00f,0.00f, 0.250f, 0.080f, 2.742f, 0.050f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_MOOD_HELL \
+ { 26, 100.0f, 0.570f, -1000, -900, -700, 3.57f, 0.49f, 2.00f, -10000, 0.020f, 0.00f,0.00f,0.00f, 100, 0.030f, 0.00f,0.00f,0.00f, 0.110f, 0.040f, 2.109f, 0.520f, -5.0f, 5000.0f, 139.5f, 0.00f, 0x40 }
+#define EAX30_PRESET_MOOD_MEMORY \
+ { 26, 8.0f, 0.850f, -1000, -400, -900, 4.06f, 0.82f, 0.56f, -2800, 0.000f, 0.00f,0.00f,0.00f, -500, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.474f, 0.450f, -2.0f, 5000.0f, 250.0f, 0.00f, 0x0 }
+
+// DRIVING SIMULATION PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_DRIVING_COMMENTATOR \
+ { 26, 3.0f, 0.000f, -900, -500, -600, 2.42f, 0.88f, 0.68f, -1400, 0.093f, 0.00f,0.00f,0.00f, -1200, 0.017f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_DRIVING_PITGARAGE \
+ { 26, 1.9f, 0.590f, -1400, -300, -500, 1.72f, 0.93f, 0.87f, -500, 0.000f, 0.00f,0.00f,0.00f, 0, 0.016f, 0.00f,0.00f,0.00f, 0.250f, 0.110f, 0.250f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 }
+#define EAX30_PRESET_DRIVING_INCAR_RACER \
+ { 26, 1.1f, 0.800f, -700, 0, -200, 0.17f, 2.00f, 0.41f, 500, 0.007f, 0.00f,0.00f,0.00f, -500, 0.015f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_DRIVING_INCAR_SPORTS \
+ { 26, 1.1f, 0.800f, -900, -400, 0, 0.17f, 0.75f, 0.41f, 0, 0.010f, 0.00f,0.00f,0.00f, -600, 0.000f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_DRIVING_INCAR_LUXURY \
+ { 26, 1.6f, 1.000f, -800, -2000, -600, 0.13f, 0.41f, 0.46f, -200, 0.010f, 0.00f,0.00f,0.00f, 300, 0.010f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -0.0f, 10268.2f, 251.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_DRIVING_FULLGRANDSTAND \
+ { 26, 8.3f, 1.000f, -1100, -1100, -400, 3.01f, 1.37f, 1.28f, -900, 0.090f, 0.00f,0.00f,0.00f, -1700, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_DRIVING_EMPTYGRANDSTAND \
+ { 26, 8.3f, 1.000f, -700, 0, -200, 4.62f, 1.75f, 1.40f, -1363, 0.090f, 0.00f,0.00f,0.00f, -1900, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 10420.2f, 250.0f, 0.00f, 0x1f }
+#define EAX30_PRESET_DRIVING_TUNNEL \
+ { 26, 3.1f, 0.810f, -900, -800, -100, 3.42f, 0.94f, 1.31f, -300, 0.051f, 0.00f,0.00f,0.00f, -500, 0.047f, 0.00f,0.00f,0.00f, 0.214f, 0.050f, 0.250f, 0.000f, -0.0f, 5000.0f, 155.3f, 0.00f, 0x20 }
+
+// CITY PRESETS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_CITY_STREETS \
+ { 26, 3.0f, 0.780f, -1100, -300, -100, 1.79f, 1.12f, 0.91f, -1700, 0.046f, 0.00f,0.00f,0.00f, -2800, 0.028f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_CITY_SUBWAY \
+ { 26, 3.0f, 0.740f, -1100, -300, -100, 3.01f, 1.23f, 0.91f, -700, 0.046f, 0.00f,0.00f,0.00f, -1000, 0.028f, 0.00f,0.00f,0.00f, 0.125f, 0.210f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_CITY_MUSEUM \
+ { 26, 80.3f, 0.820f, -1100, -1500, -1500, 3.28f, 1.40f, 0.57f, -1600, 0.039f, 0.00f,0.00f,-0.00f, -600, 0.034f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 }
+#define EAX30_PRESET_CITY_LIBRARY \
+ { 26, 80.3f, 0.820f, -1100, -1100, -2100, 2.76f, 0.89f, 0.41f, -1100, 0.029f, 0.00f,0.00f,-0.00f, -500, 0.020f, 0.00f,0.00f,0.00f, 0.130f, 0.170f, 0.250f, 0.000f, -0.0f, 2854.4f, 107.5f, 0.00f, 0x0 }
+#define EAX30_PRESET_CITY_UNDERPASS \
+ { 26, 3.0f, 0.820f, -1500, -700, -100, 3.57f, 1.12f, 0.91f, -1500, 0.059f, 0.00f,0.00f,0.00f, -1100, 0.037f, 0.00f,0.00f,0.00f, 0.250f, 0.140f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+#define EAX30_PRESET_CITY_ABANDONED \
+ { 26, 3.0f, 0.690f, -1100, -200, -100, 3.28f, 1.17f, 0.91f, -1400, 0.044f, 0.00f,0.00f,0.00f, -2400, 0.024f, 0.00f,0.00f,0.00f, 0.250f, 0.200f, 0.250f, 0.000f, -0.0f, 5000.0f, 250.0f, 0.00f, 0x20 }
+
+// MISC ROOMS
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+#define EAX30_PRESET_DUSTYROOM \
+ { 26, 1.8f, 0.560f, -1100, -200, -300, 1.79f, 0.38f, 0.21f, -600, 0.002f, 0.00f,0.00f,0.00f, 200, 0.006f, 0.00f,0.00f,0.00f, 0.202f, 0.050f, 0.250f, 0.000f, -3.0f, 13046.0f, 163.3f, 0.00f, 0x20 }
+#define EAX30_PRESET_CHAPEL \
+ { 26, 19.6f, 0.840f, -1000, -500, 0, 4.62f, 0.64f, 1.23f, -700, 0.032f, 0.00f,0.00f,0.00f, -800, 0.049f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.110f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x3f }
+#define EAX30_PRESET_SMALLWATERROOM \
+ { 26, 36.2f, 0.700f, -1200, -698, 0, 1.51f, 1.25f, 1.14f, -100, 0.020f, 0.00f,0.00f,0.00f, 200, 0.030f, 0.00f,0.00f,0.00f, 0.179f, 0.150f, 0.895f, 0.190f, -5.0f, 5000.0f, 250.0f, 0.00f, 0x0 }
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Effect Scenarios enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ EAX30_SCENARIO_CASTLE = 0,
+ EAX30_SCENARIO_FACTORY,
+ EAX30_SCENARIO_ICEPALACE,
+ EAX30_SCENARIO_SPACESTATION,
+ EAX30_SCENARIO_WOODGALLEON,
+ EAX30_SCENARIO_SPORTS,
+ EAX30_SCENARIO_PREFAB,
+ EAX30_SCENARIO_DOMESNPIPES,
+ EAX30_SCENARIO_OUTDOORS,
+ EAX30_SCENARIO_MOOD,
+ EAX30_SCENARIO_DRIVING,
+ EAX30_SCENARIO_CITY,
+ EAX30_SCENARIO_MISC,
+ EAX30_SCENARIO_ORIGINAL
+}
+EAX30_SCENARIO;
+
+//////////////////////////////////////////////////////
+// Number of Effect Scenarios //
+//////////////////////////////////////////////////////
+
+#define EAX30_NUM_SCENARIOS 14
+
+//////////////////////////////////////////////////////
+// Number of Effect Scenarios with standardised //
+// locations //
+//////////////////////////////////////////////////////
+
+#define EAX30_NUM_STANDARD_SCENARIOS 5
+
+//////////////////////////////////////////////////////
+// Array of scenario names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_SCENARIO_NAMES[];
+
+//////////////////////////////////////////////////////
+// Standardised Locations enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ EAX30_LOCATION_HALL = 0,
+ EAX30_LOCATION_LARGEROOM,
+ EAX30_LOCATION_MEDIUMROOM,
+ EAX30_LOCATION_SMALLROOM,
+ EAX30_LOCATION_CUPBOARD,
+ EAX30_LOCATION_ALCOVE,
+ EAX30_LOCATION_LONGPASSAGE,
+ EAX30_LOCATION_SHORTPASSAGE,
+ EAX30_LOCATION_COURTYARD
+}
+EAX30_LOCATION;
+
+//////////////////////////////////////////////////////
+// Number of Standardised Locations //
+//////////////////////////////////////////////////////
+
+#define EAX30_NUM_LOCATIONS 9
+
+//////////////////////////////////////////////////////
+// Array of standardised location names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_LOCATION_NAMES[];
+
+//////////////////////////////////////////////////////
+// Number of effects in each scenario //
+//////////////////////////////////////////////////////
+
+#define EAX30_NUM_ORIGINAL_PRESETS 26
+#define EAX30_NUM_CASTLE_PRESETS EAX30_NUM_LOCATIONS
+#define EAX30_NUM_FACTORY_PRESETS EAX30_NUM_LOCATIONS
+#define EAX30_NUM_ICEPALACE_PRESETS EAX30_NUM_LOCATIONS
+#define EAX30_NUM_SPACESTATION_PRESETS EAX30_NUM_LOCATIONS
+#define EAX30_NUM_WOODGALLEON_PRESETS EAX30_NUM_LOCATIONS
+#define EAX30_NUM_SPORTS_PRESETS 7
+#define EAX30_NUM_PREFAB_PRESETS 5
+#define EAX30_NUM_DOMESNPIPES_PRESETS 6
+#define EAX30_NUM_OUTDOORS_PRESETS 5
+#define EAX30_NUM_MOOD_PRESETS 3
+#define EAX30_NUM_DRIVING_PRESETS 8
+#define EAX30_NUM_CITY_PRESETS 6
+#define EAX30_NUM_MISC_PRESETS 3
+
+//////////////////////////////////////////////////////
+// Standardised Location effects can be accessed //
+// from a matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_STANDARD_PRESETS[EAX30_NUM_STANDARD_SCENARIOS][EAX30_NUM_LOCATIONS];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Original Preset effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ ORIGINAL_GENERIC = 0,
+ ORIGINAL_PADDEDCELL,
+ ORIGINAL_ROOM,
+ ORIGINAL_BATHROOM,
+ ORIGINAL_LIVINGROOM,
+ ORIGINAL_STONEROOM,
+ ORIGINAL_AUDITORIUM,
+ ORIGINAL_CONCERTHALL,
+ ORIGINAL_CAVE,
+ ORIGINAL_ARENA,
+ ORIGINAL_HANGAR,
+ ORIGINAL_CARPETTEDHALLWAY,
+ ORIGINAL_HALLWAY,
+ ORIGINAL_STONECORRIDOR,
+ ORIGINAL_ALLEY,
+ ORIGINAL_FOREST,
+ ORIGINAL_CITY,
+ ORIGINAL_MOUNTAINS,
+ ORIGINAL_QUARRY,
+ ORIGINAL_PLAIN,
+ ORIGINAL_PARKINGLOT,
+ ORIGINAL_SEWERPIPE,
+ ORIGINAL_UNDERWATER,
+ ORIGINAL_DRUGGED,
+ ORIGINAL_DIZZY,
+ ORIGINAL_PSYCHOTIC
+}
+EAX30_ORIGINAL_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of original environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_ORIGINAL_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Original effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_ORIGINAL_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Sports scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ SPORT_EMPTYSTADIUM=0,
+ SPORT_FULLSTADIUM,
+ SPORT_STADIUMTANNOY,
+ SPORT_SQUASHCOURT,
+ SPORT_SMALLSWIMMINGPOOL,
+ SPORT_LARGESWIMMINGPOOL,
+ SPORT_GYMNASIUM
+}
+EAX30_SPORTS_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of sport environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_SPORTS_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Sports effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_SPORTS_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Prefab scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ PREFAB_WORKSHOP,
+ PREFAB_SCHOOLROOM,
+ PREFAB_PRACTISEROOM,
+ PREFAB_OUTHOUSE,
+ PREFAB_CARAVAN
+}
+EAX30_PREFAB_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of prefab environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_PREFAB_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Prefab effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_PREFAB_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Domes & Pipes effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ DOME_TOMB,
+ DOME_SAINTPAULS,
+ PIPE_SMALL,
+ PIPE_LONGTHIN,
+ PIPE_LARGE,
+ PIPE_RESONANT
+}
+EAX30_DOMESNPIPES_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of Domes & Pipes environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_DOMESNPIPES_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Domes & Pipes effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_DOMESNPIPES_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Outdoors scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ OUTDOORS_BACKYARD,
+ OUTDOORS_ROLLINGPLAINS,
+ OUTDOORS_DEEPCANYON,
+ OUTDOORS_CREEK,
+ OUTDOORS_VALLEY
+}
+EAX30_OUTDOORS_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of Outdoors environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_OUTDOORS_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Outdoors effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_OUTDOORS_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Mood scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ MOOD_HEAVEN,
+ MOOD_HELL,
+ MOOD_MEMORY
+}
+EAX30_MOOD_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of Mood environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_MOOD_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Mood effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_MOOD_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Driving scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ DRIVING_COMMENTATOR,
+ DRIVING_PITGARAGE,
+ DRIVING_INCAR_RACER,
+ DRIVING_INCAR_SPORTS,
+ DRIVING_INCAR_LUXURY,
+ DRIVING_FULLGRANDSTAND,
+ DRIVING_EMPTYGRANDSTAND,
+ DRIVING_TUNNEL
+}
+EAX30_DRIVING_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of driving environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_DRIVING_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Driving effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_DRIVING_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// City scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ CITY_STREETS,
+ CITY_SUBWAY,
+ CITY_MUSEUM,
+ CITY_LIBRARY,
+ CITY_UNDERPASS,
+ CITY_ABANDONED
+}
+EAX30_CITY_PRESET_ENUMS;
+
+//////////////////////////////////////////////////////
+// Array of City environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_CITY_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// City effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_CITY_PRESETS[];
+
+/********************************************************************************************************/
+
+//////////////////////////////////////////////////////
+// Misc scenario effects enumerated //
+//////////////////////////////////////////////////////
+
+typedef enum
+{
+ DUSTYROOM,
+ CHAPEL,
+ SMALLWATERROOM
+}
+EAX30_MISC_PRESET_ENUMS;
+
+
+//////////////////////////////////////////////////////
+// Array of Misc environment names //
+//////////////////////////////////////////////////////
+
+extern const char* EAX30_MISC_PRESET_NAMES[];
+
+//////////////////////////////////////////////////////
+// Misc effects matrix //
+//////////////////////////////////////////////////////
+
+extern EAXLISTENERPROPERTIES EAX30_MISC_PRESETS[];
+
+
+/***********************************************************************************************\
+*
+* Material transmission presets
+*
+* Three values in this order :-
+*
+* 1. Occlusion (or Obstruction)
+* 2. Occlusion LF Ratio (or Obstruction LF Ratio)
+* 3. Occlusion Room Ratio
+*
+************************************************************************************************/
+
+
+// Single window material preset
+#define EAX_MATERIAL_SINGLEWINDOW (-2800)
+#define EAX_MATERIAL_SINGLEWINDOWLF 0.71f
+#define EAX_MATERIAL_SINGLEWINDOWROOMRATIO 0.43f
+
+// Double window material preset
+#define EAX_MATERIAL_DOUBLEWINDOW (-5000)
+#define EAX_MATERIAL_DOUBLEWINDOWLF 0.40f
+#define EAX_MATERIAL_DOUBLEWINDOWROOMRATIO 0.24f
+
+// Thin door material preset
+#define EAX_MATERIAL_THINDOOR (-1800)
+#define EAX_MATERIAL_THINDOORLF 0.66f
+#define EAX_MATERIAL_THINDOORROOMRATIO 0.66f
+
+// Thick door material preset
+#define EAX_MATERIAL_THICKDOOR (-4400)
+#define EAX_MATERIAL_THICKDOORLF 0.64f
+#define EAX_MATERIAL_THICKDOORROOMRATIO 0.27f
+
+// Wood wall material preset
+#define EAX_MATERIAL_WOODWALL (-4000)
+#define EAX_MATERIAL_WOODWALLLF 0.50f
+#define EAX_MATERIAL_WOODWALLROOMRATIO 0.30f
+
+// Brick wall material preset
+#define EAX_MATERIAL_BRICKWALL (-5000)
+#define EAX_MATERIAL_BRICKWALLLF 0.60f
+#define EAX_MATERIAL_BRICKWALLROOMRATIO 0.24f
+
+// Stone wall material preset
+#define EAX_MATERIAL_STONEWALL (-6000)
+#define EAX_MATERIAL_STONEWALLLF 0.68f
+#define EAX_MATERIAL_STONEWALLROOMRATIO 0.20f
+
+// Curtain material preset
+#define EAX_MATERIAL_CURTAIN (-1200)
+#define EAX_MATERIAL_CURTAINLF 0.15f
+#define EAX_MATERIAL_CURTAINROOMRATIO 1.00f
+
+
+#endif // EAXUTIL_INCLUDED
diff --git a/src/audio/eax/eax.h b/src/audio/eax/eax.h
new file mode 100644
index 00000000..b2210936
--- /dev/null
+++ b/src/audio/eax/eax.h
@@ -0,0 +1,536 @@
+/*******************************************************************\
+* *
+* EAX.H - Environmental Audio Extensions version 3.0 *
+* for OpenAL and DirectSound3D *
+* *
+********************************************************************/
+
+#ifndef EAX_H_INCLUDED
+#define EAX_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifndef AUDIO_OAL
+ #include <dsound.h>
+
+ /*
+ * EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
+ */
+ DEFINE_GUID(CLSID_EAXDirectSound,
+ 0x4ff53b81,
+ 0x1ce0,
+ 0x11d3,
+ 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
+
+ /*
+ * EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
+ */
+ DEFINE_GUID(CLSID_EAXDirectSound8,
+ 0xca503b60,
+ 0xb176,
+ 0x11d4,
+ 0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
+
+
+
+#ifdef DIRECTSOUND_VERSION
+#if DIRECTSOUND_VERSION >= 0x0800
+ __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
+ typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*);
+#endif
+#endif
+
+ __declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
+ typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
+
+ __declspec(dllimport) void CDECL GetCurrentVersion(LPDWORD major, LPDWORD minor);
+ typedef void (CDECL *LPGETCURRENTVERSION)(LPDWORD major, LPDWORD minor);
+
+
+#else // AUDIO_OAL
+ #include <AL/al.h>
+ #include <string.h>
+
+ #ifndef GUID_DEFINED
+ #define GUID_DEFINED
+ typedef struct _GUID
+ {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+ } GUID;
+ #endif // !GUID_DEFINED
+
+ #ifndef DEFINE_GUID
+ #ifndef INITGUID
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ extern const GUID /*FAR*/ name
+ #else
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+ #endif // INITGUID
+ #endif // DEFINE_GUID
+
+
+ /*
+ * EAX OpenAL Extension
+ */
+ typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
+ typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
+#endif
+
+#pragma pack(push, 4)
+
+/*
+ * EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87}
+ */
+DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties,
+ 0xa8fa6882,
+ 0xb476,
+ 0x11d3,
+ 0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
+
+// For compatibility with future EAX versions:
+#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties
+
+typedef enum
+{
+ DSPROPERTY_EAXLISTENER_NONE,
+ DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
+ DSPROPERTY_EAXLISTENER_ENVIRONMENT,
+ DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
+ DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
+ DSPROPERTY_EAXLISTENER_ROOM,
+ DSPROPERTY_EAXLISTENER_ROOMHF,
+ DSPROPERTY_EAXLISTENER_ROOMLF,
+ DSPROPERTY_EAXLISTENER_DECAYTIME,
+ DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
+ DSPROPERTY_EAXLISTENER_DECAYLFRATIO,
+ DSPROPERTY_EAXLISTENER_REFLECTIONS,
+ DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
+ DSPROPERTY_EAXLISTENER_REFLECTIONSPAN,
+ DSPROPERTY_EAXLISTENER_REVERB,
+ DSPROPERTY_EAXLISTENER_REVERBDELAY,
+ DSPROPERTY_EAXLISTENER_REVERBPAN,
+ DSPROPERTY_EAXLISTENER_ECHOTIME,
+ DSPROPERTY_EAXLISTENER_ECHODEPTH,
+ DSPROPERTY_EAXLISTENER_MODULATIONTIME,
+ DSPROPERTY_EAXLISTENER_MODULATIONDEPTH,
+ DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
+ DSPROPERTY_EAXLISTENER_HFREFERENCE,
+ DSPROPERTY_EAXLISTENER_LFREFERENCE,
+ DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
+ DSPROPERTY_EAXLISTENER_FLAGS
+} DSPROPERTY_EAX_LISTENERPROPERTY;
+
+// OR these flags with property id
+#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
+#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
+#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \
+ DSPROPERTY_EAXLISTENER_IMMEDIATE)
+
+typedef struct _EAXVECTOR {
+ float x;
+ float y;
+ float z;
+} EAXVECTOR;
+
+// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
+// - all levels are hundredths of decibels
+// - all times and delays are in seconds
+//
+// NOTE: This structure may change in future EAX versions.
+// It is recommended to initialize fields by name:
+// myListener.lRoom = -1000;
+// myListener.lRoomHF = -100;
+// ...
+// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
+// instead of:
+// myListener = { -1000, -100, ... , 0x00000009 };
+// If you want to save and load presets in binary form, you
+// should define your own structure to insure future compatibility.
+//
+typedef struct _EAXLISTENERPROPERTIES
+{
+ unsigned long ulEnvironment; // sets all listener properties
+ float flEnvironmentSize; // environment size in meters
+ float flEnvironmentDiffusion; // environment diffusion
+ long lRoom; // room effect level (at mid frequencies)
+ long lRoomHF; // relative room effect level at high frequencies
+ long lRoomLF; // relative room effect level at low frequencies
+ float flDecayTime; // reverberation decay time at mid frequencies
+ float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio
+ float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio
+ long lReflections; // early reflections level relative to room effect
+ float flReflectionsDelay; // initial reflection delay time
+ EAXVECTOR vReflectionsPan; // early reflections panning vector
+ long lReverb; // late reverberation level relative to room effect
+ float flReverbDelay; // late reverberation delay time relative to initial reflection
+ EAXVECTOR vReverbPan; // late reverberation panning vector
+ float flEchoTime; // echo time
+ float flEchoDepth; // echo depth
+ float flModulationTime; // modulation time
+ float flModulationDepth; // modulation depth
+ float flAirAbsorptionHF; // change in level per meter at high frequencies
+ float flHFReference; // reference high frequency
+ float flLFReference; // reference low frequency
+ float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
+ unsigned long ulFlags; // modifies the behavior of properties
+} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES;
+
+// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
+enum
+{
+ EAX_ENVIRONMENT_GENERIC,
+ EAX_ENVIRONMENT_PADDEDCELL,
+ EAX_ENVIRONMENT_ROOM,
+ EAX_ENVIRONMENT_BATHROOM,
+ EAX_ENVIRONMENT_LIVINGROOM,
+ EAX_ENVIRONMENT_STONEROOM,
+ EAX_ENVIRONMENT_AUDITORIUM,
+ EAX_ENVIRONMENT_CONCERTHALL,
+ EAX_ENVIRONMENT_CAVE,
+ EAX_ENVIRONMENT_ARENA,
+ EAX_ENVIRONMENT_HANGAR,
+ EAX_ENVIRONMENT_CARPETEDHALLWAY,
+ EAX_ENVIRONMENT_HALLWAY,
+ EAX_ENVIRONMENT_STONECORRIDOR,
+ EAX_ENVIRONMENT_ALLEY,
+ EAX_ENVIRONMENT_FOREST,
+ EAX_ENVIRONMENT_CITY,
+ EAX_ENVIRONMENT_MOUNTAINS,
+ EAX_ENVIRONMENT_QUARRY,
+ EAX_ENVIRONMENT_PLAIN,
+ EAX_ENVIRONMENT_PARKINGLOT,
+ EAX_ENVIRONMENT_SEWERPIPE,
+ EAX_ENVIRONMENT_UNDERWATER,
+ EAX_ENVIRONMENT_DRUGGED,
+ EAX_ENVIRONMENT_DIZZY,
+ EAX_ENVIRONMENT_PSYCHOTIC,
+
+ EAX_ENVIRONMENT_UNDEFINED,
+
+ EAX_ENVIRONMENT_COUNT
+};
+
+// Used by DSPROPERTY_EAXLISTENER_FLAGS
+//
+// Note: The number and order of flags may change in future EAX versions.
+// It is recommended to use the flag defines as follows:
+// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
+// instead of:
+// myFlags = 0x00000009;
+//
+// These flags determine what properties are affected by environment size.
+#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
+#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
+#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
+#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
+#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
+#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time
+#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time
+
+// This flag limits high-frequency decay time according to air absorption.
+#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
+
+#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use
+
+// Property ranges and defaults:
+
+#define EAXLISTENER_MINENVIRONMENT 0
+#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
+#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
+
+#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
+#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
+#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
+
+#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
+#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
+#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
+
+#define EAXLISTENER_MINROOM (-10000)
+#define EAXLISTENER_MAXROOM 0
+#define EAXLISTENER_DEFAULTROOM (-1000)
+
+#define EAXLISTENER_MINROOMHF (-10000)
+#define EAXLISTENER_MAXROOMHF 0
+#define EAXLISTENER_DEFAULTROOMHF (-100)
+
+#define EAXLISTENER_MINROOMLF (-10000)
+#define EAXLISTENER_MAXROOMLF 0
+#define EAXLISTENER_DEFAULTROOMLF 0
+
+#define EAXLISTENER_MINDECAYTIME 0.1f
+#define EAXLISTENER_MAXDECAYTIME 20.0f
+#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
+
+#define EAXLISTENER_MINDECAYHFRATIO 0.1f
+#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
+#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
+
+#define EAXLISTENER_MINDECAYLFRATIO 0.1f
+#define EAXLISTENER_MAXDECAYLFRATIO 2.0f
+#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f
+
+#define EAXLISTENER_MINREFLECTIONS (-10000)
+#define EAXLISTENER_MAXREFLECTIONS 1000
+#define EAXLISTENER_DEFAULTREFLECTIONS (-2602)
+
+#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
+#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
+#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
+
+#define EAXLISTENER_MINREVERB (-10000)
+#define EAXLISTENER_MAXREVERB 2000
+#define EAXLISTENER_DEFAULTREVERB 200
+
+#define EAXLISTENER_MINREVERBDELAY 0.0f
+#define EAXLISTENER_MAXREVERBDELAY 0.1f
+#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
+
+#define EAXLISTENER_MINECHOTIME 0.075f
+#define EAXLISTENER_MAXECHOTIME 0.25f
+#define EAXLISTENER_DEFAULTECHOTIME 0.25f
+
+#define EAXLISTENER_MINECHODEPTH 0.0f
+#define EAXLISTENER_MAXECHODEPTH 1.0f
+#define EAXLISTENER_DEFAULTECHODEPTH 0.0f
+
+#define EAXLISTENER_MINMODULATIONTIME 0.04f
+#define EAXLISTENER_MAXMODULATIONTIME 4.0f
+#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f
+
+#define EAXLISTENER_MINMODULATIONDEPTH 0.0f
+#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f
+#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f
+
+#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f)
+#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
+#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
+
+#define EAXLISTENER_MINHFREFERENCE 1000.0f
+#define EAXLISTENER_MAXHFREFERENCE 20000.0f
+#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f
+
+#define EAXLISTENER_MINLFREFERENCE 20.0f
+#define EAXLISTENER_MAXLFREFERENCE 1000.0f
+#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f
+
+#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
+#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
+#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
+
+#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \
+ EAXLISTENERFLAGS_REFLECTIONSSCALE | \
+ EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
+ EAXLISTENERFLAGS_REVERBSCALE | \
+ EAXLISTENERFLAGS_REVERBDELAYSCALE | \
+ EAXLISTENERFLAGS_DECAYHFLIMIT)
+
+
+
+/*
+* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87}
+*/
+DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties,
+ 0xa8fa6881,
+ 0xb476,
+ 0x11d3,
+ 0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
+
+// For compatibility with future EAX versions:
+#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties
+#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties
+
+typedef enum
+{
+ DSPROPERTY_EAXBUFFER_NONE,
+ DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
+ DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS,
+ DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS,
+ DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS,
+ DSPROPERTY_EAXBUFFER_DIRECT,
+ DSPROPERTY_EAXBUFFER_DIRECTHF,
+ DSPROPERTY_EAXBUFFER_ROOM,
+ DSPROPERTY_EAXBUFFER_ROOMHF,
+ DSPROPERTY_EAXBUFFER_OBSTRUCTION,
+ DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
+ DSPROPERTY_EAXBUFFER_OCCLUSION,
+ DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
+ DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
+ DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO,
+ DSPROPERTY_EAXBUFFER_EXCLUSION,
+ DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO,
+ DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
+ DSPROPERTY_EAXBUFFER_DOPPLERFACTOR,
+ DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR,
+ DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
+ DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
+ DSPROPERTY_EAXBUFFER_FLAGS
+} DSPROPERTY_EAX_BUFFERPROPERTY;
+
+// OR these flags with property id
+#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
+#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
+#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \
+ DSPROPERTY_EAXBUFFER_IMMEDIATE)
+
+// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
+// - all levels are hundredths of decibels
+// - all delays are in seconds
+//
+// NOTE: This structure may change in future EAX versions.
+// It is recommended to initialize fields by name:
+// myBuffer.lDirect = 0;
+// myBuffer.lDirectHF = -200;
+// ...
+// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
+// instead of:
+// myBuffer = { 0, -200, ... , 0x00000003 };
+//
+typedef struct _EAXBUFFERPROPERTIES
+{
+ long lDirect; // direct path level (at low and mid frequencies)
+ long lDirectHF; // relative direct path level at high frequencies
+ long lRoom; // room effect level (at low and mid frequencies)
+ long lRoomHF; // relative room effect level at high frequencies
+ long lObstruction; // main obstruction control (attenuation at high frequencies)
+ float flObstructionLFRatio; // obstruction low-frequency level re. main control
+ long lOcclusion; // main occlusion control (attenuation at high frequencies)
+ float flOcclusionLFRatio; // occlusion low-frequency level re. main control
+ float flOcclusionRoomRatio; // relative occlusion control for room effect
+ float flOcclusionDirectRatio; // relative occlusion control for direct path
+ long lExclusion; // main exlusion control (attenuation at high frequencies)
+ float flExclusionLFRatio; // exclusion low-frequency level re. main control
+ long lOutsideVolumeHF; // outside sound cone level at high frequencies
+ float flDopplerFactor; // like DS3D flDopplerFactor but per source
+ float flRolloffFactor; // like DS3D flRolloffFactor but per source
+ float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
+ float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
+ unsigned long ulFlags; // modifies the behavior of properties
+} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES;
+
+// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION,
+typedef struct _EAXOBSTRUCTIONPROPERTIES
+{
+ long lObstruction;
+ float flObstructionLFRatio;
+} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES;
+
+// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION
+typedef struct _EAXOCCLUSIONPROPERTIES
+{
+ long lOcclusion;
+ float flOcclusionLFRatio;
+ float flOcclusionRoomRatio;
+ float flOcclusionDirectRatio;
+} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES;
+
+// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION
+typedef struct _EAXEXCLUSIONPROPERTIES
+{
+ long lExclusion;
+ float flExclusionLFRatio;
+} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES;
+
+// Used by DSPROPERTY_EAXBUFFER_FLAGS
+// TRUE: value is computed automatically - property is an offset
+// FALSE: value is used directly
+//
+// Note: The number and order of flags may change in future EAX versions.
+// To insure future compatibility, use flag defines as follows:
+// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
+// instead of:
+// myFlags = 0x00000003;
+//
+#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
+#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
+#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
+
+#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
+
+// Property ranges and defaults:
+
+#define EAXBUFFER_MINDIRECT (-10000)
+#define EAXBUFFER_MAXDIRECT 1000
+#define EAXBUFFER_DEFAULTDIRECT 0
+
+#define EAXBUFFER_MINDIRECTHF (-10000)
+#define EAXBUFFER_MAXDIRECTHF 0
+#define EAXBUFFER_DEFAULTDIRECTHF 0
+
+#define EAXBUFFER_MINROOM (-10000)
+#define EAXBUFFER_MAXROOM 1000
+#define EAXBUFFER_DEFAULTROOM 0
+
+#define EAXBUFFER_MINROOMHF (-10000)
+#define EAXBUFFER_MAXROOMHF 0
+#define EAXBUFFER_DEFAULTROOMHF 0
+
+#define EAXBUFFER_MINOBSTRUCTION (-10000)
+#define EAXBUFFER_MAXOBSTRUCTION 0
+#define EAXBUFFER_DEFAULTOBSTRUCTION 0
+
+#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
+#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
+#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
+
+#define EAXBUFFER_MINOCCLUSION (-10000)
+#define EAXBUFFER_MAXOCCLUSION 0
+#define EAXBUFFER_DEFAULTOCCLUSION 0
+
+#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
+#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
+#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
+
+#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
+#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
+#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f
+
+#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f
+#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f
+#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f
+
+#define EAXBUFFER_MINEXCLUSION (-10000)
+#define EAXBUFFER_MAXEXCLUSION 0
+#define EAXBUFFER_DEFAULTEXCLUSION 0
+
+#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f
+#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f
+#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f
+
+#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000)
+#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
+#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
+
+#define EAXBUFFER_MINDOPPLERFACTOR 0.0f
+#define EAXBUFFER_MAXDOPPLERFACTOR 10.f
+#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f
+
+#define EAXBUFFER_MINROLLOFFFACTOR 0.0f
+#define EAXBUFFER_MAXROLLOFFFACTOR 10.f
+#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f
+
+#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
+#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
+#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
+
+#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
+#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
+#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
+
+#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \
+ EAXBUFFERFLAGS_ROOMAUTO | \
+ EAXBUFFERFLAGS_ROOMHFAUTO )
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index 34080514..eeaaafb0 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -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
diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp
index ee9ec17e..86b4caf1 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -105,6 +105,10 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
void
CRoadBlocks::GenerateRoadBlocks(void)
{
+#ifdef SQUEEZE_PERFORMANCE
+ if (FindPlayerPed()->m_pWanted->m_RoadblockDensity == 0)
+ return;
+#endif
CMatrix offsetMatrix;
uint32 frame = CTimer::GetFrameCounter() & 0xF;
int16 nRoadblockNode = (int16)(NUMROADBLOCKS * frame) / 16;
diff --git a/src/core/Accident.cpp b/src/core/Accident.cpp
index 1fd6c123..c8611323 100644
--- a/src/core/Accident.cpp
+++ b/src/core/Accident.cpp
@@ -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);
diff --git a/src/core/Accident.h b/src/core/Accident.h
index 949d5fb9..568e1149 100644
--- a/src/core/Accident.h
+++ b/src/core/Accident.h
@@ -1,5 +1,4 @@
#pragma once
-#include "common.h"
#include "config.h"
class CPed;
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index 99be816f..6522ff1c 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+#include "VuVector.h"
#include "main.h"
#include "Lists.h"
#include "Game.h"
@@ -21,6 +22,346 @@
#include "Lines.h"
#include "Collision.h"
+
+// TODO: where do these go?
+
+#ifdef VU_COLLISION
+
+struct VuTriangle
+{
+ // Compressed int16 but unpacked
+#ifdef GTA_PS2
+ uint128 v0;
+ uint128 v1;
+ uint128 v2;
+ uint128 plane;
+#else
+ int32 v0[4];
+ int32 v1[4];
+ int32 v2[4];
+ int32 plane[4];
+#endif
+};
+
+#ifndef GTA_PS2
+static int16 vi01;
+static CVuVector vf01;
+static CVuVector vf02;
+static CVuVector vf03;
+
+CVuVector
+DistanceBetweenSphereAndLine(const CVuVector &center, const CVuVector &p0, const CVuVector &line)
+{
+ // center VF12
+ // p0 VF14
+ // line VF15
+ CVuVector ret; // VF16
+ CVuVector p1 = p0+line;
+ CVuVector dist0 = center - p0; // VF20
+ CVuVector dist1 = center - p1; // VF25
+ float lenSq = line.MagnitudeSqr(); // VF21
+ float distSq0 = dist0.MagnitudeSqr(); // VF22
+ float distSq1 = dist1.MagnitudeSqr();
+ float dot = DotProduct(dist0, line); // VF23
+ if(dot < 0.0f){
+ // not above line, closest to p0
+ ret = p0;
+ ret.w = distSq0;
+ return ret;
+ }
+ float t = dot/lenSq; // param of nearest point on infinite line
+ if(t > 1.0f){
+ // not above line, closest to p1
+ ret = p1;
+ ret.w = distSq1;
+ return ret;
+ }
+ // closest to line
+ ret = p0 + line*t;
+ ret.w = (ret - center).MagnitudeSqr();
+ return ret;
+}
+inline int SignFlags(const CVector &v)
+{
+ int f = 0;
+ if(v.x < 0.0f) f |= 1;
+ if(v.y < 0.0f) f |= 2;
+ if(v.z < 0.0f) f |= 4;
+ return f;
+}
+#endif
+
+extern "C" void
+LineToTriangleCollision(const CVuVector &p0, const CVuVector &p1,
+ const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
+ const CVuVector &plane)
+{
+#ifdef GTA_PS2
+ __asm__ volatile (
+ ".set noreorder\n"
+ "lqc2 vf12, 0x0(%0)\n"
+ "lqc2 vf13, 0x0(%1)\n"
+ "lqc2 vf14, 0x0(%2)\n"
+ "lqc2 vf15, 0x0(%3)\n"
+ "lqc2 vf16, 0x0(%4)\n"
+ "lqc2 vf17, 0x0(%5)\n"
+ "vcallms Vu0LineToTriangleCollisionStart\n"
+ ".set reorder\n"
+ :
+ : "r" (&p0), "r" (&p1), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
+ );
+#else
+ float dot0 = DotProduct(plane, p0);
+ float dot1 = DotProduct(plane, p1);
+ float dist0 = plane.w - dot0;
+ float dist1 = plane.w - dot1;
+
+ // if points are on the same side, no collision
+ if(dist0 * dist1 > 0.0f){
+ vi01 = 0;
+ return;
+ }
+
+ CVuVector diff = p1 - p0;
+ float t = dist0/(dot1 - dot0);
+ CVuVector p = p0 + diff*t;
+ p.w = 0.0f;
+ vf01 = p;
+ vf03.x = t;
+
+ // Check if point is inside
+ CVector cross1 = CrossProduct(p-v0, v1-v0);
+ CVector cross2 = CrossProduct(p-v1, v2-v1);
+ CVector cross3 = CrossProduct(p-v2, v0-v2);
+ // Only check relevant directions
+ int flagmask = 0;
+ if(Abs(plane.x) > 0.5f) flagmask |= 1;
+ if(Abs(plane.y) > 0.5f) flagmask |= 2;
+ if(Abs(plane.z) > 0.5f) flagmask |= 4;
+ int flags1 = SignFlags(cross1) & flagmask;
+ int flags2 = SignFlags(cross2) & flagmask;
+ int flags3 = SignFlags(cross3) & flagmask;
+ // inside if on the same side of all edges
+ if(flags1 != flags2 || flags1 != flags3){
+ vi01 = 0;
+ return;
+ }
+ vi01 = 1;
+ vf02 = plane;
+ return;
+#endif
+}
+
+extern "C" void
+LineToTriangleCollisionCompressed(const CVuVector &p0, const CVuVector &p1, VuTriangle &tri)
+{
+#ifdef GTA_PS2
+ __asm__ volatile (
+ ".set noreorder\n"
+ "lqc2 vf12, 0x0(%0)\n"
+ "lqc2 vf13, 0x0(%1)\n"
+ "lqc2 vf14, 0x0(%2)\n"
+ "lqc2 vf15, 0x10(%2)\n"
+ "lqc2 vf16, 0x20(%2)\n"
+ "lqc2 vf17, 0x30(%2)\n"
+ "vcallms Vu0LineToTriangleCollisionCompressedStart\n"
+ ".set reorder\n"
+ :
+ : "r" (&p0), "r" (&p1), "r" (&tri)
+ );
+#else
+ CVuVector v0, v1, v2, plane;
+ v0.x = tri.v0[0]/128.0f;
+ v0.y = tri.v0[1]/128.0f;
+ v0.z = tri.v0[2]/128.0f;
+ v0.w = tri.v0[3]/128.0f;
+ v1.x = tri.v1[0]/128.0f;
+ v1.y = tri.v1[1]/128.0f;
+ v1.z = tri.v1[2]/128.0f;
+ v1.w = tri.v1[3]/128.0f;
+ v2.x = tri.v2[0]/128.0f;
+ v2.y = tri.v2[1]/128.0f;
+ v2.z = tri.v2[2]/128.0f;
+ v2.w = tri.v2[3]/128.0f;
+ plane.x = tri.plane[0]/4096.0f;
+ plane.y = tri.plane[1]/4096.0f;
+ plane.z = tri.plane[2]/4096.0f;
+ plane.w = tri.plane[3]/128.0f;
+ LineToTriangleCollision(p0, p1, v0, v1, v2, plane);
+#endif
+}
+
+extern "C" void
+SphereToTriangleCollision(const CVuVector &sph,
+ const CVuVector &v0, const CVuVector &v1, const CVuVector &v2,
+ const CVuVector &plane)
+{
+#ifdef GTA_PS2
+ __asm__ volatile (
+ ".set noreorder\n"
+ "lqc2 vf12, 0x0(%0)\n"
+ "lqc2 vf14, 0x0(%1)\n"
+ "lqc2 vf15, 0x0(%2)\n"
+ "lqc2 vf16, 0x0(%3)\n"
+ "lqc2 vf17, 0x0(%4)\n"
+ "vcallms Vu0SphereToTriangleCollisionStart\n"
+ ".set reorder\n"
+ :
+ : "r" (&sph), "r" (&v0), "r" (&v1), "r" (&v2), "r" (&plane)
+ );
+#else
+ float planedist = DotProduct(plane, sph) - plane.w; // VF02
+ if(Abs(planedist) > sph.w){
+ vi01 = 0;
+ return;
+ }
+ // point on plane
+ CVuVector p = sph - planedist*plane;
+ p.w = 0.0f;
+ vf01 = p;
+ planedist = Abs(planedist);
+ // edges
+ CVuVector v01 = v1 - v0;
+ CVuVector v12 = v2 - v1;
+ CVuVector v20 = v0 - v2;
+ // VU code calculates normal again for some weird reason...
+ // Check sides of point
+ CVector cross1 = CrossProduct(p-v0, v01);
+ CVector cross2 = CrossProduct(p-v1, v12);
+ CVector cross3 = CrossProduct(p-v2, v20);
+ // Only check relevant directions
+ int flagmask = 0;
+ if(Abs(plane.x) > 0.1f) flagmask |= 1;
+ if(Abs(plane.y) > 0.1f) flagmask |= 2;
+ if(Abs(plane.z) > 0.1f) flagmask |= 4;
+ int nflags = SignFlags(plane) & flagmask;
+ int flags1 = SignFlags(cross1) & flagmask;
+ int flags2 = SignFlags(cross2) & flagmask;
+ int flags3 = SignFlags(cross3) & flagmask;
+ int testcase = 0;
+ CVuVector closest(0.0f, 0.0f, 0.0f); // VF04
+ if(flags1 == nflags){
+ closest += v2;
+ testcase++;
+ }
+ if(flags2 == nflags){
+ closest += v0;
+ testcase++;
+ }
+ if(flags3 == nflags){
+ closest += v1;
+ testcase++;
+ }
+ if(testcase == 3){
+ // inside triangle - dist to plane already checked
+ vf02 = plane;
+ vf02.w = vf03.x = planedist;
+ vi01 = 1;
+ }else if(testcase == 1){
+ // outside two sides - closest to point opposide inside edge
+ vf01 = closest;
+ vf02 = sph - closest;
+ float distSq = vf02.MagnitudeSqr();
+ vi01 = sph.w*sph.w > distSq;
+ vf03.x = Sqrt(distSq);
+ vf02 *= 1.0f/vf03.x;
+ }else{
+ // inside two sides - closest to third edge
+ if(flags1 != nflags)
+ closest = DistanceBetweenSphereAndLine(sph, v0, v01);
+ else if(flags2 != nflags)
+ closest = DistanceBetweenSphereAndLine(sph, v1, v12);
+ else
+ closest = DistanceBetweenSphereAndLine(sph, v2, v20);
+ vi01 = sph.w*sph.w > closest.w;
+ vf01 = closest;
+ vf02 = sph - closest;
+ vf03.x = Sqrt(closest.w);
+ vf02 *= 1.0f/vf03.x;
+ }
+#endif
+}
+
+extern "C" void
+SphereToTriangleCollisionCompressed(const CVuVector &sph, VuTriangle &tri)
+{
+#ifdef GTA_PS2
+ __asm__ volatile (
+ ".set noreorder\n"
+ "lqc2 vf12, 0x0(%0)\n"
+ "lqc2 vf14, 0x0(%1)\n"
+ "lqc2 vf15, 0x10(%1)\n"
+ "lqc2 vf16, 0x20(%1)\n"
+ "lqc2 vf17, 0x30(%1)\n"
+ "vcallms Vu0SphereToTriangleCollisionCompressedStart\n"
+ ".set reorder\n"
+ :
+ : "r" (&sph), "r" (&tri)
+ );
+#else
+ CVuVector v0, v1, v2, plane;
+ v0.x = tri.v0[0]/128.0f;
+ v0.y = tri.v0[1]/128.0f;
+ v0.z = tri.v0[2]/128.0f;
+ v0.w = tri.v0[3]/128.0f;
+ v1.x = tri.v1[0]/128.0f;
+ v1.y = tri.v1[1]/128.0f;
+ v1.z = tri.v1[2]/128.0f;
+ v1.w = tri.v1[3]/128.0f;
+ v2.x = tri.v2[0]/128.0f;
+ v2.y = tri.v2[1]/128.0f;
+ v2.z = tri.v2[2]/128.0f;
+ v2.w = tri.v2[3]/128.0f;
+ plane.x = tri.plane[0]/4096.0f;
+ plane.y = tri.plane[1]/4096.0f;
+ plane.z = tri.plane[2]/4096.0f;
+ plane.w = tri.plane[3]/128.0f;
+ SphereToTriangleCollision(sph, v0, v1, v2, plane);
+#endif
+}
+
+inline int
+GetVUresult(void)
+{
+#ifdef GTA_PS2
+ int ret;
+ __asm__ volatile (
+ "cfc2.i %0,vi01\n" // .i important! wait for VU0 to finish
+ : "=r" (ret)
+ );
+ return ret;
+#else
+ return vi01;
+#endif
+}
+
+inline int
+GetVUresult(CVuVector &point, CVuVector &normal, float &dist)
+{
+#ifdef GTA_PS2
+ int ret;
+ __asm__ volatile (
+ "cfc2.i %0,vi01\n" // .i important! wait for VU0 to finish
+ "sqc2 vf01,(%1)\n"
+ "sqc2 vf02,(%2)\n"
+ "qmfc2 $12,vf03\n"
+ "sw $12,(%3)\n"
+ : "=r" (ret)
+ : "r" (&point), "r" (&normal), "r" (&dist)
+ : "$12"
+ );
+ return ret;
+#else
+ point = vf01;
+ normal = vf02;
+ dist = vf03.x;
+ return vi01;
+#endif
+}
+
+#endif
+
+
enum Direction
{
DIR_X_POS,
@@ -397,6 +738,20 @@ CCollision::TestVerticalLineBox(const CColLine &line, const CColBox &box)
bool
CCollision::TestLineTriangle(const CColLine &line, const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
{
+#ifdef VU_COLLISION
+ // not used in favour of optimized loops
+ VuTriangle vutri;
+ verts[tri.a].Unpack(vutri.v0);
+ verts[tri.b].Unpack(vutri.v1);
+ verts[tri.c].Unpack(vutri.v2);
+ plane.Unpack(vutri.plane);
+
+ LineToTriangleCollisionCompressed(*(CVuVector*)&line.p0, *(CVuVector*)&line.p1, vutri);
+
+ if(GetVUresult())
+ return true;
+ return false;
+#else
float t;
CVector normal;
plane.GetNormal(normal);
@@ -470,6 +825,7 @@ CCollision::TestLineTriangle(const CColLine &line, const CompressedVector *verts
if(CrossProduct2D(vec3-vec1, vect-vec1) > 0.0f) return false;
if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return false;
return true;
+#endif
}
// Test if line segment intersects with sphere.
@@ -507,6 +863,20 @@ bool
CCollision::TestSphereTriangle(const CColSphere &sphere,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane)
{
+#ifdef VU_COLLISION
+ // not used in favour of optimized loops
+ VuTriangle vutri;
+ verts[tri.a].Unpack(vutri.v0);
+ verts[tri.b].Unpack(vutri.v1);
+ verts[tri.c].Unpack(vutri.v2);
+ plane.Unpack(vutri.plane);
+
+ SphereToTriangleCollisionCompressed(*(CVuVector*)&sphere, vutri);
+
+ if(GetVUresult())
+ return true;
+ return false;
+#else
// If sphere and plane don't intersect, no collision
float planedist = plane.CalcPoint(sphere.center);
if(Abs(planedist) > sphere.radius)
@@ -520,7 +890,9 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
CVector vec2 = vb - va;
float len = vec2.Magnitude();
vec2 = vec2 * (1.0f/len);
- CVector vec1 = CrossProduct(vec2, plane.normal);
+ CVector normal;
+ plane.GetNormal(normal);
+ CVector vec1 = CrossProduct(vec2, normal);
// We know A has local coordinate [0,0] and B has [0,len].
// Now calculate coordinates on triangle for these two vectors:
@@ -563,11 +935,78 @@ CCollision::TestSphereTriangle(const CColSphere &sphere,
}
return dist < sphere.radius;
+#endif
}
bool
CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColModel &model, bool ignoreSeeThrough)
{
+#ifdef VU_COLLISION
+ CMatrix matTransform;
+ int i;
+
+ // transform line to model space
+ Invert(matrix, matTransform);
+ CVuVector newline[2];
+ TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2);
+
+ // If we don't intersect with the bounding box, no chance on the rest
+ if(!TestLineBox(*(CColLine*)newline, model.boundingBox))
+ return false;
+
+ for(i = 0; i < model.numSpheres; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(TestLineSphere(*(CColLine*)newline, model.spheres[i]))
+ return true;
+ }
+
+ for(i = 0; i < model.numBoxes; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(TestLineBox(*(CColLine*)newline, model.boxes[i]))
+ return true;
+ }
+
+ CalculateTrianglePlanes(&model);
+ int lastTest = -1;
+ VuTriangle vutri;
+ for(i = 0; i < model.numTriangles; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+
+ CColTriangle *tri = &model.triangles[i];
+ model.vertices[tri->a].Unpack(vutri.v0);
+ model.vertices[tri->b].Unpack(vutri.v1);
+ model.vertices[tri->c].Unpack(vutri.v2);
+ model.trianglePlanes[i].Unpack(vutri.plane);
+
+ LineToTriangleCollisionCompressed(newline[0], newline[1], vutri);
+ lastTest = i;
+ break;
+ }
+#ifdef FIX_BUGS
+ // no need to check first again
+ i++;
+#endif
+ for(; i < model.numTriangles; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+
+ CColTriangle *tri = &model.triangles[i];
+ model.vertices[tri->a].Unpack(vutri.v0);
+ model.vertices[tri->b].Unpack(vutri.v1);
+ model.vertices[tri->c].Unpack(vutri.v2);
+ model.trianglePlanes[i].Unpack(vutri.plane);
+
+ if(GetVUresult())
+ return true;
+
+ LineToTriangleCollisionCompressed(newline[0], newline[1], vutri);
+ lastTest = i;
+
+ }
+ if(lastTest != -1 && GetVUresult())
+ return true;
+
+ return false;
+#else
static CMatrix matTransform;
int i;
@@ -599,6 +1038,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
}
return false;
+#endif
}
@@ -614,20 +1054,24 @@ CCollision::ProcessSphereSphere(const CColSphere &s1, const CColSphere &s2, CCol
{
CVector dist = s1.center - s2.center;
float d = dist.Magnitude() - s2.radius; // distance from s1's center to s2
- float dc = d < 0.0f ? 0.0f : d; // clamp to zero, i.e. if s1's center is inside s2
+ float depth = s1.radius - d; // sphere overlap
+ if(d < 0.0f) d = 0.0f; // clamp to zero, i.e. if s1's center is inside s2
// no collision if sphere is not close enough
- if(mindistsq <= dc*dc || s1.radius <= dc)
- return false;
- dist.Normalise();
- point.point = s1.center - dist*dc;
- point.normal = dist;
- point.surfaceA = s1.surface;
- point.pieceA = s1.piece;
- point.surfaceB = s2.surface;
- point.pieceB = s2.piece;
- point.depth = s1.radius - d; // sphere overlap
- mindistsq = dc*dc; // collision radius
- return true;
+ if(d*d < mindistsq && d < s1.radius){
+ dist.Normalise();
+ point.point = s1.center - dist*d;
+ point.normal = dist;
+#ifndef VU_COLLISION
+ point.surfaceA = s1.surface;
+ point.pieceA = s1.piece;
+ point.surfaceB = s2.surface;
+ point.pieceB = s2.piece;
+#endif
+ point.depth = depth;
+ mindistsq = d*d; // collision radius
+ return true;
+ }
+ return false;
}
bool
@@ -667,10 +1111,12 @@ CCollision::ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoin
if(lensq < mindistsq){
point.normal = dist * (1.0f/Sqrt(lensq));
point.point = sph.center - point.normal;
+#ifndef VU_COLLISION
point.surfaceA = sph.surface;
point.pieceA = sph.piece;
point.surfaceB = box.surface;
point.pieceB = box.piece;
+#endif
// find absolute distance to the closer side in each dimension
float dx = dist.x > 0.0f ?
@@ -710,10 +1156,12 @@ CCollision::ProcessSphereBox(const CColSphere &sph, const CColBox &box, CColPoin
float len = Sqrt(lensq);
point.point = p;
point.normal = dist * (1.0f/len);
+#ifndef VU_COLLISION
point.surfaceA = sph.surface;
point.pieceA = sph.piece;
point.surfaceB = box.surface;
point.pieceB = box.piece;
+#endif
point.depth = sph.radius - len;
mindistsq = lensq;
return true;
@@ -828,10 +1276,12 @@ CCollision::ProcessLineBox(const CColLine &line, const CColBox &box, CColPoint &
point.point = p;
point.normal = normal;
+#ifndef VU_COLLISION
point.surfaceA = 0;
point.pieceA = 0;
point.surfaceB = box.surface;
point.pieceB = box.piece;
+#endif
mindist = mint;
return true;
@@ -861,10 +1311,12 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC
point.point = line.p0 + v01*t;
point.normal = point.point - sphere.center;
point.normal.Normalise();
+#ifndef VU_COLLISION
point.surfaceA = 0;
point.pieceA = 0;
point.surfaceB = sphere.surface;
point.pieceB = sphere.piece;
+#endif
mindist = t;
return true;
}
@@ -874,6 +1326,17 @@ CCollision::ProcessVerticalLineTriangle(const CColLine &line,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist, CStoredCollPoly *poly)
{
+#ifdef VU_COLLISION
+ // not used in favour of optimized loops
+ bool res = ProcessLineTriangle(line, verts, tri, plane, point, mindist);
+ if(res && poly){
+ poly->verts[0] = verts[tri.a].Get();
+ poly->verts[1] = verts[tri.b].Get();
+ poly->verts[2] = verts[tri.c].Get();
+ poly->valid = true;
+ }
+ return res;
+#else
float t;
CVector normal;
@@ -960,11 +1423,40 @@ CCollision::ProcessVerticalLineTriangle(const CColLine &line,
}
mindist = t;
return true;
+#endif
}
bool
CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CColPoint &point, CStoredCollPoly *poly)
{
+#ifdef VU_COLLISION
+ if(!poly->valid)
+ return false;
+
+ CVuVector p0 = pos;
+ CVuVector p1 = pos;
+ p1.z = z;
+
+ CVector v01 = poly->verts[1] - poly->verts[0];
+ CVector v02 = poly->verts[2] - poly->verts[0];
+ CVuVector plane = CrossProduct(v02, v01);
+ plane.Normalise();
+ plane.w = DotProduct(plane, poly->verts[0]);
+
+ LineToTriangleCollision(p0, p1, poly->verts[0], poly->verts[1], poly->verts[2], plane);
+
+ CVuVector pnt;
+ float dist;
+ if(!GetVUresult(pnt, plane, dist))
+#ifdef FIX_BUGS
+ // perhaps not needed but be safe
+ return poly->valid = false;
+#else
+ return false;
+#endif
+ point.point = pnt;
+ return true;
+#else
float t;
if(!poly->valid)
@@ -987,7 +1479,9 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
return poly->valid = false;
// intersection parameter on line
- t = -plane.CalcPoint(p0) / DotProduct(p1 - p0, plane.normal);
+ CVector normal;
+ plane.GetNormal(normal);
+ t = -plane.CalcPoint(p0) / DotProduct(p1 - p0, normal);
// find point of intersection
CVector p = p0 + (p1-p0)*t;
@@ -1037,13 +1531,36 @@ CCollision::IsStoredPolyStillValidVerticalLine(const CVector &pos, float z, CCol
if(CrossProduct2D(vec3-vec2, vect-vec2) < 0.0f) return poly->valid = false;
point.point = p;
return poly->valid = true;
+#endif
}
bool
-CCollision::ProcessLineTriangle(const CColLine &line ,
+CCollision::ProcessLineTriangle(const CColLine &line,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindist)
{
+#ifdef VU_COLLISION
+ // not used in favour of optimized loops
+ VuTriangle vutri;
+ verts[tri.a].Unpack(vutri.v0);
+ verts[tri.b].Unpack(vutri.v1);
+ verts[tri.c].Unpack(vutri.v2);
+ plane.Unpack(vutri.plane);
+
+ LineToTriangleCollisionCompressed(*(CVuVector*)&line.p0, *(CVuVector*)&line.p1, vutri);
+
+ CVuVector pnt, normal;
+ float dist;
+ if(GetVUresult(pnt, normal, dist)){
+ if(dist < mindist){
+ point.point = pnt;
+ point.normal = normal;
+ mindist = dist;
+ return true;
+ }
+ }
+ return false;
+#else
float t;
CVector normal;
plane.GetNormal(normal);
@@ -1117,6 +1634,7 @@ CCollision::ProcessLineTriangle(const CColLine &line ,
point.pieceB = 0;
mindist = t;
return true;
+#endif
}
bool
@@ -1124,6 +1642,30 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
CColPoint &point, float &mindistsq)
{
+#ifdef VU_COLLISION
+ // not used in favour of optimized loops
+ VuTriangle vutri;
+ verts[tri.a].Unpack(vutri.v0);
+ verts[tri.b].Unpack(vutri.v1);
+ verts[tri.c].Unpack(vutri.v2);
+ plane.Unpack(vutri.plane);
+
+ SphereToTriangleCollisionCompressed(*(CVuVector*)&sphere, vutri);
+
+ CVuVector pnt, normal;
+ float dist;
+ if(GetVUresult(pnt, normal, dist) && dist*dist < mindistsq){
+ float depth = sphere.radius - dist;
+ if(depth > point.depth){
+ point.point = pnt;
+ point.normal = normal;
+ point.depth = depth;
+ mindistsq = dist*dist;
+ return true;
+ }
+ }
+ return false;
+#else
// If sphere and plane don't intersect, no collision
float planedist = plane.CalcPoint(sphere.center);
float distsq = planedist*planedist;
@@ -1191,13 +1733,16 @@ CCollision::ProcessSphereTriangle(const CColSphere &sphere,
point.point = p;
point.normal = sphere.center - p;
point.normal.Normalise();
+#ifndef VU_COLLISION
point.surfaceA = sphere.surface;
point.pieceA = sphere.piece;
point.surfaceB = tri.surface;
point.pieceB = 0;
+#endif
point.depth = sphere.radius - dist;
mindistsq = dist*dist;
return true;
+#endif
}
bool
@@ -1205,6 +1750,94 @@ CCollision::ProcessLineOfSight(const CColLine &line,
const CMatrix &matrix, CColModel &model,
CColPoint &point, float &mindist, bool ignoreSeeThrough)
{
+#ifdef VU_COLLISION
+ CMatrix matTransform;
+ int i;
+
+ // transform line to model space
+ Invert(matrix, matTransform);
+ CVuVector newline[2];
+ TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2);
+
+ if(mindist < 1.0f)
+ newline[1] = newline[0] + (newline[1] - newline[0])*mindist;
+
+ // If we don't intersect with the bounding box, no chance on the rest
+ if(!TestLineBox(*(CColLine*)newline, model.boundingBox))
+ return false;
+
+ float coldist = 1.0f;
+ for(i = 0; i < model.numSpheres; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ProcessLineSphere(*(CColLine*)newline, model.spheres[i], point, coldist))
+ point.Set(0, 0, model.spheres[i].surface, model.spheres[i].piece);
+ }
+
+ for(i = 0; i < model.numBoxes; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ProcessLineBox(*(CColLine*)newline, model.boxes[i], point, coldist))
+ point.Set(0, 0, model.boxes[i].surface, model.boxes[i].piece);
+ }
+
+ CalculateTrianglePlanes(&model);
+ VuTriangle vutri;
+ CColTriangle *lasttri = nil;
+ for(i = 0; i < model.numTriangles; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+
+ CColTriangle *tri = &model.triangles[i];
+ model.vertices[tri->a].Unpack(vutri.v0);
+ model.vertices[tri->b].Unpack(vutri.v1);
+ model.vertices[tri->c].Unpack(vutri.v2);
+ model.trianglePlanes[i].Unpack(vutri.plane);
+
+ LineToTriangleCollisionCompressed(newline[0], newline[1], vutri);
+ lasttri = tri;
+ break;
+ }
+#ifdef FIX_BUGS
+ // no need to check first again
+ i++;
+#endif
+ CVuVector pnt, normal;
+ float dist;
+ for(; i < model.numTriangles; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+
+ CColTriangle *tri = &model.triangles[i];
+ model.vertices[tri->a].Unpack(vutri.v0);
+ model.vertices[tri->b].Unpack(vutri.v1);
+ model.vertices[tri->c].Unpack(vutri.v2);
+ model.trianglePlanes[i].Unpack(vutri.plane);
+
+ if(GetVUresult(pnt, normal, dist))
+ if(dist < coldist){
+ point.point = pnt;
+ point.normal = normal;
+ point.Set(0, 0, lasttri->surface, 0);
+ coldist = dist;
+ }
+
+ LineToTriangleCollisionCompressed(newline[0], newline[1], vutri);
+ lasttri = tri;
+ }
+ if(lasttri && GetVUresult(pnt, normal, dist))
+ if(dist < coldist){
+ point.point = pnt;
+ point.normal = normal;
+ point.Set(0, 0, lasttri->surface, 0);
+ coldist = dist;
+ }
+
+
+ if(coldist < 1.0f){
+ point.point = matrix * point.point;
+ point.normal = Multiply3x3(matrix, point.normal);
+ mindist *= coldist;
+ return true;
+ }
+ return false;
+#else
static CMatrix matTransform;
int i;
@@ -1240,6 +1873,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
return true;
}
return false;
+#endif
}
bool
@@ -1247,6 +1881,125 @@ CCollision::ProcessVerticalLine(const CColLine &line,
const CMatrix &matrix, CColModel &model,
CColPoint &point, float &mindist, bool ignoreSeeThrough, CStoredCollPoly *poly)
{
+#ifdef VU_COLLISION
+ static CStoredCollPoly TempStoredPoly;
+ CMatrix matTransform;
+ int i;
+
+ // transform line to model space
+ Invert(matrix, matTransform);
+ CVuVector newline[2];
+ TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2);
+
+ if(mindist < 1.0f)
+ newline[1] = newline[0] + (newline[1] - newline[0])*mindist;
+
+ if(!TestLineBox(*(CColLine*)newline, model.boundingBox))
+ return false;
+
+ float coldist = 1.0f;
+ for(i = 0; i < model.numSpheres; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.spheres[i].surface)) continue;
+ if(ProcessLineSphere(*(CColLine*)newline, model.spheres[i], point, coldist))
+ point.Set(0, 0, model.spheres[i].surface, model.spheres[i].piece);
+ }
+
+ for(i = 0; i < model.numBoxes; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.boxes[i].surface)) continue;
+ if(ProcessLineBox(*(CColLine*)newline, model.boxes[i], point, coldist))
+ point.Set(0, 0, model.boxes[i].surface, model.boxes[i].piece);
+ }
+
+ CalculateTrianglePlanes(&model);
+ TempStoredPoly.valid = false;
+ if(model.numTriangles){
+ bool registeredCol;
+ CColTriangle *lasttri = nil;
+ VuTriangle vutri;
+ for(i = 0; i < model.numTriangles; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+
+ CColTriangle *tri = &model.triangles[i];
+ model.vertices[tri->a].Unpack(vutri.v0);
+ model.vertices[tri->b].Unpack(vutri.v1);
+ model.vertices[tri->c].Unpack(vutri.v2);
+ model.trianglePlanes[i].Unpack(vutri.plane);
+
+ LineToTriangleCollisionCompressed(newline[0], newline[1], vutri);
+ lasttri = tri;
+ break;
+ }
+#ifdef FIX_BUGS
+ // no need to check first again
+ i++;
+#endif
+ CVuVector pnt, normal;
+ float dist;
+ for(; i < model.numTriangles; i++){
+ if(ignoreSeeThrough && IsSeeThrough(model.triangles[i].surface)) continue;
+
+ CColTriangle *tri = &model.triangles[i];
+ model.vertices[tri->a].Unpack(vutri.v0);
+ model.vertices[tri->b].Unpack(vutri.v1);
+ model.vertices[tri->c].Unpack(vutri.v2);
+ model.trianglePlanes[i].Unpack(vutri.plane);
+
+ if(GetVUresult(pnt, normal, dist)){
+ if(dist < coldist){
+ point.point = pnt;
+ point.normal = normal;
+ point.Set(0, 0, lasttri->surface, 0);
+ coldist = dist;
+ registeredCol = true;
+ }else
+ registeredCol = false;
+ }else
+ registeredCol = false;
+
+ if(registeredCol){
+ TempStoredPoly.verts[0] = model.vertices[lasttri->a].Get();
+ TempStoredPoly.verts[1] = model.vertices[lasttri->b].Get();
+ TempStoredPoly.verts[2] = model.vertices[lasttri->c].Get();
+ TempStoredPoly.valid = true;
+ }
+
+ LineToTriangleCollisionCompressed(newline[0], newline[1], vutri);
+ lasttri = tri;
+ }
+ if(lasttri && GetVUresult(pnt, normal, dist)){
+ if(dist < coldist){
+ point.point = pnt;
+ point.normal = normal;
+ point.Set(0, 0, lasttri->surface, 0);
+ coldist = dist;
+ registeredCol = true;
+ }else
+ registeredCol = false;
+ }else
+ registeredCol = false;
+
+ if(registeredCol){
+ TempStoredPoly.verts[0] = model.vertices[lasttri->a].Get();
+ TempStoredPoly.verts[1] = model.vertices[lasttri->b].Get();
+ TempStoredPoly.verts[2] = model.vertices[lasttri->c].Get();
+ TempStoredPoly.valid = true;
+ }
+ }
+
+ if(coldist < 1.0f){
+ point.point = matrix * point.point;
+ point.normal = Multiply3x3(matrix, point.normal);
+ if(TempStoredPoly.valid && poly){
+ *poly = TempStoredPoly;
+ poly->verts[0] = matrix * CVector(poly->verts[0]);
+ poly->verts[1] = matrix * CVector(poly->verts[1]);
+ poly->verts[2] = matrix * CVector(poly->verts[2]);
+ }
+ mindist *= coldist;
+ return true;
+ }
+ return false;
+#else
static CStoredCollPoly TempStoredPoly;
int i;
@@ -1290,6 +2043,7 @@ CCollision::ProcessVerticalLine(const CColLine &line,
return true;
}
return false;
+#endif
}
enum {
@@ -1299,6 +2053,15 @@ enum {
MAXNUMTRIS = 600
};
+#ifdef VU_COLLISION
+#ifdef GTA_PS2
+#define SPR(off) ((uint8*)(0x70000000 + (off)))
+#else
+static uint8 fakeSPR[16*1024];
+#define SPR(off) ((uint8*)(fakeSPR + (off)))
+#endif
+#endif
+
// This checks model A's spheres and lines against model B's spheres, boxes and triangles.
// Returns the number of A's spheres that collide.
// Returned ColPoints are in world space.
@@ -1308,6 +2071,308 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
const CMatrix &matrixB, CColModel &modelB,
CColPoint *spherepoints, CColPoint *linepoints, float *linedists)
{
+#ifdef VU_COLLISION
+ CVuVector *aSpheresA = (CVuVector*)SPR(0x0000);
+ CVuVector *aSpheresB = (CVuVector*)SPR(0x0800);
+ CVuVector *aLinesA = (CVuVector*)SPR(0x1000);
+ int32 *aSphereIndicesA = (int32*)SPR(0x1200);
+ int32 *aSphereIndicesB = (int32*)SPR(0x1400);
+ int32 *aBoxIndicesB = (int32*)SPR(0x1600);
+ int32 *aTriangleIndicesB = (int32*)SPR(0x1680);
+ bool *aCollided = (bool*)SPR(0x1FE0);
+ CMatrix &matAB = *(CMatrix*)SPR(0x1FF0);
+ CMatrix &matBA = *(CMatrix*)SPR(0x2040);
+ int i, j, k;
+
+ // From model A space to model B space
+ Invert(matrixB, matAB);
+ matAB *= matrixA;
+
+ CVuVector bsphereAB; // bounding sphere of A in B space
+ TransformPoint(bsphereAB, matAB, *(RwV3d*)modelA.boundingSphere.center); // inlined
+ bsphereAB.w = modelA.boundingSphere.radius;
+ if(!TestSphereBox(*(CColSphere*)&bsphereAB, modelB.boundingBox))
+ return 0;
+
+ // transform modelA's spheres and lines to B space
+ TransformPoints(aSpheresA, modelA.numSpheres, matAB, (RwV3d*)&modelA.spheres->center, sizeof(CColSphere));
+ for(i = 0; i < modelA.numSpheres; i++)
+ aSpheresA[i].w = modelA.spheres[i].radius;
+ TransformPoints(aLinesA, modelA.numLines*2, matAB, (RwV3d*)&modelA.lines->p0, sizeof(CColLine)/2);
+
+ // Test them against model B's bounding volumes
+ int numSpheresA = 0;
+ for(i = 0; i < modelA.numSpheres; i++)
+ if(TestSphereBox(*(CColSphere*)&aSpheresA[i], modelB.boundingBox))
+ aSphereIndicesA[numSpheresA++] = i;
+ // No collision
+ if(numSpheresA == 0 && modelA.numLines == 0)
+ return 0;
+
+
+ // B to A space
+ Invert(matrixA, matBA);
+ matBA *= matrixB;
+
+ // transform modelB's spheres to A space
+ TransformPoints(aSpheresB, modelB.numSpheres, matBA, (RwV3d*)&modelB.spheres->center, sizeof(CColSphere));
+ for(i = 0; i < modelB.numSpheres; i++)
+ aSpheresB[i].w = modelB.spheres[i].radius;
+
+ // Check model B against A's bounding volumes
+ int numSpheresB = 0;
+ int numBoxesB = 0;
+ int numTrianglesB = 0;
+ for(i = 0; i < modelB.numSpheres; i++)
+ if(TestSphereBox(*(CColSphere*)&aSpheresB[i], modelA.boundingBox))
+ aSphereIndicesB[numSpheresB++] = i;
+ for(i = 0; i < modelB.numBoxes; i++)
+ if(TestSphereBox(*(CColSphere*)&bsphereAB, modelB.boxes[i]))
+ aBoxIndicesB[numBoxesB++] = i;
+ CalculateTrianglePlanes(&modelB);
+ if(modelB.numTriangles){
+ VuTriangle vutri;
+ // process the first triangle
+ CColTriangle *tri = &modelB.triangles[0];
+ modelB.vertices[tri->a].Unpack(vutri.v0);
+ modelB.vertices[tri->b].Unpack(vutri.v1);
+ modelB.vertices[tri->c].Unpack(vutri.v2);
+ modelB.trianglePlanes[0].Unpack(vutri.plane);
+
+ SphereToTriangleCollisionCompressed(bsphereAB, vutri);
+
+ for(i = 1; i < modelB.numTriangles; i++){
+ // set up the next triangle while VU0 is running
+ tri = &modelB.triangles[i];
+ modelB.vertices[tri->a].Unpack(vutri.v0);
+ modelB.vertices[tri->b].Unpack(vutri.v1);
+ modelB.vertices[tri->c].Unpack(vutri.v2);
+ modelB.trianglePlanes[i].Unpack(vutri.plane);
+
+ // check previous result
+ if(GetVUresult())
+ aTriangleIndicesB[numTrianglesB++] = i-1;
+
+ // kick off this one
+ SphereToTriangleCollisionCompressed(bsphereAB, vutri);
+ }
+
+ // check last result
+ if(GetVUresult())
+ aTriangleIndicesB[numTrianglesB++] = i-1;
+ }
+ // No collision
+ if(numSpheresB == 0 && numBoxesB == 0 && numTrianglesB == 0)
+ return 0;
+
+ // We now have the collision volumes in A and B that are worth processing.
+
+ // Process A's spheres against B's collision volumes
+ int numCollisions = 0;
+ spherepoints[numCollisions].depth = -1.0f;
+ for(i = 0; i < numSpheresA; i++){
+ float coldist = 1.0e24f;
+ bool hasCollided = false;
+ CColSphere *sphA = &modelA.spheres[aSphereIndicesA[i]];
+ CVuVector *vusphA = &aSpheresA[aSphereIndicesA[i]];
+
+ for(j = 0; j < numSpheresB; j++)
+ // This actually looks like something was inlined here
+ if(ProcessSphereSphere(*(CColSphere*)vusphA, modelB.spheres[aSphereIndicesB[j]],
+ spherepoints[numCollisions], coldist)){
+ spherepoints[numCollisions].Set(
+ sphA->surface, sphA->piece,
+ modelB.spheres[aSphereIndicesB[j]].surface, modelB.spheres[aSphereIndicesB[j]].piece);
+ hasCollided = true;
+ }
+ for(j = 0; j < numBoxesB; j++)
+ if(ProcessSphereBox(*(CColSphere*)vusphA, modelB.boxes[aBoxIndicesB[j]],
+ spherepoints[numCollisions], coldist)){
+ spherepoints[numCollisions].Set(
+ sphA->surface, sphA->piece,
+ modelB.boxes[aBoxIndicesB[j]].surface, modelB.boxes[aBoxIndicesB[j]].piece);
+ hasCollided = true;
+ }
+ if(numTrianglesB){
+ CVuVector point, normal;
+ float depth;
+ bool registeredCol;
+ CColTriangle *lasttri;
+
+ VuTriangle vutri;
+ // process the first triangle
+ k = aTriangleIndicesB[0];
+ CColTriangle *tri = &modelB.triangles[k];
+ modelB.vertices[tri->a].Unpack(vutri.v0);
+ modelB.vertices[tri->b].Unpack(vutri.v1);
+ modelB.vertices[tri->c].Unpack(vutri.v2);
+ modelB.trianglePlanes[k].Unpack(vutri.plane);
+
+ SphereToTriangleCollisionCompressed(*vusphA, vutri);
+ lasttri = tri;
+
+ for(j = 1; j < numTrianglesB; j++){
+ k = aTriangleIndicesB[j];
+ // set up the next triangle while VU0 is running
+ tri = &modelB.triangles[k];
+ modelB.vertices[tri->a].Unpack(vutri.v0);
+ modelB.vertices[tri->b].Unpack(vutri.v1);
+ modelB.vertices[tri->c].Unpack(vutri.v2);
+ modelB.trianglePlanes[k].Unpack(vutri.plane);
+
+ // check previous result
+ // TODO: this looks inlined but spherepoints[numCollisions] does not...
+ if(GetVUresult(point, normal, depth)){
+ depth = sphA->radius - depth;
+ if(depth > spherepoints[numCollisions].depth){
+ spherepoints[numCollisions].point = point;
+ spherepoints[numCollisions].normal = normal;
+ spherepoints[numCollisions].Set(depth,
+ sphA->surface, sphA->piece, lasttri->surface, 0);
+ registeredCol = true;
+ }else
+ registeredCol = false;
+ }else
+ registeredCol = false;
+
+ if(registeredCol)
+ hasCollided = true;
+
+ // kick off this one
+ SphereToTriangleCollisionCompressed(*vusphA, vutri);
+ lasttri = tri;
+ }
+
+ // check last result
+ // TODO: this looks inlined but spherepoints[numCollisions] does not...
+ if(GetVUresult(point, normal, depth)){
+ depth = sphA->radius - depth;
+ if(depth > spherepoints[numCollisions].depth){
+ spherepoints[numCollisions].point = point;
+ spherepoints[numCollisions].normal = normal;
+ spherepoints[numCollisions].Set(depth,
+ sphA->surface, sphA->piece, lasttri->surface, 0);
+ registeredCol = true;
+ }else
+ registeredCol = false;
+ }else
+ registeredCol = false;
+
+ if(registeredCol)
+ hasCollided = true;
+ }
+
+ if(hasCollided){
+ numCollisions++;
+ if(numCollisions == MAX_COLLISION_POINTS)
+ break;
+ spherepoints[numCollisions].depth = -1.0f;
+ }
+ }
+ for(i = 0; i < numCollisions; i++){
+ // TODO: both VU0 macros
+ spherepoints[i].point = matrixB * spherepoints[i].point;
+ spherepoints[i].normal = Multiply3x3(matrixB, spherepoints[i].normal);
+ }
+
+ // And the same thing for the lines in A
+ for(i = 0; i < modelA.numLines; i++){
+ aCollided[i] = false;
+ CVuVector *lineA = &aLinesA[i*2];
+
+ for(j = 0; j < numSpheresB; j++)
+ if(ProcessLineSphere(*(CColLine*)lineA, modelB.spheres[aSphereIndicesB[j]],
+ linepoints[i], linedists[i])){
+ linepoints[i].Set(0, 0,
+#ifdef FIX_BUGS
+ modelB.spheres[aSphereIndicesB[j]].surface, modelB.spheres[aSphereIndicesB[j]].piece);
+#else
+ modelB.spheres[j].surface, modelB.spheres[j].piece);
+#endif
+ aCollided[i] = true;
+ }
+ for(j = 0; j < numBoxesB; j++)
+ if(ProcessLineBox(*(CColLine*)lineA, modelB.boxes[aBoxIndicesB[j]],
+ linepoints[i], linedists[i])){
+ linepoints[i].Set(0, 0,
+ modelB.boxes[aBoxIndicesB[j]].surface, modelB.boxes[aBoxIndicesB[j]].piece);
+ aCollided[i] = true;
+ }
+ if(numTrianglesB){
+ CVuVector point, normal;
+ float dist;
+ bool registeredCol;
+ CColTriangle *lasttri;
+
+ VuTriangle vutri;
+ // process the first triangle
+ k = aTriangleIndicesB[0];
+ CColTriangle *tri = &modelB.triangles[k];
+ modelB.vertices[tri->a].Unpack(vutri.v0);
+ modelB.vertices[tri->b].Unpack(vutri.v1);
+ modelB.vertices[tri->c].Unpack(vutri.v2);
+ modelB.trianglePlanes[k].Unpack(vutri.plane);
+
+ LineToTriangleCollisionCompressed(lineA[0], lineA[1], vutri);
+ lasttri = tri;
+
+ for(j = 1; j < numTrianglesB; j++){
+ k = aTriangleIndicesB[j];
+ // set up the next triangle while VU0 is running
+ CColTriangle *tri = &modelB.triangles[k];
+ modelB.vertices[tri->a].Unpack(vutri.v0);
+ modelB.vertices[tri->b].Unpack(vutri.v1);
+ modelB.vertices[tri->c].Unpack(vutri.v2);
+ modelB.trianglePlanes[k].Unpack(vutri.plane);
+
+ // check previous result
+ // TODO: this again somewhat looks inlined
+ if(GetVUresult(point, normal, dist)){
+ if(dist < linedists[i]){
+ linepoints[i].point = point;
+ linepoints[i].normal = normal;
+ linedists[i] = dist;
+ linepoints[i].Set(0, 0, lasttri->surface, 0);
+ registeredCol = true;
+ }else
+ registeredCol = false;
+ }else
+ registeredCol = false;
+
+ if(registeredCol)
+ aCollided[i] = true;
+
+ // kick of this one
+ LineToTriangleCollisionCompressed(lineA[0], lineA[1], vutri);
+ lasttri = tri;
+ }
+
+ // check last result
+ if(GetVUresult(point, normal, dist)){
+ if(dist < linedists[i]){
+ linepoints[i].point = point;
+ linepoints[i].normal = normal;
+ linedists[i] = dist;
+ linepoints[i].Set(0, 0, lasttri->surface, 0);
+ registeredCol = true;
+ }else
+ registeredCol = false;
+ }else
+ registeredCol = false;
+
+ if(registeredCol)
+ aCollided[i] = true;
+ }
+
+ if(aCollided[i]){
+ // TODO: both VU0 macros
+ linepoints[i].point = matrixB * linepoints[i].point;
+ linepoints[i].normal = Multiply3x3(matrixB, linepoints[i].normal);
+ }
+ }
+
+ return numCollisions; // sphere collisions
+#else
static int aSphereIndicesA[MAXNUMSPHERES];
static int aLineIndicesA[MAXNUMLINES];
static int aSphereIndicesB[MAXNUMSPHERES];
@@ -1324,14 +2389,16 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
assert(modelA.numLines <= MAXNUMLINES);
// From model A space to model B space
- matAB = Invert(matrixB, matAB) * matrixA;
+ Invert(matrixB, matAB);
+ matAB *= matrixA;
CColSphere bsphereAB; // bounding sphere of A in B space
bsphereAB.Set(modelA.boundingSphere.radius, matAB * modelA.boundingSphere.center);
if(!TestSphereBox(bsphereAB, modelB.boundingBox))
return 0;
// B to A space
- matBA = Invert(matrixA, matBA) * matrixB;
+ matBA = Invert(matrixA, matBA);
+ matBA *= matrixB;
// transform modelA's spheres and lines to B space
for(i = 0; i < modelA.numSpheres; i++){
@@ -1444,6 +2511,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
}
return numCollisions; // sphere collisions
+#endif
}
@@ -1987,6 +3055,19 @@ CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uin
this->surface = surf;
}
+#ifdef VU_COLLISION
+void
+CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
+{
+ CVector norm = CrossProduct(vc-va, vb-va);
+ norm.Normalise();
+ float d = DotProduct(norm, va);
+ normal.x = norm.x*4096.0f;
+ normal.y = norm.y*4096.0f;
+ normal.z = norm.z*4096.0f;
+ dist = d*128.0f;
+}
+#else
void
CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
{
@@ -2002,6 +3083,7 @@ CColTrianglePlane::Set(const CVector &va, const CVector &vb, const CVector &vc)
else
dir = normal.z < 0.0f ? DIR_Z_NEG : DIR_Z_POS;
}
+#endif
CColModel::CColModel(void)
{
diff --git a/src/core/Collision.h b/src/core/Collision.h
index d988f0c2..d7498ac0 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -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 CColSphere
{
+ // NB: this has to be compatible with a CVuVector
CVector center;
float radius;
uint8 surface;
@@ -47,6 +73,7 @@ struct CColBox
struct CColLine
{
+ // NB: this has to be compatible with two CVuVectors
CVector p0;
int pad0;
CVector p1;
@@ -69,6 +96,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;
@@ -77,6 +137,7 @@ struct CColTrianglePlane
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 CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
+#endif
};
struct CColPoint
@@ -91,11 +152,29 @@ struct CColPoint
uint8 surfaceB;
uint8 pieceB;
float depth;
+
+ void Set(float depth, uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
+ this->depth = depth;
+ this->surfaceA = surfA;
+ this->pieceA = pieceA;
+ this->surfaceB = surfB;
+ this->pieceB = pieceB;
+ }
+ void Set(uint8 surfA, uint8 pieceA, uint8 surfB, uint8 pieceB) {
+ this->surfaceA = surfA;
+ this->pieceA = pieceA;
+ this->surfaceB = surfB;
+ this->pieceB = pieceB;
+ }
};
struct CStoredCollPoly
{
+#ifdef VU_COLLISION
+ CVuVector verts[3];
+#else
CVector verts[3];
+#endif
bool valid;
};
diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp
index 675040ea..8d69ba78 100644
--- a/src/core/EventList.cpp
+++ b/src/core/EventList.cpp
@@ -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:
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 82e6992d..08623c65 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -106,6 +106,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
@@ -139,6 +140,7 @@ void MessageScreen(char *msg)
DoRWStuffEndOfFrame();
}
+#endif
bool
CGame::InitialiseOnceBeforeRW(void)
@@ -431,6 +433,7 @@ bool CGame::Initialise(const char* datFile)
if ( !TheMemoryCard.m_bWantToLoad )
{
#endif
+ LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript();
CTheScripts::Process();
TheCamera.Process();
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 7df548aa..d4ffc5ea 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -1104,7 +1104,9 @@ void CPad::UpdatePads(void)
if ( bUpdate )
{
GetPad(0)->Update(0);
+#ifndef SQUEEZE_PERFORMANCE
GetPad(1)->Update(0);
+#endif
}
#if defined(MASTER) && !defined(XINPUT)
diff --git a/src/core/SurfaceTable.h b/src/core/SurfaceTable.h
index 1f16843d..8ee1724e 100644
--- a/src/core/SurfaceTable.h
+++ b/src/core/SurfaceTable.h
@@ -60,6 +60,11 @@ IsSeeThrough(uint8 surfType)
switch(surfType)
case SURFACE_GLASS:
case SURFACE_TRANSPARENT_CLOTH:
+#if defined(FIX_BUGS) || defined(GTA_PS2)
+ case SURFACE_METAL_CHAIN_FENCE:
+ case SURFACE_TRANSPARENT_STONE:
+ case SURFACE_SCAFFOLD_POLE:
+#endif
return true;
return false;
}
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 9f384048..7f8d8994 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -1941,6 +1941,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())) {
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(),
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 1556731b..2e3e0f6e 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -7,6 +7,7 @@
#include "Clock.h"
#include "Text.h"
#include "World.h"
+#include "Timer.h"
eLevelName CTheZones::m_CurrLevel;
CZone *CTheZones::m_pPlayersZone;
@@ -122,6 +123,10 @@ CTheZones::Init(void)
void
CTheZones::Update(void)
{
+#ifdef SQUEEZE_PERFORMANCE
+ if (CTimer::GetFrameCounter() % 5 != 0)
+ return;
+#endif
CVector pos;
pos = FindPlayerCoors();
m_pPlayersZone = FindSmallestZonePosition(&pos);
diff --git a/src/core/common.h b/src/core/common.h
index ebb3acb0..e876c4ec 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -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
diff --git a/src/core/config.h b/src/core/config.h
index 94a35782..43fc54fa 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -158,7 +158,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
@@ -170,6 +170,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
@@ -282,4 +286,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 \ No newline at end of file
+//#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 \ No newline at end of file
diff --git a/src/core/main.cpp b/src/core/main.cpp
index a1c64a6d..b63688ec 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -816,7 +816,9 @@ RenderScene(void)
DefinedState();
CWaterLevel::RenderWater();
CRenderer::RenderFadingInEntities();
+#ifndef SQUEEZE_PERFORMANCE
CRenderer::RenderVehiclesButNotBoats();
+#endif
CWeather::RenderRainStreaks();
}
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 8c0020d0..f9be4b51 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -457,9 +457,7 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); });
DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, 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);
diff --git a/src/core/vu0Collision.dsm b/src/core/vu0Collision.dsm
new file mode 100644
index 00000000..657c8b81
--- /dev/null
+++ b/src/core/vu0Collision.dsm
@@ -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
diff --git a/src/core/vu0Collision_1.s b/src/core/vu0Collision_1.s
new file mode 100644
index 00000000..055c8640
--- /dev/null
+++ b/src/core/vu0Collision_1.s
@@ -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:
diff --git a/src/core/vu0Collision_2.s b/src/core/vu0Collision_2.s
new file mode 100644
index 00000000..716c29ac
--- /dev/null
+++ b/src/core/vu0Collision_2.s
@@ -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:
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index c849a5c4..e2d6b0e0 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -81,6 +81,7 @@ public:
m_matrix.pos.z += rhs.m_matrix.pos.z;
return *this;
}
+ CMatrix& operator*=(CMatrix const &rhs);
CVector &GetPosition(void){ return *(CVector*)&m_matrix.pos; }
CVector &GetRight(void) { return *(CVector*)&m_matrix.right; }
diff --git a/src/math/VuVector.h b/src/math/VuVector.h
new file mode 100644
index 00000000..f90818e0
--- /dev/null
+++ b/src/math/VuVector.h
@@ -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);
diff --git a/src/math/math.cpp b/src/math/math.cpp
index 0cfc2ce9..4792fdd0 100644
--- a/src/math/math.cpp
+++ b/src/math/math.cpp
@@ -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
CVector2D::Normalise(void)
{
@@ -87,6 +202,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:
@@ -117,6 +233,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,
@@ -126,6 +243,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;
@@ -145,9 +263,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,
@@ -179,6 +306,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;
}
}
diff --git a/src/peds/CopPed.cpp b/src/peds/CopPed.cpp
index 6d106b0e..f289697e 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -45,7 +45,7 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 50.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
- m_wepAccuracy = 64;
+ m_wepAccuracy = 68;
break;
case COP_ARMY:
SetModelIndex(MI_ARMY);
@@ -479,7 +479,7 @@ CCopPed::CopAI(void)
SetAttack(playerOrHisVeh);
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
}
- SetAttackTimer(CGeneral::GetRandomNumberInRange(100, 300));
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 300));
}
SetMoveState(PEDMOVE_STILL);
}
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index 1357907d..0756df38 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -1104,7 +1104,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) {
@@ -1117,6 +1121,13 @@ CPopulation::ManagePopulation(void)
}
float dist = (ped->GetPosition() - playerPos).Magnitude2D();
+#ifdef SQUEEZE_PERFORMANCE
+ if (dist > 50.f)
+ ped->bUsesCollision = false;
+ else
+ ped->bUsesCollision = true;
+#endif
+
bool pedIsFarAway = false;
if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist
|| (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index f86801bf..690a1d3f 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -152,9 +152,9 @@ void CMovingThings::Shutdown()
void CMovingThings::Update()
{
- const int TIME_SPAN = 64; // frames to process all aMovingThings
-
int16 i;
+#ifndef SQUEEZE_PERFORMANCE
+ const int TIME_SPAN = 64; // frames to process all aMovingThings
int block = CTimer::GetFrameCounter() % TIME_SPAN;
@@ -167,6 +167,7 @@ void CMovingThings::Update()
if (aMovingThings[i].m_nHidden == 0)
aMovingThings[i].Update();
}
+#endif
for (i = 0; i < ARRAY_SIZE(aScrollBars); ++i)
{
diff --git a/src/render/Font.h b/src/render/Font.h
index 9b4e7132..48f5703d 100644
--- a/src/render/Font.h
+++ b/src/render/Font.h
@@ -68,8 +68,8 @@ class CFont
static int16 Size[MAX_FONTS][193];
#endif
static int16 NewLine;
- static CSprite2d Sprite[MAX_FONTS];
public:
+ static CSprite2d Sprite[MAX_FONTS];
static CFontDetails Details;
static void Initialise(void);
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 88d412c9..717021a7 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -73,8 +73,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;
diff --git a/src/render/Rubbish.h b/src/render/Rubbish.h
index 2be592fe..37f895f3 100644
--- a/src/render/Rubbish.h
+++ b/src/render/Rubbish.h
@@ -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
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp
index c169c351..8c892be3 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/Shadows.cpp
@@ -458,7 +458,7 @@ CShadows::StoreShadowForCar(CAutomobile *pCar)
if ( CTimeCycle::GetShadowStrength() != 0 )
{
CVector CarPos = pCar->GetPosition();
- float fDistToCamSqr = (CarPos - TheCamera.GetPosition()).MagnitudeSqr();
+ float fDistToCamSqr = (CarPos - TheCamera.GetPosition()).MagnitudeSqr2D();
if ( CCutsceneMgr::IsRunning() )
fDistToCamSqr /= SQR(TheCamera.LODDistMultiplier) * 4.0f;
@@ -1027,7 +1027,9 @@ CShadows::CastShadowEntity(CEntity *pEntity, float fStartX, float fStartY, floa
CColTrianglePlane *pColTriPlanes = pCol->trianglePlanes;
ASSERT(pColTriPlanes != NULL);
- if ( Abs(pColTriPlanes[i].normal.z) > 0.1f )
+ CVector normal;
+ pColTriPlanes[i].GetNormal(normal);
+ if ( Abs(normal.z) > 0.1f )
{
CColTriangle *pColTri = pCol->triangles;
ASSERT(pColTri != NULL);
@@ -1578,40 +1580,41 @@ CStaticShadow::Free(void)
void
CShadows::CalcPedShadowValues(CVector vecLightDir,
- float *pfDisplacementX, float *pfDisplacementY,
float *pfFrontX, float *pfFrontY,
- float *pfSideX, float *pfSideY)
+ float *pfSideX, float *pfSideY,
+ float *pfDisplacementX, float *pfDisplacementY)
{
- ASSERT(pfDisplacementX != NULL);
- ASSERT(pfDisplacementY != NULL);
- ASSERT(pfFrontX != NULL);
- ASSERT(pfFrontY != NULL);
- ASSERT(pfSideX != NULL);
- ASSERT(pfSideY != NULL);
+ ASSERT(pfFrontX != nil);
+ ASSERT(pfFrontY != nil);
+ ASSERT(pfSideX != nil);
+ ASSERT(pfSideY != nil);
+ ASSERT(pfDisplacementX != nil);
+ ASSERT(pfDisplacementY != nil);
- *pfDisplacementX = -vecLightDir.x;
- *pfDisplacementY = -vecLightDir.y;
+ *pfFrontX = -vecLightDir.x;
+ *pfFrontY = -vecLightDir.y;
- float fDist = Sqrt(*pfDisplacementY * *pfDisplacementY + *pfDisplacementX * *pfDisplacementX);
+ float fDist = Sqrt(*pfFrontY * *pfFrontY + *pfFrontX * *pfFrontX);
float fMult = (fDist + 1.0f) / fDist;
- *pfDisplacementX *= fMult;
- *pfDisplacementY *= fMult;
-
- *pfFrontX = -vecLightDir.y / fDist;
- *pfFrontY = vecLightDir.x / fDist;
+ *pfFrontX *= fMult;
+ *pfFrontY *= fMult;
- *pfSideX = -vecLightDir.x;
- *pfSideY = -vecLightDir.y;
+ *pfSideX = -vecLightDir.y / fDist;
+ *pfSideY = vecLightDir.x / fDist;
- *pfDisplacementX /= 2;
- *pfDisplacementY /= 2;
+ *pfDisplacementX = -vecLightDir.x;
+ *pfDisplacementY = -vecLightDir.y;
*pfFrontX /= 2;
*pfFrontY /= 2;
*pfSideX /= 2;
*pfSideY /= 2;
+
+ *pfDisplacementX /= 2;
+ *pfDisplacementY /= 2;
+
}
void
@@ -1656,22 +1659,22 @@ CShadows::RenderExtraPlayerShadows(void)
vecLight.y *= fInv;
vecLight.z *= fInv;
- float fDisplacementX, fDisplacementY, fFrontX, fFrontY, fSideX, fSideY;
+ float fFrontX, fFrontY, fSideX, fSideY, fDisplacementX, fDisplacementY;
CalcPedShadowValues(vecLight,
- &fDisplacementX, &fDisplacementY,
- &fFrontX, &fFrontY,
- &fSideX, &fSideY);
+ &fFrontX, &fFrontY,
+ &fSideX, &fSideY,
+ &fDisplacementX, &fDisplacementY);
CVector shadowPos = FindPlayerCoors();
- shadowPos.x += fSideX;
- shadowPos.y += fSideY;
+ shadowPos.x += fDisplacementX;
+ shadowPos.y += fDisplacementY;
StoreShadowToBeRendered(SHADOWTYPE_DARK, gpShadowPedTex, &shadowPos,
- fDisplacementX, fDisplacementY,
fFrontX, fFrontY,
+ fSideX, fSideY,
nColorStrength, 0, 0, 0,
4.0f, false, 1.0f);
}
@@ -1768,7 +1771,7 @@ CShadows::RenderIndicatorShadow(uint32 nID, uint8 ShadowType, RwTexture *pTextur
{
ASSERT(pPosn != NULL);
- C3dMarkers::PlaceMarkerSet(nID, _TODOCONST(4), *pPosn, Max(fFrontX, -fSideY),
+ C3dMarkers::PlaceMarkerSet(nID, MARKERTYPE_CYLINDER, *pPosn, Max(fFrontX, -fSideY),
0, 128, 255, 128,
2048, 0.2f, 0);
}
diff --git a/src/render/Shadows.h b/src/render/Shadows.h
index 63aaaaf2..8c909df3 100644
--- a/src/render/Shadows.h
+++ b/src/render/Shadows.h
@@ -128,21 +128,12 @@ 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);
@@ -166,7 +157,7 @@ public:
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 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);
diff --git a/src/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index 52b85018..453ed004 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/Sprite2d.cpp
@@ -4,6 +4,7 @@
#include "Draw.h"
#include "Camera.h"
#include "Sprite2d.h"
+#include "Font.h"
RwIm2DVertex CSprite2d::maVertices[8];
float CSprite2d::RecipNearClip;
@@ -27,14 +28,18 @@ CSprite2d::InitPerFrame(void)
mCurrentBank = 0;
for(i = 0; i < 10; i++)
mCurrentSprite[i] = 0;
+#ifndef SQUEEZE_PERFORMANCE
for(i = 0; i < 10; i++)
mpBankTextures[i] = nil;
+#endif
}
int32
CSprite2d::GetBank(int32 n, RwTexture *tex)
{
+#ifndef SQUEEZE_PERFORMANCE
mpBankTextures[mCurrentBank] = tex;
+#endif
mCurrentSprite[mCurrentBank] = 0;
mBankStart[mCurrentBank+1] = mBankStart[mCurrentBank] + n;
return mCurrentBank++;
@@ -59,8 +64,12 @@ CSprite2d::DrawBank(int32 bank)
{
if(mCurrentSprite[bank] == 0)
return;
+#ifndef SQUEEZE_PERFORMANCE
RwRenderStateSet(rwRENDERSTATETEXTURERASTER,
mpBankTextures[bank] ? RwTextureGetRaster(mpBankTextures[bank]) : nil);
+#else
+ CFont::Sprite[bank].SetRenderState();
+#endif
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
RwIm2DRenderPrimitive(rwPRIMTYPETRILIST, &maBankVertices[6*mBankStart[bank]], 6*mCurrentSprite[bank]);
diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp
index 26fc459d..15dde011 100644
--- a/src/weapons/BulletInfo.cpp
+++ b/src/weapons/BulletInfo.cpp
@@ -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
bool bAddSound = true;
bPlayerSniperBullet = false;
for (int i = 0; i < NUM_BULLETS; i++) {
@@ -84,8 +99,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;
}
else {
@@ -134,6 +156,9 @@ void CBulletInfo::Update(void)
}
}
pBullet->m_bInUse = false;
+#ifdef SQUEEZE_PERFORMANCE
+ bulletInfoInUse--;
+#endif
vecNewPos = point.point;
}
}
@@ -148,6 +173,9 @@ void CBulletInfo::Update(void)
}
#ifdef FIX_BUGS
pBullet->m_bInUse = false;
+#ifdef SQUEEZE_PERFORMANCE
+ bulletInfoInUse--;
+#endif
vecNewPos = point.point;
#endif
}
@@ -167,6 +195,9 @@ void CBulletInfo::Update(void)
}
#ifdef FIX_BUGS
pBullet->m_bInUse = false;
+#ifdef SQUEEZE_PERFORMANCE
+ bulletInfoInUse--;
+#endif
vecNewPos = point.point;
#endif
}
@@ -217,8 +248,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
+ }
}
}
diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp
index 47bc65ac..b56e3a29 100644
--- a/src/weapons/ProjectileInfo.cpp
+++ b/src/weapons/ProjectileInfo.cpp
@@ -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
@@ -154,6 +162,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]);
@@ -165,6 +177,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);
@@ -192,6 +207,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;
@@ -200,6 +220,10 @@ CProjectileInfo::Update()
gaProjectileInfo[i].m_pSource = nil;
if (ms_apProjectile[i] == nil) {
+#ifdef SQUEEZE_PERFORMANCE
+ projectileInUse--;
+#endif
+
gaProjectileInfo[i].m_bInUse = false;
continue;
}
@@ -252,6 +276,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];
@@ -266,8 +294,17 @@ CProjectileInfo::IsProjectileInRange(float x1, float x2, float y1, float y2, flo
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];
@@ -278,12 +315,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];
diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp
index f09ae052..c0ab9ac1 100644
--- a/src/weapons/ShotInfo.cpp
+++ b/src/weapons/ShotInfo.cpp
@@ -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