Merge branch 'miami' of https://github.com/GTAmodding/re3 into miami-wiiu

This commit is contained in:
GaryOderNichts 2021-07-15 19:30:35 +02:00
commit f348ee2532
187 changed files with 36132 additions and 6727 deletions

1
.gitignore vendored
View File

@ -355,6 +355,7 @@ vendor/glfw-3.3.2.bin.WIN64/
sdk/
codewarrior/reVC.mcp
codewarrior/reVC_Data/
codewarrior/Release/
codewarrior/Debug/

View File

@ -14,29 +14,29 @@ To build the channel edit `CHANNEL_BUILD := 0` to `CHANNEL_BUILD := 1` in the `M
# Original README
[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGTAmodding%2Fre3%2Fbadge%3Fref%3Dmiami&style=flat)](https://actions-badge.atrox.dev/GTAmodding/re3/goto?ref=miami)
<a href="https://discord.gg/ERYg58ttcE"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
<a href="https://discord.gg/RFNbjsUMGg"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
## Intro
In this repository you'll find the fully reversed source code for GTA III ([master](https://github.com/GTAmodding/re3/tree/master/) branch) and GTA VC ([miami](https://github.com/GTAmodding/re3/tree/miami/) branch).
It has been tested and works on Windows, Linux and FreeBSD, on x86, amd64, arm and arm64.\
It has been tested and works on Windows, Linux, MacOS and FreeBSD, on x86, amd64, arm and arm64.\
Rendering is handled either by original RenderWare (D3D8)
or the reimplementation [librw](https://github.com/aap/librw) (D3D9, OpenGL 2.1 or above, OpenGL ES 2.0 or above).\
Audio is done with MSS (using dlls from original GTA) or OpenAL.
We cannot build for PS2 or Xbox yet. If you're interested in doing so, get in touch with us.
## How can I try it?
## Installation
- reVC requires game assets to work, so you **must** own [a copy of GTA Vice City](https://store.steampowered.com/app/12110/Grand_Theft_Auto_Vice_City/).
- Build reVC or download the latest nightly build:
- Build reVC or download the latest build:
- [Windows D3D9 MSS 32bit](https://nightly.link/GTAmodding/re3/workflows/reVC_msvc_x86/miami/reVC_Release_win-x86-librw_d3d9-mss.zip)
- [Windows D3D9 64bit](https://nightly.link/GTAmodding/re3/workflows/reVC_msvc_amd64/miami/reVC_Release_win-amd64-librw_d3d9-oal.zip)
- [Windows OpenGL 64bit](https://nightly.link/GTAmodding/re3/workflows/reVC_msvc_amd64/miami/reVC_Release_win-amd64-librw_gl3_glfw-oal.zip)
- [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/ubuntu-latest-gl3.zip)
- [MacOS 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/macos-latest-gl3.zip)
- Extract the downloaded zip over your GTA VC directory and run reVC. The zip includes the gamefiles and in case of OpenAL the required dlls.
- [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/ubuntu-18.04-gl3.zip)
- [MacOS 64bit x86-64](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/macos-latest-gl3.zip)
- Extract the downloaded zip over your GTA VC directory and run reVC. The zip includes the binary, updated and additional gamefiles and in case of OpenAL the required dlls.
## Screenshots
@ -120,6 +120,12 @@ conan build .. -if build -bf build -pf package
```
</details>
<details><summary>MacOS Premake</summary>
For MacOS using premake, proceed: [Building on MacOS](https://github.com/GTAmodding/re3/wiki/Building-on-MacOS)
</details>
<details><summary>FreeBSD</summary>
For FreeBSD using premake, proceed: [Building on FreeBSD](https://github.com/GTAmodding/re3/wiki/Building-on-FreeBSD)
@ -137,7 +143,7 @@ Microsoft recently discontinued its downloads of the DX9 SDK. You can download a
**If you choose OpenAL on Windows** You must read [Running OpenAL build on Windows](https://github.com/GTAmodding/re3/wiki/Running-OpenAL-build-on-Windows).
</details>
> :information_source: premake has an `--lto` option if you want the project to be compiled with Link Time Optimization.
> :information_source: premake has an `--with-lto` option if you want the project to be compiled with Link Time Optimization.
> :information_source: There are various settings in [config.h](https://github.com/GTAmodding/re3/tree/miami/src/core/config.h), you may want to take a look there.

Binary file not shown.

16066
codewarrior/reVC.mcp.xml Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
gamefiles/TEXT/russian.gxt Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -28,8 +28,18 @@ newoption {
}
newoption {
trigger = "lto",
description = "Use link time optimization"
trigger = "with-lto",
description = "Build with link time optimization"
}
newoption {
trigger = "no-git-hash",
description = "Don't print git commit hash into binary"
}
newoption {
trigger = "no-full-paths",
description = "Don't print full paths into binary"
}
if(_OPTIONS["with-librw"]) then
@ -58,7 +68,7 @@ end
workspace "reVC"
language "C++"
configurations { "Debug", "Release", "Vanilla" }
configurations { "Debug", "Release" }
startproject "reVC"
location "build"
symbols "Full"
@ -70,6 +80,7 @@ workspace "reVC"
end
filter { "system:windows" }
configurations { "Vanilla" }
platforms {
"win-x86-RW34_d3d8-mss",
"win-x86-librw_d3d9-mss",
@ -109,13 +120,10 @@ workspace "reVC"
filter "configurations:not Debug"
defines { "NDEBUG" }
optimize "Speed"
if(_OPTIONS["lto"]) then
if(_OPTIONS["with-lto"]) then
flags { "LinkTimeOptimization" }
end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter { "platforms:win*" }
system "windows"
@ -137,12 +145,18 @@ workspace "reVC"
filter { "platforms:*arm*" }
architecture "ARM"
filter { "platforms:macosx-arm64-*" }
filter { "platforms:macosx-arm64-*", "files:**.cpp"}
buildoptions { "-target", "arm64-apple-macos11", "-std=gnu++14" }
filter { "platforms:macosx-amd64-*" }
filter { "platforms:macosx-arm64-*", "files:**.c"}
buildoptions { "-target", "arm64-apple-macos11" }
filter { "platforms:macosx-amd64-*", "files:**.cpp"}
buildoptions { "-target", "x86_64-apple-macos10.12", "-std=gnu++14" }
filter { "platforms:macosx-amd64-*", "files:**.c"}
buildoptions { "-target", "x86_64-apple-macos10.12" }
filter { "platforms:*librw_d3d9*" }
defines { "RW_D3D9" }
if(not _OPTIONS["with-librw"]) then
@ -202,8 +216,14 @@ project "librw"
includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" }
filter "platforms:macosx*"
-- Support MacPorts and Homebrew
-- Support MacPorts and Homebrew
filter "platforms:macosx-arm64-*"
includedirs { "/opt/local/include" }
includedirs {"/opt/homebrew/include" }
libdirs { "/opt/local/lib" }
libdirs { "/opt/homebrew/lib" }
filter "platforms:macosx-amd64-*"
includedirs { "/opt/local/include" }
includedirs {"/usr/local/include" }
libdirs { "/opt/local/lib" }
@ -253,7 +273,11 @@ project "reVC"
files { addSrcFiles("src/vehicles") }
files { addSrcFiles("src/weapons") }
files { addSrcFiles("src/extras") }
files { "src/extras/GitSHA1.cpp" } -- this won't be in repo in first build
if(not _OPTIONS["no-git-hash"]) then
files { "src/extras/GitSHA1.cpp" } -- this won't be in repo in first build
else
removefiles { "src/extras/GitSHA1.cpp" } -- but it will be everytime after
end
includedirs { "src" }
includedirs { "src/animation" }
@ -279,12 +303,19 @@ project "reVC"
includedirs { "src/weapons" }
includedirs { "src/extras" }
if(not _OPTIONS["no-git-hash"]) then
defines { "USE_OUR_VERSIONING" }
end
if _OPTIONS["with-opus"] then
includedirs { "vendor/ogg/include" }
includedirs { "vendor/opus/include" }
includedirs { "vendor/opusfile/include" }
end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter "platforms:*mss"
defines { "AUDIO_MSS" }
includedirs { "vendor/milessdk/include" }
@ -314,14 +345,22 @@ project "reVC"
linkoptions "/SAFESEH:NO"
characterset ("MBCS")
targetextension ".exe"
if(_OPTIONS["no-full-paths"]) then
usefullpaths "off"
linkoptions "/PDBALTPATH:%_PDB%"
end
if(_OPTIONS["with-librw"]) then
-- external librw is dynamic
staticruntime "on"
end
prebuildcommands { '"%{prj.location}..\\printHash.bat" "%{prj.location}..\\src\\extras\\GitSHA1.cpp"' }
if(not _OPTIONS["no-git-hash"]) then
prebuildcommands { '"%{prj.location}..\\printHash.bat" "%{prj.location}..\\src\\extras\\GitSHA1.cpp"' }
end
filter "platforms:not win*"
prebuildcommands { '"%{prj.location}/../printHash.sh" "%{prj.location}/../src/extras/GitSHA1.cpp"' }
if(not _OPTIONS["no-git-hash"]) then
prebuildcommands { '"%{prj.location}/../printHash.sh" "%{prj.location}/../src/extras/GitSHA1.cpp"' }
end
filter "platforms:win*glfw*"
staticruntime "off"
@ -342,13 +381,19 @@ project "reVC"
libdirs { "vendor/openal-soft/libs/Win64" }
filter "platforms:linux*oal"
links { "openal", "mpg123", "sndfile", "pthread" }
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
filter "platforms:bsd*oal"
links { "openal", "mpg123", "sndfile", "pthread" }
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
filter "platforms:macosx*oal"
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:macosx-arm64-*oal"
includedirs { "/opt/homebrew/opt/openal-soft/include" }
libdirs { "/opt/homebrew/opt/openal-soft/lib" }
filter "platforms:macosx-amd64-*oal"
includedirs { "/usr/local/opt/openal-soft/include" }
libdirs { "/usr/local/opt/openal-soft/lib" }
@ -400,10 +445,18 @@ project "reVC"
includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" }
filter "platforms:macosx*gl3_glfw*"
filter "platforms:macosx-arm64-*gl3_glfw*"
links { "glfw" }
linkoptions { "-framework OpenGL" }
includedirs { "/opt/local/include" }
includedirs { "/usr/local/include" }
includedirs {"/opt/homebrew/include" }
libdirs { "/opt/local/lib" }
libdirs { "/opt/homebrew/lib" }
filter "platforms:macosx-amd64-*gl3_glfw*"
links { "glfw" }
linkoptions { "-framework OpenGL" }
includedirs { "/opt/local/include" }
includedirs {"/usr/local/include" }
libdirs { "/opt/local/lib" }
libdirs { "/usr/local/lib" }

View File

@ -1,12 +1,14 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
if [ -z "${1}" ]
then
printf "%s\n" "Input the path to the file for writing the commit hash to."
else
printf "%s" "#define GIT_SHA1 \"" > $1
> $1
if (command -v "git" >/dev/null) then
git rev-parse --short HEAD | tr -d '\n' >> $1
fi
echo -n "#define GIT_SHA1 \"" > $1
if (command -v "git" >/dev/null) then
git rev-parse --short HEAD | tr -d '\n' >> $1
printf "%s\n" "\"" >> $1
printf "%s\n" "const char* g_GIT_SHA1 = GIT_SHA1;" >> $1
fi
echo "\"" >> $1
echo "const char* g_GIT_SHA1 = GIT_SHA1;" >> $1

View File

@ -50,6 +50,7 @@ if(LIBRW_PLATFORM_D3D9)
endif()
target_compile_definitions(${EXECUTABLE} PRIVATE CMAKE_BUILD)
target_compile_definitions(${EXECUTABLE} PRIVATE USE_OUR_VERSIONING)
if(${PROJECT}_AUDIO STREQUAL "OAL")
find_package(OpenAL REQUIRED)

View File

@ -158,7 +158,7 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio
void
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{
bool distCalculated = false;
bool8 distCalculated = FALSE;
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
@ -168,20 +168,17 @@ cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 coun
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 7;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
}
@ -311,17 +308,16 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
if(counter >= 255) counter = 28;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nReleasingVolumeModificator = 11;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
RESET_LOOP_OFFSETS
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_bReleasingSoundFlag = TRUE;
m_sQueueSample.m_bReverbFlag = TRUE;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
}
@ -332,13 +328,12 @@ void
cAudioManager::ServiceCollisions()
{
int i, j;
bool abRepeatedCollision1[NUMAUDIOCOLLISIONS];
bool abRepeatedCollision2[NUMAUDIOCOLLISIONS];
bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
abRepeatedCollision1[i] = abRepeatedCollision2[i] = false;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++) abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
@ -348,8 +343,8 @@ cAudioManager::ServiceCollisions()
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
) {
abRepeatedCollision1[index] = true;
abRepeatedCollision2[j] = true;
abRepeatedCollision1[index] = TRUE;
abRepeatedCollision2[j] = TRUE;
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
break;

File diff suppressed because it is too large Load Diff

View File

@ -14,21 +14,17 @@
cAudioManager AudioManager;
const int channels = ARRAY_SIZE(AudioManager.m_asActiveSamples);
const int policeChannel = channels + 1;
const int allChannels = channels + 2;
#define SPEED_OF_SOUND 343.f
#define TIME_SPENT 40
cAudioManager::cAudioManager()
{
m_bIsInitialised = false;
m_bReverb = true;
m_bIsInitialised = FALSE;
m_bReverb = TRUE;
field_6 = 0;
m_fSpeedOfSound = SPEED_OF_SOUND / TIME_SPENT;
m_nTimeSpent = TIME_SPENT;
m_nActiveSamples = NUM_SOUNDS_SAMPLES_SLOTS;
m_nActiveSamples = NUM_CHANNELS_GENERIC;
m_nActiveSampleQueue = 1;
ClearRequestedQueue();
m_nActiveSampleQueue = 0;
@ -36,16 +32,16 @@ cAudioManager::cAudioManager()
ClearActiveSamples();
GenerateIntegerRandomNumberTable();
field_4 = 0;
m_bDynamicAcousticModelingStatus = true;
m_bDynamicAcousticModelingStatus = TRUE;
for (int i = 0; i < NUM_AUDIOENTITIES; i++) {
m_asAudioEntities[i].m_bIsUsed = false;
m_asAudioEntities[i].m_bIsUsed = FALSE;
m_anAudioEntityIndices[i] = NUM_AUDIOENTITIES;
}
m_nAudioEntitiesTotal = 0;
m_FrameCounter = 0;
m_bFifthFrameFlag = false;
m_bTimerJustReset = false;
m_bFifthFrameFlag = FALSE;
m_bTimerJustReset = FALSE;
m_nTimer = 0;
}
@ -83,7 +79,7 @@ cAudioManager::Terminate()
MusicManager.Terminate();
for (uint32 i = 0; i < NUM_AUDIOENTITIES; i++) {
m_asAudioEntities[i].m_bIsUsed = false;
m_asAudioEntities[i].m_bIsUsed = FALSE;
m_anAudioEntityIndices[i] = ARRAY_SIZE(m_anAudioEntityIndices);
}
@ -98,7 +94,7 @@ cAudioManager::Terminate()
SampleManager.Terminate();
m_bIsInitialised = false;
m_bIsInitialised = FALSE;
PostTerminateGameSpecificShutdown();
}
}
@ -110,7 +106,7 @@ cAudioManager::Service()
if (m_bTimerJustReset) {
ResetAudioLogicTimers(m_nTimer);
MusicManager.ResetTimers(m_nTimer);
m_bTimerJustReset = false;
m_bTimerJustReset = FALSE;
}
if (m_bIsInitialised) {
m_nPreviousUserPause = m_nUserPause;
@ -132,8 +128,8 @@ cAudioManager::CreateEntity(eAudioType type, void *entity)
return AEHANDLE_ERROR_BADAUDIOTYPE;
for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) {
if (!m_asAudioEntities[i].m_bIsUsed) {
m_asAudioEntities[i].m_bIsUsed = true;
m_asAudioEntities[i].m_bStatus = false;
m_asAudioEntities[i].m_bIsUsed = TRUE;
m_asAudioEntities[i].m_bStatus = FALSE;
m_asAudioEntities[i].m_nType = type;
m_asAudioEntities[i].m_pEntity = entity;
m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_NO_SOUND;
@ -152,7 +148,7 @@ void
cAudioManager::DestroyEntity(int32 id)
{
if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed) {
m_asAudioEntities[id].m_bIsUsed = false;
m_asAudioEntities[id].m_bIsUsed = FALSE;
for (int32 i = 0; i < m_nAudioEntitiesTotal; ++i) {
if (id == m_anAudioEntityIndices[i]) {
if (i < NUM_AUDIOENTITIES - 1)
@ -165,7 +161,7 @@ cAudioManager::DestroyEntity(int32 id)
}
void
cAudioManager::SetEntityStatus(int32 id, uint8 status)
cAudioManager::SetEntityStatus(int32 id, bool8 status)
{
if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed)
m_asAudioEntities[id].m_bStatus = status;
@ -193,7 +189,7 @@ cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
}
} else {
int32 i = 0;
while (true) {
while (TRUE) {
if (i >= entity.m_AudioEvents) {
if (entity.m_AudioEvents < ARRAY_SIZE(entity.m_awAudioEvent)) {
entity.m_awAudioEvent[i] = sound;
@ -246,7 +242,7 @@ cAudioManager::SetEffectsFadeVol(uint8 volume) const
}
void
cAudioManager::SetMonoMode(uint8 mono)
cAudioManager::SetMonoMode(bool8 mono)
{
SampleManager.SetMonoMode(mono);
}
@ -261,7 +257,7 @@ void
cAudioManager::ResetTimers(uint32 time)
{
if (m_bIsInitialised) {
m_bTimerJustReset = true;
m_bTimerJustReset = TRUE;
m_nTimer = time;
ClearRequestedQueue();
if (m_nActiveSampleQueue) {
@ -276,11 +272,11 @@ cAudioManager::ResetTimers(uint32 time)
ClearActiveSamples();
ClearMissionAudio(0);
ClearMissionAudio(1);
SampleManager.StopChannel(policeChannel);
SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload();
m_bIsPlayerShutUp = false;
m_bIsPlayerShutUp = FALSE;
#ifdef AUDIO_OAL
SampleManager.Service();
#endif
@ -335,7 +331,7 @@ cAudioManager::Get3DProviderName(uint8 id) const
if (!m_bIsInitialised)
return nil;
#ifdef AUDIO_OAL
id = clamp(id, 0, SampleManager.GetNum3DProvidersAvailable() - 1);
id = Clamp(id, 0, SampleManager.GetNum3DProvidersAvailable() - 1);
#else
// We don't want that either since it will crash the game, but skipping for now
if (id >= SampleManager.GetNum3DProvidersAvailable())
@ -391,13 +387,13 @@ cAudioManager::SetSpeakerConfig(int32 conf) const
SampleManager.SetSpeakerConfig(conf);
}
bool
bool8
cAudioManager::IsMP3RadioChannelAvailable() const
{
if (m_bIsInitialised)
return SampleManager.IsMP3RadioChannelAvailable();
return false;
return FALSE;
}
void
@ -417,25 +413,25 @@ cAudioManager::ReacquireDigitalHandle() const
}
void
cAudioManager::SetDynamicAcousticModelingStatus(uint8 status)
cAudioManager::SetDynamicAcousticModelingStatus(bool8 status)
{
m_bDynamicAcousticModelingStatus = status!=0;
m_bDynamicAcousticModelingStatus = status;
}
bool
bool8
cAudioManager::CheckForAnAudioFileOnCD() const
{
return SampleManager.CheckForAnAudioFileOnCD();
}
uint8
char
cAudioManager::GetCDAudioDriveLetter() const
{
if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter();
return 0;
return '\0';
}
bool
bool8
cAudioManager::IsAudioInitialised() const
{
return m_bIsInitialised;
@ -444,9 +440,12 @@ cAudioManager::IsAudioInitialised() const
void
cAudioManager::ServiceSoundEffects()
{
#ifdef FIX_BUGS
if(CTimer::GetLogicalFramesPassed() != 0)
#endif
m_bFifthFrameFlag = (m_FrameCounter++ % 5) == 0;
if (m_nUserPause && !m_nPreviousUserPause) {
for (int32 i = 0; i < allChannels; i++)
for (int32 i = 0; i < NUM_CHANNELS; i++)
SampleManager.StopChannel(i);
ClearRequestedQueue();
@ -532,7 +531,7 @@ cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1,
if (dist != 0.0f) {
float speedOfSource = (dist / m_nTimeSpent) * speedMultiplier;
if (m_fSpeedOfSound > Abs(speedOfSource)) {
speedOfSource = clamp2(speedOfSource, 0.0f, 1.5f);
speedOfSource = Clamp2(speedOfSource, 0.0f, 1.5f);
newFreq = (oldFreq * m_fSpeedOfSound) / (speedOfSource + m_fSpeedOfSound);
}
}
@ -545,7 +544,7 @@ cAudioManager::RandomDisplacement(uint32 seed) const
{
int32 value;
static bool bPos = true;
static bool8 bPos = TRUE;
static uint32 Adjustment = 0;
if (!seed)
@ -576,7 +575,7 @@ cAudioManager::AddSampleToRequestedQueue()
{
int32 calculatedVolume;
uint8 sampleIndex;
bool bReflections;
bool8 bReflections;
if (m_sQueueSample.m_nSampleIndex < TOTAL_AUDIO_SAMPLES) {
calculatedVolume = m_sQueueSample.m_nReleasingVolumeModificator * (MAX_VOLUME - m_sQueueSample.m_nVolume);
@ -589,24 +588,24 @@ cAudioManager::AddSampleToRequestedQueue()
++m_SampleRequestQueuesStatus[m_nActiveSampleQueue];
}
m_sQueueSample.m_nCalculatedVolume = calculatedVolume;
m_sQueueSample.m_bLoopEnded = false;
m_sQueueSample.m_bLoopEnded = FALSE;
if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) {
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_bRequireReflection = FALSE;
m_sQueueSample.m_nLoopsRemaining = 0;
}
if (m_bDynamicAcousticModelingStatus && m_sQueueSample.m_nLoopCount) {
bReflections = m_sQueueSample.m_bRequireReflection;
} else {
bReflections = false;
bReflections = FALSE;
m_sQueueSample.m_nLoopsRemaining = 0;
}
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_bRequireReflection = FALSE;
if ( m_bReverb && m_sQueueSample.m_bIs2D )
m_sQueueSample.field_4C = 30;
if (!m_bDynamicAcousticModelingStatus)
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_bReverbFlag = FALSE;
m_asSamples[m_nActiveSampleQueue][sampleIndex] = m_sQueueSample;
@ -773,7 +772,12 @@ cAudioManager::UpdateReflections()
void
cAudioManager::AddReleasingSounds()
{
bool toProcess[44]; // why not 27?
// in case someone would want to increase it
#ifdef FIX_BUGS
bool8 toProcess[NUM_CHANNELS_GENERIC];
#else
bool8 toProcess[44];
#endif
int8 queue = m_nActiveSampleQueue == 0 ? 1 : 0;
@ -782,19 +786,19 @@ cAudioManager::AddReleasingSounds()
if (sample.m_bLoopEnded)
continue;
toProcess[i] = false;
toProcess[i] = FALSE;
for (int32 j = 0; j < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; j++) {
if (sample.m_nEntityIndex == m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][j]].m_nEntityIndex &&
sample.m_nCounter == m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][j]].m_nCounter) {
toProcess[i] = true;
toProcess[i] = TRUE;
break;
}
}
if (!toProcess[i]) {
if (sample.m_nCounter <= 255 || !sample.m_nLoopsRemaining) {
if (!sample.m_nReleasingVolumeDivider)
if (sample.m_nReleasingVolumeDivider == 0)
continue;
if (!sample.m_nLoopCount) {
if (sample.m_nLoopCount == 0) {
if (sample.m_nVolumeChange == -1) {
sample.m_nVolumeChange = sample.m_nVolume / sample.m_nReleasingVolumeDivider;
if (sample.m_nVolumeChange <= 0)
@ -806,12 +810,15 @@ cAudioManager::AddReleasingSounds()
}
sample.m_nVolume -= sample.m_nVolumeChange;
}
#ifdef FIX_BUGS
if(CTimer::GetLogicalFramesPassed() != 0)
#endif
--sample.m_nReleasingVolumeDivider;
if (m_bFifthFrameFlag) {
if (sample.m_nReleasingVolumeModificator < 20)
++sample.m_nReleasingVolumeModificator;
}
sample.m_bReleasingSoundFlag = false;
sample.m_bReleasingSoundFlag = FALSE;
}
memcpy(&m_sQueueSample, &sample, sizeof(tSound));
AddSampleToRequestedQueue();
@ -829,12 +836,12 @@ cAudioManager::ProcessActiveQueues()
uint8 vol;
uint8 offset;
float x;
bool flag;
bool missionState;
bool8 flag;
bool8 missionState;
for (int32 i = 0; i < m_nActiveSamples; i++) {
m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = false;
m_asActiveSamples[i].m_bIsProcessed = false;
m_asSamples[m_nActiveSampleQueue][i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bIsProcessed = FALSE;
}
for (int32 i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) {
tSound& sample = m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
@ -847,19 +854,19 @@ cAudioManager::ProcessActiveQueues()
if (m_FrameCounter & 1) {
if (!(j & 1)) {
flag = false;
flag = FALSE;
} else {
flag = true;
flag = TRUE;
}
} else if (j & 1) {
flag = false;
flag = FALSE;
} else {
flag = true;
flag = TRUE;
}
if (flag && !SampleManager.GetChannelUsedFlag(j)) {
sample.m_bLoopEnded = true;
m_asActiveSamples[j].m_bLoopEnded = true;
sample.m_bLoopEnded = TRUE;
m_asActiveSamples[j].m_bLoopEnded = TRUE;
m_asActiveSamples[j].m_nSampleIndex = NO_SAMPLE;
m_asActiveSamples[j].m_nEntityIndex = AEHANDLE_NONE;
continue;
@ -867,8 +874,8 @@ cAudioManager::ProcessActiveQueues()
if (!sample.m_nReleasingVolumeDivider)
sample.m_nReleasingVolumeDivider = 1;
}
sample.m_bIsProcessed = true;
m_asActiveSamples[j].m_bIsProcessed = true;
sample.m_bIsProcessed = TRUE;
m_asActiveSamples[j].m_bIsProcessed = TRUE;
sample.m_nVolumeChange = -1;
if (!sample.m_bReleasingSoundFlag) {
if (sample.m_bIs2D) {
@ -888,11 +895,11 @@ cAudioManager::ProcessActiveQueues()
sample.m_fSpeedMultiplier);
if (sample.m_nFrequency != m_asActiveSamples[j].m_nFrequency) {
m_asActiveSamples[j].m_nFrequency = clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
m_asActiveSamples[j].m_nFrequency = Clamp2((int32)sample.m_nFrequency, (int32)m_asActiveSamples[j].m_nFrequency, 6000);
SampleManager.SetChannelFrequency(j, m_asActiveSamples[j].m_nFrequency);
}
if (sample.m_nEmittingVolume != m_asActiveSamples[j].m_nEmittingVolume) {
vol = clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10);
vol = Clamp2((int8)sample.m_nEmittingVolume, (int8)m_asActiveSamples[j].m_nEmittingVolume, 10);
if (field_4) {
emittingVol = 2 * Min(63, vol);
@ -900,10 +907,10 @@ cAudioManager::ProcessActiveQueues()
emittingVol = vol;
}
missionState = false;
missionState = FALSE;
for (int32 k = 0; k < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); k++) {
if (m_sMissionAudio.m_bIsMobile[k]) {
missionState = true;
missionState = TRUE;
break;
}
}
@ -924,8 +931,8 @@ cAudioManager::ProcessActiveQueues()
SampleManager.SetChannelReverbFlag(j, sample.m_bReverbFlag);
break; //continue for i
}
sample.m_bIsProcessed = false;
m_asActiveSamples[j].m_bIsProcessed = false;
sample.m_bIsProcessed = FALSE;
m_asActiveSamples[j].m_bIsProcessed = FALSE;
//continue for j
}
}
@ -966,10 +973,10 @@ cAudioManager::ProcessActiveQueues()
}
if (SampleManager.InitialiseChannel(k, m_asActiveSamples[k].m_nSampleIndex, m_asActiveSamples[k].m_nBankIndex)) {
SampleManager.SetChannelFrequency(k, m_asActiveSamples[k].m_nFrequency);
bool isMobile = false;
bool8 isMobile = FALSE;
for (int32 l = 0; l < ARRAY_SIZE(m_sMissionAudio.m_bIsMobile); l++) {
if (m_sMissionAudio.m_bIsMobile[l]) {
isMobile = true;
isMobile = TRUE;
break;
}
}
@ -1000,8 +1007,8 @@ cAudioManager::ProcessActiveQueues()
SampleManager.SetChannel3DDistances(k, m_asActiveSamples[k].m_fSoundIntensity, 0.25f * m_asActiveSamples[k].m_fSoundIntensity);
SampleManager.StartChannel(k);
}
m_asActiveSamples[k].m_bIsProcessed = true;
sample.m_bIsProcessed = true;
m_asActiveSamples[k].m_bIsProcessed = TRUE;
sample.m_bIsProcessed = TRUE;
sample.m_nVolumeChange = -1;
break;
}
@ -1029,28 +1036,30 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_nCounter = 0;
m_asActiveSamples[i].m_nSampleIndex = NO_SAMPLE;
m_asActiveSamples[i].m_nBankIndex = INVALID_SFX_BANK;
m_asActiveSamples[i].m_bIs2D = false;
m_asActiveSamples[i].m_bIs2D = FALSE;
m_asActiveSamples[i].m_nReleasingVolumeModificator = 5;
m_asActiveSamples[i].m_nFrequency = 0;
m_asActiveSamples[i].m_nVolume = 0;
m_asActiveSamples[i].m_nEmittingVolume = 0;
m_asActiveSamples[i].m_fDistance = 0.0f;
m_asActiveSamples[i].m_bIsProcessed = false;
m_asActiveSamples[i].m_bLoopEnded = false;
m_asActiveSamples[i].m_bIsProcessed = FALSE;
m_asActiveSamples[i].m_bLoopEnded = FALSE;
m_asActiveSamples[i].m_nLoopCount = 1;
#ifndef GTA_PS2
m_asActiveSamples[i].m_nLoopStart = 0;
m_asActiveSamples[i].m_nLoopEnd = -1;
#endif
m_asActiveSamples[i].m_fSpeedMultiplier = 0.0f;
m_asActiveSamples[i].m_fSoundIntensity = 200.0f;
m_asActiveSamples[i].m_nOffset = 63;
m_asActiveSamples[i].m_bReleasingSoundFlag = false;
m_asActiveSamples[i].m_bReleasingSoundFlag = FALSE;
m_asActiveSamples[i].m_nCalculatedVolume = 0;
m_asActiveSamples[i].m_nReleasingVolumeDivider = 0;
m_asActiveSamples[i].m_nVolumeChange = -1;
m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f);
m_asActiveSamples[i].m_bReverbFlag = false;
m_asActiveSamples[i].m_bReverbFlag = FALSE;
m_asActiveSamples[i].m_nLoopsRemaining = 0;
m_asActiveSamples[i].m_bRequireReflection = false;
m_asActiveSamples[i].m_bRequireReflection = FALSE;
}
}
@ -1067,7 +1076,7 @@ void
cAudioManager::AdjustSamplesVolume()
{
for (int i = 0; i < m_SampleRequestQueuesStatus[m_nActiveSampleQueue]; i++) {
tSound *pSample = &m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i] + 1];
tSound *pSample = &m_asSamples[m_nActiveSampleQueue][m_abSampleQueueIndexTable[m_nActiveSampleQueue][i]];
if (!pSample->m_bIs2D)
pSample->m_nEmittingVolume = ComputeEmittingVolume(pSample->m_nEmittingVolume, pSample->m_fSoundIntensity, pSample->m_fDistance);

View File

@ -2,7 +2,7 @@
#include "audio_enums.h"
#include "AudioCollision.h"
#include "PoliceRadio.h"
#include "PolRadio.h"
#include "VehicleModelInfo.h"
#include "Vehicle.h"
@ -13,27 +13,29 @@ public:
int32 m_nCounter;
int32 m_nSampleIndex;
uint8 m_nBankIndex;
bool m_bIs2D;
bool8 m_bIs2D;
int32 m_nReleasingVolumeModificator;
uint32 m_nFrequency;
uint8 m_nVolume;
float m_fDistance;
int32 m_nLoopCount;
#ifndef GTA_PS2
int32 m_nLoopStart;
int32 m_nLoopEnd;
#endif
uint8 m_nEmittingVolume;
float m_fSpeedMultiplier;
float m_fSoundIntensity;
bool m_bReleasingSoundFlag;
bool8 m_bReleasingSoundFlag;
CVector m_vecPos;
bool m_bReverbFlag;
bool8 m_bReverbFlag;
uint8 m_nLoopsRemaining;
bool m_bRequireReflection; // Used for oneshots
bool8 m_bRequireReflection; // Used for oneshots
uint8 m_nOffset;
uint8 field_4C;
int32 m_nReleasingVolumeDivider;
bool m_bIsProcessed;
bool m_bLoopEnded;
bool8 m_bIsProcessed;
bool8 m_bLoopEnded;
int32 m_nCalculatedVolume;
int8 m_nVolumeChange;
};
@ -48,7 +50,7 @@ class tAudioEntity
public:
eAudioType m_nType;
void *m_pEntity;
bool m_bIsUsed;
bool8 m_bIsUsed;
uint8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
float m_afVolume[NUM_AUDIOENTITY_EVENTS];
@ -78,7 +80,7 @@ public:
uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS];
uint8 m_nActiveBank;
#ifdef GTA_PC
bool m_bDelay;
bool8 m_bDelay;
uint32 m_nDelayTimer;
#endif
@ -94,8 +96,8 @@ public:
m_nCommentsInBank[i] = 0;
m_nActiveBank = 0;
}
void Add(tPedComment *com); // done
void Process(); // done
void Add(tPedComment *com);
void Process();
};
VALIDATE_SIZE(cPedComments, 0x490);
@ -110,14 +112,14 @@ class cMissionAudio
{
public:
CVector m_vecPos[MISSION_AUDIO_SLOTS];
bool m_bPredefinedProperties[MISSION_AUDIO_SLOTS];
bool8 m_bPredefinedProperties[MISSION_AUDIO_SLOTS];
int32 m_nSampleIndex[MISSION_AUDIO_SLOTS];
uint8 m_nLoadingStatus[MISSION_AUDIO_SLOTS];
uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS];
bool m_bIsPlaying[MISSION_AUDIO_SLOTS];
bool8 m_bIsPlaying[MISSION_AUDIO_SLOTS];
int32 m_nMissionAudioCounter[MISSION_AUDIO_SLOTS];
bool m_bIsPlayed[MISSION_AUDIO_SLOTS];
bool m_bIsMobile[MISSION_AUDIO_SLOTS];
bool8 m_bIsPlayed[MISSION_AUDIO_SLOTS];
bool8 m_bIsMobile[MISSION_AUDIO_SLOTS];
};
VALIDATE_SIZE(cMissionAudio, 0x38);
@ -141,7 +143,7 @@ class CPed;
class cPedParams
{
public:
bool m_bDistanceCalculated;
bool8 m_bDistanceCalculated;
float m_fDistance;
CPed *m_pPed;
@ -157,7 +159,7 @@ class cVehicleParams
{
public:
int32 m_VehicleType;
bool m_bDistanceCalculated;
bool8 m_bDistanceCalculated;
float m_fDistance;
CVehicle *m_pVehicle;
cTransmission *m_pTransmission;
@ -193,22 +195,22 @@ enum {
class cAudioManager
{
public:
bool m_bIsInitialised;
bool8 m_bIsInitialised;
uint8 m_bReverb; // unused
bool m_bFifthFrameFlag;
bool8 m_bFifthFrameFlag;
uint8 m_nActiveSamples;
uint8 field_4; // unused
bool m_bDynamicAcousticModelingStatus;
bool8 m_bDynamicAcousticModelingStatus;
int8 field_6;
float m_fSpeedOfSound;
bool m_bTimerJustReset;
bool8 m_bTimerJustReset;
int32 m_nTimer;
tSound m_sQueueSample;
uint8 m_nActiveSampleQueue;
tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_CHANNELS_GENERIC];
uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_CHANNELS_GENERIC];
uint8 m_SampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS];
tSound m_asActiveSamples[NUM_SOUNDS_SAMPLES_SLOTS];
tSound m_asActiveSamples[NUM_CHANNELS_GENERIC];
tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES];
int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES];
int32 m_nAudioEntitiesTotal;
@ -217,11 +219,11 @@ public:
cAudioScriptObjectManager m_sAudioScriptObjectManager;
// miami
uint8 m_bIsPlayerShutUp;
bool8 m_bIsPlayerShutUp;
uint8 m_nPlayerMood;
uint32 m_nPlayerMoodTimer;
uint8 field_rest[4];
bool m_bGenericSfx;
bool8 m_bGenericSfx;
cPedComments m_sPedComments;
int32 m_nFireAudioEntity;
@ -249,34 +251,34 @@ public:
~cAudioManager();
// getters
uint32 GetFrameCounter() const { return m_FrameCounter; } // done
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; } // done
uint32 GetFrameCounter() const { return m_FrameCounter; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
int32 GetRandomNumberInRange(int32 idx, int32 low, int32 high) const { return (m_anRandomTable[idx] % (high - low + 1)) + low; }
bool IsMissionAudioSamplePlaying(uint8 slot) const; // { return m_sMissionAudio.m_nPlayStatus == 1; }
bool ShouldDuckMissionAudio(uint8 slot) const;
bool8 IsMissionAudioSamplePlaying(uint8 slot) const; // { return m_sMissionAudio.m_nPlayStatus == 1; }
bool8 ShouldDuckMissionAudio(uint8 slot) const;
// "Should" be in alphabetic order, except "getXTalkSfx"
void AddDetailsToRequestedOrderList(uint8 sample); // done (inlined in vc)
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool notLooping); // done
void AddReflectionsToRequestedQueue(); // done
void AddReleasingSounds(); // done
void AddSampleToRequestedQueue(); // done
void AgeCrimes(); // done (inlined in vc)
void AddDetailsToRequestedOrderList(uint8 sample); // inlined in vc
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
void AddReflectionsToRequestedQueue();
void AddReleasingSounds();
void AddSampleToRequestedQueue();
void AgeCrimes(); // inlined in vc
void CalculateDistance(bool &condition, float dist); // done
bool CheckForAnAudioFileOnCD() const; // done
void ClearActiveSamples(); // done
void ClearMissionAudio(uint8 slot); // done (inlined in vc)
void ClearRequestedQueue(); // done (inlined in vc)
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const; // done
int32 ComputePan(float, CVector *); // done
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; // done
int32 CreateEntity(eAudioType type, void *entity); // done
void CalculateDistance(bool8 &condition, float dist);
bool8 CheckForAnAudioFileOnCD() const;
void ClearActiveSamples();
void ClearMissionAudio(uint8 slot); // inlined in vc
void ClearRequestedQueue(); // inlined in vc
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const;
int32 ComputePan(float, CVector *);
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
int32 CreateEntity(eAudioType type, void *entity);
void DestroyAllGameCreatedEntities(); // done
void DestroyEntity(int32 id); // done (inlined in vc)
void DoPoliceRadioCrackle(); // done
void DestroyAllGameCreatedEntities();
void DestroyEntity(int32 id); // inlined in vc
void DoPoliceRadioCrackle();
// functions returning talk sfx,
// order from GetPedCommentSfx
@ -377,174 +379,191 @@ public:
uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
// end of functions returning talk sfx
void GenerateIntegerRandomNumberTable(); // done
char *Get3DProviderName(uint8 id) const; // done
uint8 GetCDAudioDriveLetter() const; // done
int8 GetCurrent3DProviderIndex() const; // done
int8 AutoDetect3DProviders() const; // done
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const; // done
float GetCollisionRatio(float a, float b, float c, float d) const; // done (inlined in vc)
float GetDistanceSquared(const CVector &v) const; // done (inlined in vc)
int32 GetJumboTaxiFreq() const; // done (inlined in vc)
uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done
int8 GetMissionScriptPoliceAudioPlayingStatus() const; // done
uint8 GetNum3DProvidersAvailable() const; // done
uint32 GetPedCommentSfx(CPed *ped, int32 sound); // done
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const; // done
void GenerateIntegerRandomNumberTable();
char *Get3DProviderName(uint8 id) const;
char GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const;
int8 AutoDetect3DProviders() const;
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const;
float GetCollisionRatio(float a, float b, float c, float d) const; // inlined in vc
float GetDistanceSquared(const CVector &v) const; // inlined in vc
int32 GetJumboTaxiFreq() const; // inlined in vc
uint8 GetMissionAudioLoadingStatus(uint8 slot) const;
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
uint8 GetNum3DProvidersAvailable() const;
uint32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, float gasPedalAudio, cTransmission *transmission,
float velocityChange); // done
float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange); // done
float velocityChange);
float GetVehicleNonDriveWheelSkidValue(CVehicle *veh, tWheelState wheelState, cTransmission *transmission, float velocityChange);
bool HasAirBrakes(int32 model) const; // done
bool8 HasAirBrakes(int32 model) const;
void Initialise(); // done
void InitialisePoliceRadio(); // done
void InitialisePoliceRadioZones(); // done
void InterrogateAudioEntities(); // done (inlined)
bool IsAudioInitialised() const; // done
bool IsMissionAudioSampleFinished(uint8 slot); // done
bool IsMP3RadioChannelAvailable() const; // done
void Initialise();
void InitialisePoliceRadio();
void InitialisePoliceRadioZones();
void InterrogateAudioEntities(); // inlined
bool8 IsAudioInitialised() const;
bool8 IsMissionAudioSampleFinished(uint8 slot);
bool8 IsMP3RadioChannelAvailable() const;
bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done
bool8 MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
void PlayLoadedMissionAudio(uint8 slot); // done
void PlayOneShot(int32 index, uint16 sound, float vol); // done
void PlaySuspectLastSeen(float x, float y, float z); // done
void PlayerJustGotInCar() const; // done
void PlayerJustLeftCar() const; // done
void PostInitialiseGameSpecificSetup(); // done
void PostTerminateGameSpecificShutdown(); // done
void PreInitialiseGameSpecificSetup() const; // done
void PreloadMissionAudio(uint8 slot, Const char *name); // done
void PreTerminateGameSpecificShutdown(); // done
void PlayLoadedMissionAudio(uint8 slot);
void PlayOneShot(int32 index, uint16 sound, float vol);
void PlaySuspectLastSeen(float x, float y, float z);
void PlayerJustGotInCar() const;
void PlayerJustLeftCar() const;
void PostInitialiseGameSpecificSetup();
void PostTerminateGameSpecificShutdown();
void PreInitialiseGameSpecificSetup() const;
void PreloadMissionAudio(uint8 slot, Const char *name);
void PreTerminateGameSpecificShutdown();
/// processX - main logic of adding new sounds
void ProcessActiveQueues(); // done
bool ProcessAirBrakes(cVehicleParams& params); // done
bool ProcessBoatEngine(cVehicleParams& params);
bool ProcessBoatMovingOverWater(cVehicleParams& params); //done
void ProcessActiveQueues();
bool8 ProcessAirBrakes(cVehicleParams& params);
bool8 ProcessBoatEngine(cVehicleParams& params);
bool8 ProcessBoatMovingOverWater(cVehicleParams& params);
#ifdef GTA_BRIDGE
void ProcessBridge(); // done(bcs not exists in VC)
void ProcessBridgeMotor(); // done(bcs not exists in VC)
void ProcessBridgeOneShots(); // done(bcs not exists in VC)
void ProcessBridgeWarning(); // done(bcs not exists in VC)
void ProcessBridge();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
void ProcessBridgeWarning();
#endif
bool ProcessCarBombTick(cVehicleParams& params); // done
void ProcessCarHeli(cVehicleParams& params); // done
void ProcessCesna(cVehicleParams& params); // done
//void ProcessCrane(); // done(bcs not exists in VC)
bool ProcessEngineDamage(cVehicleParams& params); // done
void ProcessEntity(int32 sound); // done
void ProcessExplosions(int32 explosion); // done
void ProcessFireHydrant(); // done
void ProcessFires(int32 entity); // done
void ProcessFrontEnd(); // done
void ProcessGarages(); // done
void ProcessJumbo(cVehicleParams& params); // done
void ProcessJumboAccel(CPlane *plane); // done
void ProcessJumboDecel(CPlane *plane); // done
void ProcessJumboFlying(); // done
void ProcessJumboLanding(CPlane *plane); // done
void ProcessJumboTakeOff(CPlane *plane); // done
void ProcessJumboTaxi(); // done
void ProcessLoopingScriptObject(uint8 sound); // done
void ProcessMissionAudio(); // done
void ProcessMissionAudioSlot(uint8 slot); // done
void ProcessModelHeliVehicle(cVehicleParams& params); // done
void ProcessModelVehicle(cVehicleParams& params); // done
void ProcessOneShotScriptObject(uint8 sound); //
void ProcessPed(CPhysical *ped); // done
void ProcessPedOneShots(cPedParams &params); //
void ProcessPhysical(int32 id); // done
void ProcessPlane(cVehicleParams& params); // done
void ProcessPlayerMood(); // done
void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh); // done
void ProcessProjectiles(); // done
void ProcessRainOnVehicle(cVehicleParams& params); // done
void ProcessReverb() const; // done
bool ProcessReverseGear(cVehicleParams& params); // done
void ProcessScriptObject(int32 id); // done
void ProcessSpecial(); // done
bool8 ProcessCarBombTick(cVehicleParams& params);
void ProcessCarHeli(cVehicleParams& params);
void ProcessCesna(cVehicleParams& params);
//void ProcessCrane();
bool8 ProcessEngineDamage(cVehicleParams& params);
void ProcessEntity(int32 sound);
void ProcessExplosions(int32 explosion);
void ProcessFireHydrant();
void ProcessFires(int32 entity);
void ProcessFrontEnd();
void ProcessGarages();
void ProcessJumbo(cVehicleParams& params);
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboDecel(CPlane *plane);
void ProcessJumboFlying();
void ProcessJumboLanding(CPlane *plane);
void ProcessJumboTakeOff(CPlane *plane);
void ProcessJumboTaxi();
void ProcessLoopingScriptObject(uint8 sound);
void ProcessMissionAudio();
void ProcessMissionAudioSlot(uint8 slot);
void ProcessModelHeliVehicle(cVehicleParams& params);
void ProcessModelVehicle(cVehicleParams& params);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessPed(CPhysical *ped);
void ProcessPedOneShots(cPedParams &params);
void ProcessPhysical(int32 id);
void ProcessPlane(cVehicleParams& params);
void ProcessPlayerMood();
void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh);
void ProcessProjectiles();
void ProcessRainOnVehicle(cVehicleParams& params);
void ProcessReverb() const;
bool8 ProcessReverseGear(cVehicleParams& params);
void ProcessScriptObject(int32 id);
void ProcessSpecial();
#ifdef GTA_TRAIN
bool ProcessTrainNoise(cVehicleParams *params); //done(bcs not exists in VC)
bool8 ProcessTrainNoise(cVehicleParams *params);
#endif
void ProcessVehicle(CVehicle *vehicle); // done
bool ProcessVehicleDoors(cVehicleParams &params); // done
void ProcessVehicleEngine(cVehicleParams &params); // done
void ProcessVehicleFlatTyre(cVehicleParams &params); // done
bool ProcessVehicleHorn(cVehicleParams &params); // done
void ProcessVehicleOneShots(cVehicleParams &params); // done
bool ProcessVehicleReverseWarning(cVehicleParams &params); // done
bool ProcessVehicleRoadNoise(cVehicleParams &params); // done
bool ProcessVehicleSirenOrAlarm(cVehicleParams &params); // done
bool ProcessVehicleSkidding(cVehicleParams &params); // done
void ProcessWaterCannon(int32); // done
void ProcessWeather(int32 id); // done
bool ProcessWetRoadNoise(cVehicleParams& params); // done
void ProcessEscalators(); // done
void ProcessExtraSounds(); // done
void ProcessVehicle(CVehicle *vehicle);
bool8 ProcessVehicleDoors(cVehicleParams &params);
void ProcessVehicleEngine(cVehicleParams &params);
void ProcessVehicleFlatTyre(cVehicleParams &params);
bool8 ProcessVehicleHorn(cVehicleParams &params);
void ProcessVehicleOneShots(cVehicleParams &params);
bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
bool8 ProcessVehicleSkidding(cVehicleParams &params);
void ProcessWaterCannon(int32);
void ProcessWeather(int32 id);
bool8 ProcessWetRoadNoise(cVehicleParams& params);
void ProcessEscalators();
void ProcessExtraSounds();
int32 RandomDisplacement(uint32 seed) const; // done
void ReacquireDigitalHandle() const; // done
void ReleaseDigitalHandle() const; // done
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2); // done
void ReportCrime(eCrimeType crime, const CVector &pos); // done
void ResetAudioLogicTimers(uint32 timer); // done
void ResetPoliceRadio(); // done
void ResetTimers(uint32 time); // done
int32 RandomDisplacement(uint32 seed) const;
void ReacquireDigitalHandle() const;
void ReleaseDigitalHandle() const;
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
void ReportCrime(eCrimeType crime, const CVector &pos);
void ResetAudioLogicTimers(uint32 timer);
void ResetPoliceRadio();
void ResetTimers(uint32 time);
void Service(); // done
void ServiceCollisions(); // done
void ServicePoliceRadio(); // done
void ServicePoliceRadioChannel(uint8 wantedLevel); // done
void ServiceSoundEffects(); // done
int8 SetCurrent3DProvider(uint8 which); // done
void SetDynamicAcousticModelingStatus(uint8 status); // done
void SetEffectsFadeVol(uint8 volume) const; // done
void SetEffectsMasterVolume(uint8 volume) const; // done
void SetMP3BoostVolume(uint8 volume) const; // done
void SetEntityStatus(int32 id, uint8 status); // done
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); // done
void SetMissionAudioLocation(uint8 slot, float x, float y, float z); // done
void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized
void SetMonoMode(uint8 mono); // done
void SetMusicFadeVol(uint8 volume) const; // done
void SetMusicMasterVolume(uint8 volume) const; // done
void SetSpeakerConfig(int32 conf) const; // done
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); // done
void SetUpOneShotCollisionSound(const cAudioCollision &col); // done
bool SetupCrimeReport(); // done
bool SetupJumboEngineSound(uint8 vol, uint32 freq); // done
bool SetupJumboFlySound(uint8 emittingVol); // done
bool SetupJumboRumbleSound(uint8 emittingVol); // done
bool SetupJumboTaxiSound(uint8 vol); // done
bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq); // done
void SetupPedComments(cPedParams &params, uint16 sound); // done
void Service();
void ServiceCollisions();
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
void ServiceSoundEffects();
int8 SetCurrent3DProvider(uint8 which);
void SetDynamicAcousticModelingStatus(bool8 status);
void SetEffectsFadeVol(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetMP3BoostVolume(uint8 volume) const;
void SetEntityStatus(int32 id, bool8 status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized
void SetMonoMode(bool8 mono);
void SetMusicFadeVol(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const;
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
void SetUpOneShotCollisionSound(const cAudioCollision &col);
bool8 SetupCrimeReport();
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
bool8 SetupJumboFlySound(uint8 emittingVol);
bool8 SetupJumboRumbleSound(uint8 emittingVol);
bool8 SetupJumboTaxiSound(uint8 vol);
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
void SetupPedComments(cPedParams &params, uint16 sound);
void SetupSuspectLastSeenReport();
void Terminate(); // done
void TranslateEntity(Const CVector *v1, CVector *v2) const; // done
void Terminate();
void TranslateEntity(Const CVector *v1, CVector *v2) const;
void UpdateGasPedalAudio(CVehicle *veh, int vehType); // done
void UpdateReflections(); // done
bool UsesReverseWarning(int32 model) const; // done
bool UsesSiren(cVehicleParams &params) const; // done
bool UsesSirenSwitching(cVehicleParams &params) const; // done
void UpdateGasPedalAudio(CVehicle *veh, int vehType);
void UpdateReflections();
bool8 UsesReverseWarning(int32 model) const;
bool8 UsesSiren(cVehicleParams &params) const;
bool8 UsesSirenSwitching(cVehicleParams &params) const;
CVehicle *FindVehicleOfPlayer(); // done
void SetPedTalkingStatus(CPed *ped, uint8 status); // done
void SetPlayersMood(uint8 mood, uint32 time); // done
CVehicle *FindVehicleOfPlayer();
void SetPedTalkingStatus(CPed *ped, bool8 status);
void SetPlayersMood(uint8 mood, uint32 time);
float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); }
#ifdef GTA_PC
// only used in pc
void AdjustSamplesVolume(); // done (inlined)
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // done (inlined)
void AdjustSamplesVolume(); // inlined
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // inlined
#endif
};
#ifdef AUDIO_MSS
/*
Manual loop points are not on PS2 so let's have these macros to avoid massive ifndefs.
Setting these manually was pointless anyway since they never change from sdt values.
What were they thinking?
*/
#ifndef GTA_PS2
#define RESET_LOOP_OFFSETS \
m_sQueueSample.m_nLoopStart = 0; \
m_sQueueSample.m_nLoopEnd = -1;
#define SET_LOOP_OFFSETS(sample) \
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(sample); \
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(sample);
#else
#define RESET_LOOP_OFFSETS
#define SET_LOOP_OFFSETS(sample)
#endif
#if defined(AUDIO_MSS) && !defined(PS2_AUDIO_CHANNELS)
static_assert(sizeof(cAudioManager) == 0x5558, "cAudioManager: error");
#endif

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#include "AudioScriptObject.h"
#include "Pools.h"
#include "DMAudio.h"
#include "SaveBuf.h"
cAudioScriptObject::cAudioScriptObject()
{
@ -23,25 +24,25 @@ cAudioScriptObject::Reset()
}
void *
cAudioScriptObject::operator new(size_t sz)
cAudioScriptObject::operator new(size_t sz) throw()
{
return CPools::GetAudioScriptObjectPool()->New();
}
void *
cAudioScriptObject::operator new(size_t sz, int handle)
cAudioScriptObject::operator new(size_t sz, int handle) throw()
{
return CPools::GetAudioScriptObjectPool()->New(handle);
}
void
cAudioScriptObject::operator delete(void *p, size_t sz)
cAudioScriptObject::operator delete(void *p, size_t sz) throw()
{
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
}
void
cAudioScriptObject::operator delete(void *p, int handle)
cAudioScriptObject::operator delete(void *p, int handle) throw()
{
CPools::GetAudioScriptObjectPool()->Delete((cAudioScriptObject *)p);
}
@ -53,12 +54,14 @@ cAudioScriptObject::LoadAllAudioScriptObjects(uint8 *buf, uint32 size)
CheckSaveHeader(buf, 'A', 'U', 'D', '\0', size - SAVE_HEADER_SIZE);
int32 pool_size = ReadSaveBuf<int32>(buf);
int32 pool_size;
ReadSaveBuf(&pool_size, buf);
for (int32 i = 0; i < pool_size; i++) {
int handle = ReadSaveBuf<int32>(buf);
int32 handle;
ReadSaveBuf(&handle, buf);
cAudioScriptObject *p = new(handle) cAudioScriptObject;
assert(p != nil);
*p = ReadSaveBuf<cAudioScriptObject>(buf);
ReadSaveBuf(p, buf);
p->AudioEntity = DMAudio.CreateLoopingScriptObject(p);
}
@ -90,6 +93,8 @@ cAudioScriptObject::SaveAllAudioScriptObjects(uint8 *buf, uint32 *size)
void
PlayOneShotScriptObject(uint8 id, CVector const &pos)
{
if (!DMAudio.IsAudioInitialised()) return;
cAudioScriptObject *audioScriptObject = new cAudioScriptObject();
audioScriptObject->Posn = pos;
audioScriptObject->AudioId = id;

View File

@ -12,10 +12,10 @@ public:
void Reset(); /// ok
static void* operator new(size_t);
static void* operator new(size_t, int);
static void operator delete(void*, size_t);
static void operator delete(void*, int);
static void* operator new(size_t) throw();
static void* operator new(size_t, int) throw();
static void operator delete(void*, size_t) throw();
static void operator delete(void*, int) throw();
static void LoadAllAudioScriptObjects(uint8 *buf, uint32 size);
static void SaveAllAudioScriptObjects(uint8 *buf, uint32 *size);

View File

@ -39,7 +39,7 @@ cDMAudio::DestroyEntity(int32 audioEntity)
}
void
cDMAudio::SetEntityStatus(int32 audioEntity, uint8 status)
cDMAudio::SetEntityStatus(int32 audioEntity, bool8 status)
{
AudioManager.SetEntityStatus(audioEntity, status);
}
@ -57,7 +57,7 @@ cDMAudio::DestroyAllGameCreatedEntities(void)
}
void
cDMAudio::SetMonoMode(uint8 mono)
cDMAudio::SetMonoMode(bool8 mono)
{
AudioManager.SetMonoMode(mono);
}
@ -142,7 +142,7 @@ cDMAudio::SetSpeakerConfig(int32 config)
AudioManager.SetSpeakerConfig(config);
}
bool
bool8
cDMAudio::IsMP3RadioChannelAvailable(void)
{
return AudioManager.IsMP3RadioChannelAvailable();
@ -161,12 +161,12 @@ cDMAudio::ReacquireDigitalHandle(void)
}
void
cDMAudio::SetDynamicAcousticModelingStatus(uint8 status)
cDMAudio::SetDynamicAcousticModelingStatus(bool8 status)
{
AudioManager.SetDynamicAcousticModelingStatus(status);
}
bool
bool8
cDMAudio::CheckForAnAudioFileOnCD(void)
{
return AudioManager.CheckForAnAudioFileOnCD();
@ -178,7 +178,7 @@ cDMAudio::GetCDAudioDriveLetter(void)
return AudioManager.GetCDAudioDriveLetter();
}
bool
bool8
cDMAudio::IsAudioInitialised(void)
{
return AudioManager.IsAudioInitialised();
@ -196,7 +196,7 @@ cDMAudio::CreateLoopingScriptObject(cAudioScriptObject *scriptObject)
int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, scriptObject);
if ( AEHANDLE_IS_OK(audioEntity) )
AudioManager.SetEntityStatus(audioEntity, true);
AudioManager.SetEntityStatus(audioEntity, TRUE);
return audioEntity;
}
@ -214,7 +214,7 @@ cDMAudio::CreateOneShotScriptObject(cAudioScriptObject *scriptObject)
if ( AEHANDLE_IS_OK(audioEntity) )
{
AudioManager.SetEntityStatus(audioEntity, true);
AudioManager.SetEntityStatus(audioEntity, TRUE);
AudioManager.PlayOneShot(audioEntity, scriptObject->AudioId, 0.0f);
}
}
@ -244,7 +244,7 @@ cDMAudio::PlayRadioAnnouncement(uint32 announcement)
}
void
cDMAudio::PlayFrontEndTrack(uint32 track, uint8 frontendFlag)
cDMAudio::PlayFrontEndTrack(uint32 track, bool8 frontendFlag)
{
MusicManager.PlayFrontEndTrack(track, frontendFlag);
}
@ -309,7 +309,7 @@ cDMAudio::PlayLoadedMissionAudio(uint8 slot)
AudioManager.PlayLoadedMissionAudio(slot);
}
bool
bool8
cDMAudio::IsMissionAudioSampleFinished(uint8 slot)
{
return AudioManager.IsMissionAudioSampleFinished(slot);
@ -340,7 +340,7 @@ cDMAudio::SetRadioChannel(uint32 radio, int32 pos)
}
void
cDMAudio::SetStartingTrackPositions(uint8 isStartGame)
cDMAudio::SetStartingTrackPositions(bool8 isStartGame)
{
MusicManager.SetStartingTrackPositions(isStartGame);
}
@ -364,7 +364,7 @@ cDMAudio::GetRadioPosition(uint32 station)
}
void
cDMAudio::SetPedTalkingStatus(CPed *ped, uint8 status)
cDMAudio::SetPedTalkingStatus(CPed *ped, bool8 status)
{
return AudioManager.SetPedTalkingStatus(ped, status);
}
@ -376,7 +376,7 @@ cDMAudio::SetPlayersMood(uint8 mood, uint32 time)
}
void
cDMAudio::ShutUpPlayerTalking(uint8 state)
cDMAudio::ShutUpPlayerTalking(bool8 state)
{
AudioManager.m_bIsPlayerShutUp = state;
}

View File

@ -25,11 +25,11 @@ public:
int32 CreateEntity(eAudioType type, void *UID);
void DestroyEntity(int32 audioEntity);
void SetEntityStatus(int32 audioEntity, uint8 status);
void SetEntityStatus(int32 audioEntity, bool8 status);
void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume);
void DestroyAllGameCreatedEntities(void);
void SetMonoMode(uint8 mono);
void SetMonoMode(bool8 mono);
void SetMP3BoostVolume(uint8 volume);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
@ -46,17 +46,17 @@ public:
void SetSpeakerConfig(int32 config);
bool IsMP3RadioChannelAvailable(void);
bool8 IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle(void);
void ReacquireDigitalHandle(void);
void SetDynamicAcousticModelingStatus(uint8 status);
void SetDynamicAcousticModelingStatus(bool8 status);
bool CheckForAnAudioFileOnCD(void);
bool8 CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter(void);
bool IsAudioInitialised(void);
bool8 IsAudioInitialised(void);
void ReportCrime(eCrimeType crime, CVector const &pos);
@ -70,7 +70,7 @@ public:
void PlayFrontEndSound(uint16 frontend, uint32 volume);
void PlayRadioAnnouncement(uint32 announcement);
void PlayFrontEndTrack(uint32 track, uint8 frontendFlag);
void PlayFrontEndTrack(uint32 track, bool8 frontendFlag);
void StopFrontEndTrack(void);
void ResetTimers(uint32 time);
@ -85,19 +85,19 @@ public:
uint8 GetMissionAudioLoadingStatus(uint8 slot);
void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void PlayLoadedMissionAudio(uint8 slot);
bool IsMissionAudioSampleFinished(uint8 slot);
bool8 IsMissionAudioSampleFinished(uint8 slot);
void ClearMissionAudio(uint8 slot);
uint8 GetRadioInCar(void);
void SetRadioInCar(uint32 radio);
void SetRadioChannel(uint32 radio, int32 pos);
void SetStartingTrackPositions(uint8 isStartGame);
void SetStartingTrackPositions(bool8 isStartGame);
float *GetListenTimeArray();
uint32 GetFavouriteRadioStation();
int32 GetRadioPosition(uint32 station);
void SetPedTalkingStatus(class CPed *ped, uint8 status);
void SetPedTalkingStatus(class CPed *ped, bool8 status);
void SetPlayersMood(uint8 mood, uint32 time);
void ShutUpPlayerTalking(uint8 state);
void ShutUpPlayerTalking(bool8 state);
};
extern cDMAudio DMAudio;

View File

@ -28,7 +28,7 @@ static_assert(false, "R*'s radio implementation is quite buggy, RADIO_SCROLL_TO_
cMusicManager MusicManager;
int32 gNumRetunePresses;
int32 gRetuneCounter;
bool g_bAnnouncementReadPosAlready;
bool8 g_bAnnouncementReadPosAlready;
uint8 RadioStaticCounter = 5;
uint32 RadioStaticTimer;
@ -50,13 +50,13 @@ uint32 NewGameRadioTimers[10] =
cMusicManager::cMusicManager()
{
m_bIsInitialised = false;
m_bDisabled = false;
m_bIsInitialised = FALSE;
m_bDisabled = FALSE;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
m_nUpcomingMusicMode = MUSICMODE_DISABLED;
m_nMusicMode = MUSICMODE_DISABLED;
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
for (int i = 0; i < NUM_RADIOS; i++)
aListenTimeArray[i] = 0.0f;
@ -66,7 +66,7 @@ cMusicManager::cMusicManager()
m_nCurrentVolume = 0;
m_nMaxVolume = 0;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
}
void
@ -74,38 +74,38 @@ cMusicManager::ResetMusicAfterReload()
{
float afRadioTime[NUM_RADIOS];
m_bRadioSetByScript = false;
m_bRadioSetByScript = FALSE;
m_nRadioStationScript = WILDSTYLE;
m_nRadioPosition = -1;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bSetNextStation = false;
m_bAnnouncementInProgress = FALSE;
m_bSetNextStation = FALSE;
RadioStaticTimer = 0;
gNumRetunePresses = 0;
gRetuneCounter = 0;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
m_FrontendLoopFlag = false;
m_bTrackChangeStarted = false;
m_FrontendLoopFlag = FALSE;
m_bTrackChangeStarted = FALSE;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_bGameplayAllowsRadio = false;
m_bRadioStreamReady = false;
m_nNextLoopFlag = FALSE;
m_bVerifyNextTrackStartedToPlay = FALSE;
m_bGameplayAllowsRadio = FALSE;
m_bRadioStreamReady = FALSE;
nFramesSinceCutsceneEnded = -1;
m_bUserResumedGame = false;
m_bMusicModeChangeStarted = false;
m_bEarlyFrontendTrack = false;
m_bUserResumedGame = FALSE;
m_bMusicModeChangeStarted = FALSE;
m_bEarlyFrontendTrack = FALSE;
m_nVolumeLatency = 0;
m_nCurrentVolume = 0;
m_nMaxVolume = 0;
bool bRadioWasEverListened = false;
bool8 bRadioWasEverListened = FALSE;
for (int i = 0; i < NUM_RADIOS; i++) {
afRadioTime[i] = CStats::GetFavoriteRadioStationList(i);
if (!bRadioWasEverListened && afRadioTime[i] != 0.0f)
bRadioWasEverListened = true;
bRadioWasEverListened = TRUE;
}
if (!bRadioWasEverListened) return;
@ -125,7 +125,7 @@ cMusicManager::ResetMusicAfterReload()
}
void
cMusicManager::SetStartingTrackPositions(uint8 isNewGameTimer)
cMusicManager::SetStartingTrackPositions(bool8 isNewGameTimer)
{
int pos;
@ -174,15 +174,15 @@ cMusicManager::SetStartingTrackPositions(uint8 isNewGameTimer)
}
}
bool
bool8
cMusicManager::Initialise()
{
if (!IsInitialised()) {
m_bIsInitialised = true;
SetStartingTrackPositions(false);
m_bResetTimers = false;
m_bIsInitialised = TRUE;
SetStartingTrackPositions(FALSE);
m_bResetTimers = FALSE;
m_nResetTime = 0;
m_bRadioSetByScript = false;
m_bRadioSetByScript = FALSE;
m_nRadioStationScript = WILDSTYLE;
m_nRadioPosition = -1;
m_nRadioInCar = NO_TRACK;
@ -192,18 +192,18 @@ cMusicManager::Initialise()
m_nPlayingTrack = NO_TRACK;
m_nUpcomingMusicMode = MUSICMODE_DISABLED;
m_nMusicMode = MUSICMODE_DISABLED;
m_FrontendLoopFlag = false;
m_bTrackChangeStarted = false;
m_FrontendLoopFlag = FALSE;
m_bTrackChangeStarted = FALSE;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_bGameplayAllowsRadio = false;
m_bRadioStreamReady = false;
m_nNextLoopFlag = FALSE;
m_bVerifyNextTrackStartedToPlay = FALSE;
m_bGameplayAllowsRadio = FALSE;
m_bRadioStreamReady = FALSE;
nFramesSinceCutsceneEnded = -1;
m_bUserResumedGame = false;
m_bMusicModeChangeStarted = false;
m_bUserResumedGame = FALSE;
m_bMusicModeChangeStarted = FALSE;
m_nMusicModeToBeSet = MUSICMODE_DISABLED;
m_bEarlyFrontendTrack = false;
m_bEarlyFrontendTrack = FALSE;
m_nVolumeLatency = 0;
m_nCurrentVolume = 0;
m_nMaxVolume = 0;
@ -216,11 +216,11 @@ cMusicManager::Terminate()
{
if (!IsInitialised()) return;
if (SampleManager.IsStreamPlaying(0)) {
SampleManager.StopStreamedFile(0);
if (SampleManager.IsStreamPlaying()) {
SampleManager.StopStreamedFile();
m_nPlayingTrack = NO_TRACK;
}
m_bIsInitialised = false;
m_bIsInitialised = FALSE;
}
void
@ -230,29 +230,29 @@ cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos)
if (station == STREAMED_SOUND_RADIO_MP3_PLAYER)
station = STREAMED_SOUND_CITY_AMBIENT;
if (station <= STREAMED_SOUND_RADIO_POLICE) {
m_bRadioSetByScript = true;
m_bRadioSetByScript = TRUE;
m_nRadioStationScript = station;
m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
}
}
}
bool
bool8
cMusicManager::PlayerInCar()
{
CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
if(!vehicle)
return false;
return FALSE;
int32 State = FindPlayerPed()->m_nPedState;
if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
return false;
return FALSE;
if (vehicle->GetStatus() == STATUS_WRECKED)
return false;
return FALSE;
return true;
return TRUE;
}
uint32
@ -310,31 +310,42 @@ cMusicManager::ChangeMusicMode(uint8 mode)
switch (mode)
{
case MUSICMODE_FRONTEND: m_nUpcomingMusicMode = MUSICMODE_FRONTEND; break;
case MUSICMODE_FRONTEND:
m_nUpcomingMusicMode = MUSICMODE_FRONTEND;
#ifdef PAUSE_RADIO_IN_FRONTEND
// rewind those streams we weren't listening right now
for( uint32 i = STREAMED_SOUND_RADIO_WILD; i < STREAMED_SOUND_CUTSCENE_ASS_1; i++ ) {
m_aTracks[i].m_nPosition = GetTrackStartPos(i);
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
#endif
break;
case MUSICMODE_GAME: m_nUpcomingMusicMode = MUSICMODE_GAME; break;
case MUSICMODE_CUTSCENE:
m_nUpcomingMusicMode = MUSICMODE_CUTSCENE;
if (SampleManager.IsStreamPlaying(0)) {
if (SampleManager.IsStreamPlaying()) {
if (m_nPlayingTrack != NO_TRACK) {
RecordRadioStats();
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
}
SampleManager.StopStreamedFile(0);
while (SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
while (SampleManager.IsStreamPlaying())
SampleManager.StopStreamedFile();
m_nMusicMode = m_nUpcomingMusicMode;
m_bMusicModeChangeStarted = false;
m_bTrackChangeStarted = false;
m_bMusicModeChangeStarted = FALSE;
m_bTrackChangeStarted = FALSE;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_nNextLoopFlag = FALSE;
m_bVerifyNextTrackStartedToPlay = FALSE;
m_nPlayingTrack = NO_TRACK;
m_nFrontendTrack = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
m_nAnnouncement = NO_TRACK;
g_bAnnouncementReadPosAlready = false;
g_bAnnouncementReadPosAlready = FALSE;
break;
case MUSICMODE_DISABLE: m_nUpcomingMusicMode = MUSICMODE_DISABLED; break;
default: return;
@ -344,7 +355,7 @@ cMusicManager::ChangeMusicMode(uint8 mode)
void
cMusicManager::ResetTimers(int32 time)
{
m_bResetTimers = true;
m_bResetTimers = TRUE;
m_nResetTime = time;
}
@ -352,11 +363,11 @@ void
cMusicManager::Service()
{
if (m_bResetTimers) {
m_bResetTimers = false;
m_bResetTimers = FALSE;
m_nLastTrackServiceTime = m_nResetTime;
}
static bool bRadioStatsRecorded = false;
static bool8 bRadioStatsRecorded = FALSE;
if (!m_bIsInitialised || m_bDisabled) return;
@ -369,39 +380,39 @@ cMusicManager::Service()
{
case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break;
case MUSICMODE_GAME: ServiceGameMode(); break;
case MUSICMODE_CUTSCENE: SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0); break;
case MUSICMODE_CUTSCENE: SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE); break;
}
}
else
m_nMusicMode = MUSICMODE_DISABLED;
} else {
m_bMusicModeChangeStarted = true;
m_bMusicModeChangeStarted = TRUE;
if (!m_bUserResumedGame && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause)
m_bUserResumedGame = true;
m_bUserResumedGame = TRUE;
if (AudioManager.m_FrameCounter % 4 == 0) {
gNumRetunePresses = 0;
gRetuneCounter = 0;
m_bSetNextStation = false;
if (SampleManager.IsStreamPlaying(0)) {
m_bSetNextStation = FALSE;
if (SampleManager.IsStreamPlaying()) {
if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded)
{
RecordRadioStats();
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
bRadioStatsRecorded = true;
bRadioStatsRecorded = TRUE;
}
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
} else {
bRadioStatsRecorded = false;
bRadioStatsRecorded = FALSE;
m_nMusicMode = m_nMusicModeToBeSet;
m_bMusicModeChangeStarted = false;
m_bTrackChangeStarted = false;
m_bMusicModeChangeStarted = FALSE;
m_bTrackChangeStarted = FALSE;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_nNextLoopFlag = FALSE;
m_bVerifyNextTrackStartedToPlay = FALSE;
m_nPlayingTrack = NO_TRACK;
if (m_bEarlyFrontendTrack)
m_bEarlyFrontendTrack = false;
m_bEarlyFrontendTrack = FALSE;
else
m_nFrontendTrack = NO_TRACK;
}
@ -412,15 +423,21 @@ cMusicManager::Service()
void
cMusicManager::ServiceFrontEndMode()
{
static bool bRadioStatsRecorded = false;
static bool8 bRadioStatsRecorded = FALSE;
#ifdef PAUSE_RADIO_IN_FRONTEND
// pause radio
for (uint32 i = STREAMED_SOUND_RADIO_WILD; i < STREAMED_SOUND_CUTSCENE_ASS_1; i++)
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
#endif
if (m_bAnnouncementInProgress) {
SampleManager.StopStreamedFile(0);
if (SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile();
if (SampleManager.IsStreamPlaying())
return;
g_bAnnouncementReadPosAlready = false;
g_bAnnouncementReadPosAlready = FALSE;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
m_nNextTrack = NO_TRACK;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
@ -434,50 +451,50 @@ cMusicManager::ServiceFrontEndMode()
}
if (m_nNextTrack == m_nPlayingTrack) {
if (SampleManager.IsStreamPlaying(0)) {
if (SampleManager.IsStreamPlaying()) {
if (m_nVolumeLatency > 0) m_nVolumeLatency--;
else {
if (m_nCurrentVolume < m_nMaxVolume)
m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6);
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
}
} else {
if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER)
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0);
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0);
else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && AudioManager.m_nUserPause == 0)
ChangeMusicMode(MUSICMODE_GAME);
}
} else {
m_bTrackChangeStarted = true;
if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying(0)) {
bRadioStatsRecorded = false;
if (SampleManager.IsStreamPlaying(0) || m_nNextTrack == NO_TRACK) {
m_bTrackChangeStarted = TRUE;
if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying()) {
bRadioStatsRecorded = FALSE;
if (SampleManager.IsStreamPlaying() || m_nNextTrack == NO_TRACK) {
m_nPlayingTrack = m_nNextTrack;
m_bVerifyNextTrackStartedToPlay = false;
m_bTrackChangeStarted = false;
m_bVerifyNextTrackStartedToPlay = FALSE;
m_bTrackChangeStarted = FALSE;
} else {
uint32 trackStartPos = (m_nNextTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nNextTrack);
if (m_nNextTrack != NO_TRACK) {
SampleManager.SetStreamedFileLoopFlag(m_nNextLoopFlag, 0);
SampleManager.StartStreamedFile(m_nNextTrack, trackStartPos, 0);
SampleManager.SetStreamedFileLoopFlag(m_nNextLoopFlag);
SampleManager.StartStreamedFile(m_nNextTrack, trackStartPos);
m_nVolumeLatency = 3;
m_nCurrentVolume = 0;
m_nMaxVolume = 100;
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT)
m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
m_bVerifyNextTrackStartedToPlay = true;
m_bVerifyNextTrackStartedToPlay = TRUE;
}
}
} else {
if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
RecordRadioStats();
bRadioStatsRecorded = true;
bRadioStatsRecorded = TRUE;
}
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.StopStreamedFile(0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
SampleManager.StopStreamedFile();
}
}
}
@ -488,7 +505,7 @@ cMusicManager::ServiceGameMode()
CPed *ped = FindPlayerPed();
CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
m_bRadioStreamReady = m_bGameplayAllowsRadio;
m_bGameplayAllowsRadio = false;
m_bGameplayAllowsRadio = FALSE;
switch (CGame::currArea)
{
@ -499,14 +516,14 @@ cMusicManager::ServiceGameMode()
case AREA_BLOOD:
case AREA_OVALRING:
case AREA_MALIBU_CLUB:
m_bGameplayAllowsRadio = false;
m_bGameplayAllowsRadio = FALSE;
break;
default:
if (SampleManager.GetMusicVolume()) {
if (PlayerInCar())
m_bGameplayAllowsRadio = true;
m_bGameplayAllowsRadio = TRUE;
} else
m_bGameplayAllowsRadio = false;
m_bGameplayAllowsRadio = FALSE;
break;
}
@ -514,7 +531,7 @@ cMusicManager::ServiceGameMode()
nFramesSinceCutsceneEnded = -1;
gNumRetunePresses = 0;
gRetuneCounter = 0;
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
} else if (ped) {
if(!ped->DyingOrDead() && vehicle) {
#ifdef GTA_PC
@ -567,11 +584,11 @@ cMusicManager::ServiceGameMode()
if (m_bUserResumedGame)
{
m_bRadioStreamReady = false;
m_bUserResumedGame = false;
m_bRadioStreamReady = FALSE;
m_bUserResumedGame = FALSE;
}
if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK)
m_bRadioStreamReady = false;
m_bRadioStreamReady = FALSE;
if (m_bGameplayAllowsRadio)
{
@ -594,7 +611,7 @@ cMusicManager::ServiceGameMode()
m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
m_bRadioSetByScript = false;
m_bRadioSetByScript = FALSE;
return;
}
@ -605,7 +622,7 @@ cMusicManager::ServiceGameMode()
if (m_nAnnouncement < NO_TRACK) {
if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) {
if (m_bAnnouncementInProgress) {
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
gNumRetunePresses = 0;
gRetuneCounter = 0;
return;
@ -613,7 +630,7 @@ cMusicManager::ServiceGameMode()
if(m_nAnnouncement == NO_TRACK) {
m_nNextTrack = NO_TRACK;
m_nFrontendTrack = GetCarTuning();
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
gRetuneCounter = 0;
gNumRetunePresses = 0;
}
@ -622,9 +639,9 @@ cMusicManager::ServiceGameMode()
if (!m_bAnnouncementInProgress
&& m_nAnnouncement == NO_TRACK
&& m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER
&& !SampleManager.IsStreamPlaying(0))
&& !SampleManager.IsStreamPlaying())
{
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0);
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0);
}
if (!m_bRadioSetByScript)
@ -635,7 +652,7 @@ cMusicManager::ServiceGameMode()
if(gRetuneCounter > 1)
gRetuneCounter--;
else if(gRetuneCounter == 1) {
m_bSetNextStation = true;
m_bSetNextStation = TRUE;
gRetuneCounter = 0;
}
}
@ -644,7 +661,7 @@ cMusicManager::ServiceGameMode()
{
if (--gRetuneCounter == 0)
{
m_bSetNextStation = true;
m_bSetNextStation = TRUE;
gRetuneCounter = 0;
}
}
@ -694,7 +711,7 @@ cMusicManager::ServiceGameMode()
SetUpCorrectAmbienceTrack();
ServiceTrack(vehicle, ped);
if (m_bSetNextStation)
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
return;
}
if (UsesPoliceRadio(vehicle))
@ -713,24 +730,24 @@ cMusicManager::ServiceGameMode()
gRetuneCounter = 0;
gNumRetunePresses = 0;
m_bSetNextStation = false;
m_bRadioSetByScript = false;
m_bSetNextStation = FALSE;
m_bRadioSetByScript = FALSE;
if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
SetUpCorrectAmbienceTrack();
ServiceTrack(vehicle, ped);
if (m_bSetNextStation)
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
return;
}
if (m_bAnnouncementInProgress)
{
SampleManager.StopStreamedFile(0);
if (SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile();
if (SampleManager.IsStreamPlaying())
return;
g_bAnnouncementReadPosAlready = false;
g_bAnnouncementReadPosAlready = FALSE;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
m_nNextTrack = NO_TRACK;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
@ -808,7 +825,7 @@ GetHeightScale()
}
void
cMusicManager::ComputeAmbienceVol(uint8 reset, uint8& outVolume)
cMusicManager::ComputeAmbienceVol(bool8 reset, uint8& outVolume)
{
static float fVol = 0.0f;
@ -868,77 +885,77 @@ cMusicManager::ComputeAmbienceVol(uint8 reset, uint8& outVolume)
outVolume = (90.0f - fHeightScale) / 50.0f * fVol;
}
bool
bool8
cMusicManager::ServiceAnnouncement()
{
if (m_bAnnouncementInProgress) {
if (SampleManager.IsStreamPlaying(0))
if (SampleManager.IsStreamPlaying())
m_nPlayingTrack = m_nNextTrack;
else if (m_nPlayingTrack != NO_TRACK) {
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
m_nPlayingTrack = NO_TRACK;
}
return true;
} else if (SampleManager.IsStreamPlaying(0)) {
return TRUE;
} else if (SampleManager.IsStreamPlaying()) {
if (m_nPlayingTrack != NO_TRACK && !g_bAnnouncementReadPosAlready) {
RecordRadioStats();
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
g_bAnnouncementReadPosAlready = true;
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
g_bAnnouncementReadPosAlready = TRUE;
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
} else {
g_bAnnouncementReadPosAlready = false;
g_bAnnouncementReadPosAlready = FALSE;
m_nPlayingTrack = NO_TRACK;
m_nNextTrack = m_nAnnouncement;
SampleManager.SetStreamedFileLoopFlag(0, 0);
SampleManager.StartStreamedFile(m_nNextTrack, 0, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 0, 0);
m_bAnnouncementInProgress = true;
SampleManager.SetStreamedFileLoopFlag(FALSE);
SampleManager.StartStreamedFile(m_nNextTrack, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, FALSE);
m_bAnnouncementInProgress = TRUE;
}
return true;
return TRUE;
}
void
cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
{
static bool bRadioStatsRecorded = false;
static bool bRadioStatsRecorded2 = false;
static bool8 bRadioStatsRecorded = FALSE;
static bool8 bRadioStatsRecorded2 = FALSE;
uint8 volume;
if (!m_bTrackChangeStarted)
m_nNextTrack = m_nFrontendTrack;
if (gRetuneCounter != 0 || m_bSetNextStation) {
if (SampleManager.IsStreamPlaying(0)) {
if (SampleManager.IsStreamPlaying()) {
if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
RecordRadioStats();
bRadioStatsRecorded = true;
bRadioStatsRecorded = TRUE;
}
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.StopStreamedFile(0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
SampleManager.StopStreamedFile();
}
return;
}
if (bRadioStatsRecorded) {
bRadioStatsRecorded = false;
bRadioStatsRecorded = FALSE;
m_nPlayingTrack = NO_TRACK;
}
if (m_nNextTrack != m_nPlayingTrack)
{
m_bTrackChangeStarted = true;
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
m_bTrackChangeStarted = TRUE;
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
if (!(AudioManager.m_FrameCounter & 1)) {
if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying(0)) {
bRadioStatsRecorded2 = false;
if (SampleManager.IsStreamPlaying(0)) {
if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying()) {
bRadioStatsRecorded2 = FALSE;
if (SampleManager.IsStreamPlaying()) {
m_nPlayingTrack = m_nNextTrack;
m_bVerifyNextTrackStartedToPlay = false;
m_bTrackChangeStarted = false;
m_bVerifyNextTrackStartedToPlay = FALSE;
m_bTrackChangeStarted = FALSE;
if (veh) {
#ifdef FIX_BUGS
if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
@ -955,23 +972,23 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
} else {
uint32 pos = GetTrackStartPos(m_nNextTrack);
if (m_nNextTrack != NO_TRACK) {
SampleManager.SetStreamedFileLoopFlag(1, 0);
SampleManager.StartStreamedFile(m_nNextTrack, pos, 0);
SampleManager.SetStreamedFileLoopFlag(TRUE);
SampleManager.StartStreamedFile(m_nNextTrack, pos);
if (m_nFrontendTrack < STREAMED_SOUND_CITY_AMBIENT || m_nFrontendTrack > STREAMED_SOUND_AMBSIL_AMBIENT)
{
m_nVolumeLatency = 10;
m_nCurrentVolume = 0;
m_nMaxVolume = 100;
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
}
else
{
ComputeAmbienceVol(true, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
ComputeAmbienceVol(TRUE, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
}
if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT)
m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
m_bVerifyNextTrackStartedToPlay = true;
m_bVerifyNextTrackStartedToPlay = TRUE;
}
}
} else {
@ -979,9 +996,9 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
debug("m_nPlayingTrack == NO_TRACK, yet track playing - tidying up\n");
else if (!bRadioStatsRecorded2)
{
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
bRadioStatsRecorded2 = true;
bRadioStatsRecorded2 = TRUE;
RecordRadioStats();
if (m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
{
@ -989,8 +1006,8 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_HURRICANE, 0.0);
}
}
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.StopStreamedFile(0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
SampleManager.StopStreamedFile();
}
}
return;
@ -998,8 +1015,8 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
{
ComputeAmbienceVol(false, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
ComputeAmbienceVol(FALSE, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
return;
}
if (CTimer::GetIsSlowMotionActive())
@ -1009,7 +1026,7 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr();
if (DistToTargetSq >= SQR(55.0f))
{
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
}
else if (DistToTargetSq >= SQR(10.0f))
{
@ -1026,17 +1043,17 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
}
if (gRetuneCounter != 0)
volume = 0;
SampleManager.SetStreamedVolumeAndPan(volume, pan, 0, 0);
SampleManager.SetStreamedVolumeAndPan(volume, pan, FALSE);
}
else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1))
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
else if (gRetuneCounter != 0)
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
else
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, FALSE);
}
} else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) {
SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, FALSE);
nFramesSinceCutsceneEnded = 0;
} else {
if (nFramesSinceCutsceneEnded == -1)
@ -1058,7 +1075,7 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
}
if (gRetuneCounter != 0)
volume = 0;
SampleManager.SetStreamedVolumeAndPan(volume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(volume, 63, FALSE);
}
if (m_nVolumeLatency > 0)
m_nVolumeLatency--;
@ -1071,10 +1088,10 @@ cMusicManager::PreloadCutSceneMusic(uint32 track)
{
if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && m_nMusicMode == MUSICMODE_CUTSCENE) {
AudioManager.ResetPoliceRadio();
while (SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile(0);
SampleManager.PreloadStreamedFile(track, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0);
while (SampleManager.IsStreamPlaying())
SampleManager.StopStreamedFile();
SampleManager.PreloadStreamedFile(track);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE);
m_nPlayingTrack = track;
}
}
@ -1083,27 +1100,27 @@ void
cMusicManager::PlayPreloadedCutSceneMusic(void)
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE)
SampleManager.StartPreloadedStreamedFile(0);
SampleManager.StartPreloadedStreamedFile();
}
void
cMusicManager::StopCutSceneMusic(void)
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) {
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
m_nPlayingTrack = NO_TRACK;
}
}
void
cMusicManager::PlayFrontEndTrack(uint32 track, uint8 loopFlag)
cMusicManager::PlayFrontEndTrack(uint32 track, bool8 loopFlag)
{
if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND))
{
m_nFrontendTrack = track;
m_FrontendLoopFlag = loopFlag;
if (m_nMusicMode != MUSICMODE_FRONTEND)
m_bEarlyFrontendTrack = true;
m_bEarlyFrontendTrack = TRUE;
}
}
@ -1201,7 +1218,7 @@ cMusicManager::GetFavouriteRadioStation()
return favstation;
}
bool
bool8
cMusicManager::CheckForMusicInterruptions()
{
return (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED) || (m_nPlayingTrack == STREAMED_SOUND_CUTSCENE_FINALE);
@ -1265,7 +1282,8 @@ cMusicManager::DisplayRadioStationName()
if (vehicle)
{
#if defined RADIO_SCROLL_TO_PREV_STATION || defined FIX_BUGS // Because m_nFrontendTrack can have NO_TRACK
// Prev scroll needs it to be signed, and m_nFrontendTrack can be NO_TRACK thus FIX_BUGS
#if defined RADIO_SCROLL_TO_PREV_STATION || defined FIX_BUGS
int track;
#else
uint8 track;
@ -1281,13 +1299,16 @@ cMusicManager::DisplayRadioStationName()
#endif
while (track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1;
// We already handle this condition while scrolling back, on key press. No need to change this.
// On scrolling back we handle this condition on key press. No need to change this.
if (!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK)
gNumRetunePresses++;
}
else
#ifdef RADIO_OFF_TEXT
track = GetCarTuning(); // gStreamedSound or veh->m_nRadioStation would also work, but these don't cover police/taxi radios
#else
track = m_nFrontendTrack;
#endif
wchar* string = nil;
switch (track) {
case WILDSTYLE: string = TheText.Get("FEA_FM0"); break;
@ -1304,10 +1325,11 @@ cMusicManager::DisplayRadioStationName()
return;
string = TheText.Get("FEA_MP3"); break;
#ifdef RADIO_OFF_TEXT
case STREAMED_SOUND_RADIO_POLICE:
case STREAMED_SOUND_RADIO_TAXI:
return;
default: {
case RADIO_OFF: {
// Otherwise RADIO OFF will be seen after pausing-resuming game and Mission Complete text
if (!m_bRadioStreamReady || !m_bGameplayAllowsRadio)
return;
extern wchar WideErrorString[];
string = TheText.Get("FEA_NON");
@ -1317,9 +1339,8 @@ cMusicManager::DisplayRadioStationName()
}
break;
}
#else
default: return;
#endif
default: return;
};
if (pCurrentStation != string) {
@ -1328,7 +1349,11 @@ cMusicManager::DisplayRadioStationName()
}
else {
if (cDisplay == 0) return;
#ifdef FIX_BUGS
cDisplay -= CTimer::GetLogicalFramesPassed();
#else
cDisplay--;
#endif
}
CFont::SetJustifyOff();
@ -1357,7 +1382,7 @@ cMusicManager::DisplayRadioStationName()
#endif
}
bool
bool8
cMusicManager::UsesPoliceRadio(CVehicle *veh)
{
switch (veh->GetModelIndex())
@ -1367,18 +1392,18 @@ cMusicManager::UsesPoliceRadio(CVehicle *veh)
case MI_COASTG:
case MI_RHINO:
case MI_BARRACKS:
return true;
return TRUE;
case MI_MRWHOOP:
case MI_HUNTER:
return false;
return FALSE;
}
return veh->UsesSiren();
}
bool
bool8
cMusicManager::UsesTaxiRadio(CVehicle *veh)
{
if (veh->GetModelIndex() != MI_KAUFMAN) return false;
if (veh->GetModelIndex() != MI_KAUFMAN) return FALSE;
return CTheScripts::bPlayerHasMetDebbieHarry;
}
@ -1387,10 +1412,10 @@ cMusicManager::ServiceAmbience()
{
}
bool
bool8
cMusicManager::ChangeRadioChannel()
{
return true;
return TRUE;
}
// these two are empty

View File

@ -16,18 +16,18 @@ class CPed;
class cMusicManager
{
public:
bool m_bIsInitialised;
bool m_bDisabled;
bool m_bSetNextStation;
bool8 m_bIsInitialised;
bool8 m_bDisabled;
bool8 m_bSetNextStation;
uint8 m_nVolumeLatency;
uint8 m_nCurrentVolume;
uint8 m_nMaxVolume;
uint32 m_nAnnouncement;
bool m_bAnnouncementInProgress;
bool8 m_bAnnouncementInProgress;
tStreamedSample m_aTracks[TOTAL_STREAMED_SOUNDS];
bool m_bResetTimers;
bool8 m_bResetTimers;
uint32 m_nResetTime;
bool m_bRadioSetByScript;
bool8 m_bRadioSetByScript;
uint8 m_nRadioStationScript;
int32 m_nRadioPosition;
uint32 m_nRadioInCar;
@ -35,40 +35,40 @@ public:
uint32 m_nPlayingTrack;
uint8 m_nUpcomingMusicMode;
uint8 m_nMusicMode;
bool m_FrontendLoopFlag;
bool m_bTrackChangeStarted;
bool8 m_FrontendLoopFlag;
bool8 m_bTrackChangeStarted;
uint32 m_nNextTrack;
bool m_nNextLoopFlag;
bool m_bVerifyNextTrackStartedToPlay;
bool m_bGameplayAllowsRadio;
bool m_bRadioStreamReady;
bool8 m_nNextLoopFlag;
bool8 m_bVerifyNextTrackStartedToPlay;
bool8 m_bGameplayAllowsRadio;
bool8 m_bRadioStreamReady;
int8 nFramesSinceCutsceneEnded;
bool m_bUserResumedGame;
bool m_bMusicModeChangeStarted;
bool8 m_bUserResumedGame;
bool8 m_bMusicModeChangeStarted;
uint8 m_nMusicModeToBeSet;
bool m_bEarlyFrontendTrack;
bool8 m_bEarlyFrontendTrack;
float aListenTimeArray[NUM_RADIOS];
float m_nLastTrackServiceTime;
public:
cMusicManager();
bool IsInitialised() { return m_bIsInitialised; }
bool8 IsInitialised() { return m_bIsInitialised; }
uint8 GetMusicMode() { return m_nMusicMode; }
uint32 GetCurrentTrack() { return m_nPlayingTrack; }
void ResetMusicAfterReload();
void SetStartingTrackPositions(uint8 isNewGameTimer);
bool Initialise();
void SetStartingTrackPositions(bool8 isNewGameTimer);
bool8 Initialise();
void Terminate();
void ChangeMusicMode(uint8 mode);
void StopFrontEndTrack();
bool PlayerInCar();
bool8 PlayerInCar();
void DisplayRadioStationName();
void PlayAnnouncement(uint32);
void PlayFrontEndTrack(uint32, uint8);
void PlayFrontEndTrack(uint32, bool8);
void PreloadCutSceneMusic(uint32);
void PlayPreloadedCutSceneMusic(void);
void StopCutSceneMusic(void);
@ -83,16 +83,16 @@ public:
void ServiceAmbience();
void ServiceTrack(CVehicle *veh, CPed *ped);
bool UsesPoliceRadio(CVehicle *veh);
bool UsesTaxiRadio(CVehicle *veh);
bool8 UsesPoliceRadio(CVehicle *veh);
bool8 UsesTaxiRadio(CVehicle *veh);
uint32 GetTrackStartPos(uint32 track);
void ComputeAmbienceVol(uint8 reset, uint8& outVolume);
bool ServiceAnnouncement();
void ComputeAmbienceVol(bool8 reset, uint8& outVolume);
bool8 ServiceAnnouncement();
uint32 GetCarTuning();
uint32 GetNextCarTuning();
bool ChangeRadioChannel();
bool8 ChangeRadioChannel();
void RecordRadioStats();
void SetUpCorrectAmbienceTrack();
float *GetListenTimeArray();
@ -100,7 +100,7 @@ public:
uint32 GetFavouriteRadioStation();
void SetMalibuClubTrackPos(uint8 pos);
void SetStripClubTrackPos(uint8 pos);
bool CheckForMusicInterruptions();
bool8 CheckForMusicInterruptions();
void Enable();
void Disable();
@ -109,5 +109,5 @@ public:
VALIDATE_SIZE(cMusicManager, 0x95C);
extern cMusicManager MusicManager;
extern bool g_bAnnouncementReadPosAlready; // we have a symbol of this so it was declared in .h
extern bool8 g_bAnnouncementReadPosAlready; // we have a symbol of this so it was declared in .h
float GetHeightScale();

View File

@ -7,7 +7,7 @@
#include "AudioSamples.h"
#include "MusicManager.h"
#include "PlayerPed.h"
#include "PoliceRadio.h"
#include "PolRadio.h"
#include "Replay.h"
#include "Vehicle.h"
#include "World.h"
@ -15,9 +15,6 @@
#include "sampman.h"
#include "Wanted.h"
const int channels = ARRAY_SIZE(AudioManager.m_asActiveSamples);
const int policeChannel = channels + 1;
struct tPoliceRadioZone {
char m_aName[8];
uint32 m_nSampleIndex;
@ -48,8 +45,8 @@ cAudioManager::InitialisePoliceRadioZones()
SETZONESFX(4, "BEACH2", SFX_POLICE_RADIO_WASHINGTON_BEACH);
SETZONESFX(5, "BEACH3", SFX_POLICE_RADIO_VICE_POINT);
SETZONESFX(6, "GOLFC", SFX_POLICE_RADIO_LEAF_LINKS);
SETZONESFX(7, "STARI", SFX_POLICE_RADIO_STRAFISH_ISLAND);
SETZONESFX(8, "DOCKS", SFX_POLICE_RADIO_VICE_PORT);
SETZONESFX(7, "STARI", SFX_POLICE_RADIO_STARFISH_ISLAND);
SETZONESFX(8, "DOCKS", SFX_POLICE_RADIO_VICEPORT);
SETZONESFX(9, "HAVANA", SFX_POLICE_RADIO_LITTLE_HAVANA);
SETZONESFX(10, "HAITI", SFX_POLICE_RADIO_LITTLE_HAITI);
SETZONESFX(11, "PORNI", SFX_POLICE_RADIO_PRAWN_ISLAND);
@ -68,8 +65,8 @@ cAudioManager::InitialisePoliceRadio()
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
SampleManager.SetChannelReverbFlag(policeChannel, false);
gSpecialSuspectLastSeenReport = false;
SampleManager.SetChannelReverbFlag(CHANNEL_POLICE_RADIO, FALSE);
gSpecialSuspectLastSeenReport = FALSE;
for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++)
gMinTimeToNextReport[i] = m_FrameCounter;
}
@ -78,7 +75,7 @@ void
cAudioManager::ResetPoliceRadio()
{
if (!m_bIsInitialised) return;
if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
InitialisePoliceRadio();
}
@ -105,19 +102,18 @@ cAudioManager::DoPoliceRadioCrackle()
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_RADIO_CRACKLE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = true;
m_sQueueSample.m_bIs2D = TRUE;
m_sQueueSample.m_nReleasingVolumeModificator = 10;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_nVolume = m_anRandomTable[2] % 20 + 15;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = false;
SET_LOOP_OFFSETS(SFX_POLICE_RADIO_CRACKLE)
m_sQueueSample.m_bReleasingSoundFlag = FALSE;
m_sQueueSample.m_bReverbFlag = FALSE;
m_sQueueSample.m_nOffset = 63;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_bRequireReflection = FALSE;
AddSampleToRequestedQueue();
}
@ -130,7 +126,7 @@ cAudioManager::ServicePoliceRadio()
if(!m_bIsInitialised) return;
if(m_nUserPause == 0) {
bool crimeReport = SetupCrimeReport();
bool8 crimeReport = SetupCrimeReport();
#ifdef FIX_BUGS // Crash at 0x5fe6ef
if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
return;
@ -141,7 +137,11 @@ cAudioManager::ServicePoliceRadio()
if (!crimeReport) {
if (wantedLevel != 0) {
if (nLastSeen != 0)
#ifdef FIX_BUGS
nLastSeen -= CTimer::GetLogicalFramesPassed();
#else
--nLastSeen;
#endif
else {
nLastSeen = m_anRandomTable[1] % 1000 + 2000;
SetupSuspectLastSeenReport();
@ -156,31 +156,35 @@ cAudioManager::ServicePoliceRadio()
void
cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
{
bool processed = false;
bool8 processed = FALSE;
uint32 sample;
int32 freq;
static int cWait = 0;
static bool bChannelOpen = false;
static bool8 bChannelOpen = FALSE;
static uint8 bMissionAudioPhysicalPlayingStatus = 0;
static int32 PoliceChannelFreq = 22050;
if (!m_bIsInitialised) return;
if (m_nUserPause != 0) {
if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1 &&
SampleManager.IsStreamPlaying(1)) {
SampleManager.PauseStream(1, 1);
SampleManager.PauseStream(TRUE, 1);
}
} else {
if (m_nPreviousUserPause && g_nMissionAudioSfx != NO_SAMPLE &&
bMissionAudioPhysicalPlayingStatus == 1) {
SampleManager.PauseStream(0, 1);
SampleManager.PauseStream(FALSE, 1);
}
if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = false;
if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = FALSE;
if (cWait) {
#ifdef FIX_BUGS
cWait -= CTimer::GetLogicalFramesPassed();
#else
--cWait;
#endif
return;
}
if (g_nMissionAudioSfx != NO_SAMPLE && !bChannelOpen) {
@ -200,9 +204,9 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
}
return;
}
} else if (!SampleManager.GetChannelUsedFlag(policeChannel)) {
} else if (!SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) {
SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 1);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE, 1);
SampleManager.StartPreloadedStreamedFile(1);
g_nMissionAudioPlayingStatus = 1;
bMissionAudioPhysicalPlayingStatus = 0;
@ -211,7 +215,7 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
}
if (bChannelOpen) DoPoliceRadioCrackle();
if ((g_nMissionAudioSfx == NO_SAMPLE || g_nMissionAudioPlayingStatus != 1) &&
!SampleManager.GetChannelUsedFlag(policeChannel) && m_sPoliceRadioQueue.policeChannelTimer) {
!SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO) && m_sPoliceRadioQueue.policeChannelTimer) {
if (m_sPoliceRadioQueue.policeChannelTimer) {
sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds];
m_sPoliceRadioQueue.policeChannelTimer--;
@ -223,35 +227,35 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
if (gSpecialSuspectLastSeenReport) {
gSpecialSuspectLastSeenReport = 0;
} else if (sample == SFX_POLICE_RADIO_MESSAGE_NOISE_1) {
bChannelOpen = false;
processed = true;
bChannelOpen = FALSE;
processed = TRUE;
}
}
if (sample == NO_SAMPLE) {
if (!processed) cWait = 30;
} else {
SampleManager.InitialiseChannel(policeChannel, sample, 0);
SampleManager.InitialiseChannel(CHANNEL_POLICE_RADIO, sample, SFX_BANK_0);
switch (sample) {
case SFX_POLICE_RADIO_MESSAGE_NOISE_1:
freq = m_anRandomTable[4] % 2000 + 10025;
bChannelOpen = bChannelOpen == false;
bChannelOpen = bChannelOpen == FALSE;
break;
default: freq = SampleManager.GetSampleBaseFrequency(sample); break;
}
PoliceChannelFreq = freq;
SampleManager.SetChannelFrequency(policeChannel, freq);
SampleManager.SetChannelVolume(policeChannel, 100);
SampleManager.SetChannelPan(policeChannel, 63);
SampleManager.SetChannelLoopCount(policeChannel, 1);
SampleManager.SetChannelLoopPoints(policeChannel, 0, -1);
SampleManager.StartChannel(policeChannel);
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq);
SampleManager.SetChannelVolume(CHANNEL_POLICE_RADIO, 100);
SampleManager.SetChannelPan(CHANNEL_POLICE_RADIO, 63);
SampleManager.SetChannelLoopCount(CHANNEL_POLICE_RADIO, 1);
SampleManager.SetChannelLoopPoints(CHANNEL_POLICE_RADIO, 0, -1);
SampleManager.StartChannel(CHANNEL_POLICE_RADIO);
}
if (processed) ResetPoliceRadio();
}
}
}
bool
bool8
cAudioManager::SetupCrimeReport()
{
int16 audioZoneId;
@ -264,13 +268,13 @@ cAudioManager::SetupCrimeReport()
float quarterY;
int i;
int32 sampleIndex;
bool processed = false;
bool8 processed = FALSE;
if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) return false;
if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) return FALSE;
if (60 - m_sPoliceRadioQueue.policeChannelTimer <= 9) {
AgeCrimes();
return true;
return TRUE;
}
for (i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
@ -278,7 +282,7 @@ cAudioManager::SetupCrimeReport()
break;
}
if (i == ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) return false;
if (i == ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) return FALSE;
audioZoneId = CTheZones::FindAudioZone(&m_sPoliceRadioQueue.crimes[i].position);
if (audioZoneId >= 0 && audioZoneId < NUMAUDIOZONES) {
zone = CTheZones::GetAudioZone(audioZoneId);
@ -317,10 +321,10 @@ cAudioManager::SetupCrimeReport()
if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) {
m_sPoliceRadioQueue.Add(SFX_NORTH);
processed = true;
processed = TRUE;
} else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) {
m_sPoliceRadioQueue.Add(SFX_SOUTH);
processed = true;
processed = TRUE;
}
if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX)
@ -339,7 +343,7 @@ cAudioManager::SetupCrimeReport()
}
m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
AgeCrimes();
return true;
return TRUE;
}
void
@ -479,7 +483,7 @@ cAudioManager::SetupSuspectLastSeenReport()
case MI_SABRETUR:
case MI_VIRGO:
case MI_BLISTAC:
sample = SFX_POLICE_RADIO_2_DOOR;
sample = SFX_POLICE_RADIO_TUDOOR;
break;
case MI_STINGER:
case MI_INFERNUS:
@ -688,7 +692,7 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
float quarterX;
float quarterY;
int32 sample;
bool processed = false;
bool8 processed = FALSE;
CVector vec = CVector(x, y, z);
if (!m_bIsInitialised) return;
@ -713,10 +717,10 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
if (vec.y > halfY + quarterY) {
m_sPoliceRadioQueue.Add(SFX_NORTH);
processed = true;
processed = TRUE;
} else if (vec.y < halfY - quarterY) {
m_sPoliceRadioQueue.Add(SFX_SOUTH);
processed = true;
processed = TRUE;
}
if (vec.x > halfX + quarterX)
@ -728,7 +732,7 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
m_sPoliceRadioQueue.Add(sample);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(NO_SAMPLE);
gSpecialSuspectLastSeenReport = true;
gSpecialSuspectLastSeenReport = TRUE;
break;
}
}

View File

@ -1295,3 +1295,26 @@ enum eAudioType
AUDIOTYPE_POLICERADIO,
TOTAL_AUDIO_TYPES,
};
#ifdef GTA_PS2
enum
{
NUM_CHANNELS_GENERIC = 42,
CHANNEL_POLICE_RADIO = NUM_CHANNELS_GENERIC,
CHANNEL_MISSION_AUDIO_1,
CHANNEL_MISSION_AUDIO_2,
CHANNEL_PLAYER_VEHICLE_ENGINE,
NUM_CHANNELS
};
#else
enum
{
#ifdef PS2_AUDIO_CHANNELS
NUM_CHANNELS_GENERIC = 42,
#else
NUM_CHANNELS_GENERIC = 27,
#endif
CHANNEL_POLICE_RADIO,
NUM_CHANNELS
};
#endif

View File

@ -24,12 +24,6 @@
#include "aldlist.h"
#ifndef _WIN32
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#define _strdup strdup
#endif
#ifdef AUDIO_OAL
/*
* Init call
@ -47,8 +41,8 @@ ALDeviceList::ALDeviceList()
defaultDeviceIndex = 0;
if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) {
devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
devices = (char *)alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
index = 0;
// go through device list (each device terminated with a single NULL, list terminated with double NULL)
@ -62,17 +56,11 @@ ALDeviceList::ALDeviceList()
if (context) {
alcMakeContextCurrent(context);
// if new actual device name isn't already in the list, then add it...
actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
bool bNewName = true;
for (unsigned int i = 0; i < GetNumDevices(); i++) {
if (strcmp(GetDeviceName(i), actualDeviceName) == 0) {
bNewName = false;
}
}
if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
ALDEVICEINFO ALDeviceInfo;
actualDeviceName = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
if ((actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
ALDEVICEINFO &ALDeviceInfo = aDeviceInfo[nNumOfDevices++];
ALDeviceInfo.bSelected = true;
ALDeviceInfo.strDeviceName = _strdup(actualDeviceName);
ALDeviceInfo.SetName(actualDeviceName);
alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);
@ -105,8 +93,6 @@ ALDeviceList::ALDeviceList()
// Get Source Count
ALDeviceInfo.uiSourceCount = GetMaxNumSources();
aDeviceInfo[nNumOfDevices++] = ALDeviceInfo;
}
alcMakeContextCurrent(NULL);
alcDestroyContext(context);

View File

@ -21,7 +21,7 @@ enum
};
struct ALDEVICEINFO {
const char *strDeviceName;
char *strDeviceName;
int iMajorVersion;
int iMinorVersion;
unsigned int uiSourceCount;
@ -33,6 +33,19 @@ struct ALDEVICEINFO {
strDeviceName = NULL;
Extensions = 0;
}
~ALDEVICEINFO()
{
delete[] strDeviceName;
strDeviceName = NULL;
}
void SetName(const char *name)
{
if(strDeviceName) delete[] strDeviceName;
strDeviceName = new char[strlen(name) + 1];
strcpy(strDeviceName, name);
}
};
typedef ALDEVICEINFO *LPALDEVICEINFO;

View File

@ -10,20 +10,22 @@
extern bool IsFXSupported();
ALuint alSources[MAXCHANNELS+MAX2DCHANNELS];
ALuint alFilters[MAXCHANNELS+MAX2DCHANNELS];
ALuint alBuffers[MAXCHANNELS+MAX2DCHANNELS];
ALuint alSources[NUM_CHANNELS];
ALuint alFilters[NUM_CHANNELS];
ALuint alBuffers[NUM_CHANNELS];
bool bChannelsCreated = false;
int32 CChannel::channelsThatNeedService = 0;
uint8 tempStereoBuffer[PED_BLOCKSIZE * 2];
void
CChannel::InitChannels()
{
alGenSources(MAXCHANNELS+MAX2DCHANNELS, alSources);
alGenBuffers(MAXCHANNELS+MAX2DCHANNELS, alBuffers);
alGenSources(NUM_CHANNELS, alSources);
alGenBuffers(NUM_CHANNELS, alBuffers);
if (IsFXSupported())
alGenFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters);
alGenFilters(NUM_CHANNELS, alFilters);
bChannelsCreated = true;
}
@ -32,13 +34,13 @@ CChannel::DestroyChannels()
{
if (bChannelsCreated)
{
alDeleteSources(MAXCHANNELS + MAX2DCHANNELS, alSources);
alDeleteSources(NUM_CHANNELS, alSources);
memset(alSources, 0, sizeof(alSources));
alDeleteBuffers(MAXCHANNELS + MAX2DCHANNELS, alBuffers);
alDeleteBuffers(NUM_CHANNELS, alBuffers);
memset(alBuffers, 0, sizeof(alBuffers));
if (IsFXSupported())
{
alDeleteFilters(MAXCHANNELS + MAX2DCHANNELS, alFilters);
alDeleteFilters(NUM_CHANNELS, alFilters);
memset(alFilters, 0, sizeof(alFilters));
}
bChannelsCreated = false;
@ -50,6 +52,7 @@ CChannel::CChannel()
{
Data = nil;
DataSize = 0;
bIs2D = false;
SetDefault();
}
@ -90,6 +93,7 @@ void CChannel::Init(uint32 _id, bool Is2D)
if ( Is2D )
{
bIs2D = true;
alSource3f(alSources[id], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(alSources[id], AL_GAIN, 1.0f);
}
@ -113,7 +117,20 @@ void CChannel::Start()
if ( !HasSource() ) return;
if ( !Data ) return;
alBufferData(alBuffers[id], AL_FORMAT_MONO16, Data, DataSize, Frequency);
if ( bIs2D )
{
// convert mono data to stereo
int16 *monoData = (int16*)Data;
int16 *stereoData = (int16*)tempStereoBuffer;
for (size_t i = 0; i < DataSize / 2; i++)
{
*(stereoData++) = *monoData;
*(stereoData++) = *(monoData++);
}
alBufferData(alBuffers[id], AL_FORMAT_STEREO16, tempStereoBuffer, DataSize * 2, Frequency);
}
else
alBufferData(alBuffers[id], AL_FORMAT_MONO16, Data, DataSize, Frequency);
if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 )
alBufferiv(alBuffers[id], AL_LOOP_POINTS_SOFT, LoopPoints);
alSourcei(alSources[id], AL_BUFFER, alBuffers[id]);

View File

@ -20,6 +20,7 @@ class CChannel
int32 LoopCount;
ALint LoopPoints[2];
ALint LastProcessedOffset;
bool bIs2D;
public:
static int32 channelsThatNeedService;

View File

@ -1,9 +1,7 @@
#include "common.h"
#ifdef AUDIO_OAL
#include "stream.h"
#include "sampman.h"
#include <stdio.h>
#include <malloc.h>
#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK
@ -28,6 +26,29 @@
#include <opusfile.h>
#endif
#include <queue>
#include <utility>
#ifdef MULTITHREADED_AUDIO
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "MusicManager.h"
#include "stream.h"
std::thread gAudioThread;
std::mutex gAudioThreadQueueMutex;
std::condition_variable gAudioThreadCv;
bool gAudioThreadTerm = false;
std::queue<CStream*> gStreamsToProcess; // values are not unique, we will handle that ourself
std::queue<std::pair<IDecoder*, void*>> gStreamsToClose;
#else
#include "stream.h"
#endif
#include "sampman.h"
#ifndef _WIN32
#include "crossplatform.h"
#endif
@ -45,6 +66,10 @@ class CSortStereoBuffer
{
uint16* PcmBuf;
size_t BufSize;
//#ifdef MULTITHREADED_AUDIO
// std::mutex Mutex;
//#endif
public:
CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {}
~CSortStereoBuffer()
@ -71,6 +96,9 @@ public:
void SortStereo(void* buf, size_t size)
{
//#ifdef MULTITHREADED_AUDIO
// std::lock_guard<std::mutex> lock(Mutex);
//#endif
uint16* InBuf = (uint16*)buf;
uint16* OutBuf = GetBuffer(size);
@ -140,7 +168,7 @@ public:
else
StepIndex--;
StepIndex = clamp(StepIndex, 0, 88);
StepIndex = Clamp(StepIndex, 0, 88);
int delta = step >> 3;
if (adpcm & 1) delta += step >> 2;
@ -149,7 +177,7 @@ public:
if (adpcm & 8) delta = -delta;
int newSample = Sample + delta;
Sample = clamp(newSample, -32768, 32767);
Sample = Clamp(newSample, -32768, 32767);
return Sample;
}
};
@ -285,6 +313,10 @@ public:
#undef CLOSE_ON_ERROR
}
void FileOpen()
{
}
~CWavFile()
{
Close();
@ -295,6 +327,7 @@ public:
return m_bIsOpen;
}
uint32 GetSampleSize()
{
return sizeof(uint16);
@ -464,6 +497,10 @@ public:
m_pfSound = sf_open_virtual(&vio, SFM_READ, &m_soundInfo, m_fileHandle);
}
void FileOpen()
{
}
~CSndFile()
{
if ( m_pfSound )
@ -642,18 +679,6 @@ public:
#endif
#ifdef AUDIO_OAL_USE_MPG123
// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though)
//#define MP3_USE_FUZZY_SEEK
static ssize_t mpg123_read_replacement(void* handle, void* data, size_t size)
{
return fread(data, 1, size, (FILE*)handle);
}
static off_t mpg123_seek_replacement(void* handle, off_t offset, int whence)
{
fseek((FILE*)handle, (uint32) offset, whence);
return ftell((FILE*)handle);
}
class CMP3File : public IDecoder
{
@ -662,62 +687,58 @@ protected:
bool m_bOpened;
uint32 m_nRate;
uint32 m_nChannels;
FILE* m_fileHandle;
char* m_buffer;
const char* m_pPath;
bool m_bFileNotOpenedYet;
CMP3File() :
m_pMH(nil),
m_bOpened(false),
m_nRate(0),
m_nChannels(0),
m_fileHandle(NULL),
m_buffer(NULL) {}
m_bFileNotOpenedYet(false),
m_nChannels(0) {}
public:
CMP3File(const char *path) :
m_pMH(nil),
m_bOpened(false),
m_nRate(0),
m_nChannels(0),
m_fileHandle(NULL),
m_buffer(NULL)
m_pPath(path),
m_bFileNotOpenedYet(false)
{
m_pMH = mpg123_new(nil, nil);
if ( m_pMH )
{
#ifdef MP3_USE_FUZZY_SEEK
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0);
#else
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
m_bOpened = true;
m_bFileNotOpenedYet = true;
// It's possible to move this to audioFileOpsThread(), but effect isn't noticable + probably not compatible with our current cutscene audio handling
#if 1
FileOpen();
#endif
long rate = 0;
int channels = 0;
int encoding = 0;
m_buffer = (char*) memalign(0x40, IO_BUFFER_SIZE);
m_fileHandle = fopen(path, "rb");
if (!m_fileHandle) {
m_bOpened = false;
return;
}
setvbuf(m_fileHandle, m_buffer, _IOFBF, IO_BUFFER_SIZE);
m_bOpened = mpg123_replace_reader_handle(m_pMH, mpg123_read_replacement, mpg123_seek_replacement, NULL) == MPG123_OK
&& mpg123_open_handle(m_pMH, m_fileHandle) == MPG123_OK
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if ( IsOpened() )
{
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
}
}
void FileOpen()
{
if(!m_bFileNotOpenedYet) return;
long rate = 0;
int channels = 0;
int encoding = 0;
m_bOpened = mpg123_open(m_pMH, m_pPath) == MPG123_OK
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if(IsOpened()) {
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
m_bFileNotOpenedYet = false;
}
~CMP3File()
{
if ( m_pMH )
@ -725,13 +746,6 @@ public:
mpg123_close(m_pMH);
mpg123_delete(m_pMH);
if (m_fileHandle) {
fclose(m_fileHandle);
}
free(m_buffer);
m_fileHandle = nil;
m_buffer = nil;
m_pMH = nil;
}
}
@ -748,7 +762,7 @@ public:
uint32 GetSampleCount()
{
if ( !IsOpened() ) return 0;
if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
return mpg123_length(m_pMH);
}
@ -764,19 +778,19 @@ public:
void Seek(uint32 milliseconds)
{
if ( !IsOpened() ) return;
if ( !IsOpened() || m_bFileNotOpenedYet ) return;
mpg123_seek(m_pMH, ms2samples(milliseconds), SEEK_SET);
}
uint32 Tell()
{
if ( !IsOpened() ) return 0;
if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
return samples2ms(mpg123_tell(m_pMH));
}
uint32 Decode(void *buffer)
{
if ( !IsOpened() ) return 0;
if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
size_t size;
int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size);
@ -805,43 +819,52 @@ class CADFFile : public CMP3File
fseek((FILE*)fh, pos, seekType);
return ftell((FILE*)fh);
}
static void r_close(void* fh)
{
fclose((FILE*)fh);
}
public:
CADFFile(const char* path)
{
m_pMH = mpg123_new(nil, nil);
if (m_pMH)
{
#ifdef MP3_USE_FUZZY_SEEK
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0);
#else
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
m_bOpened = true;
m_bFileNotOpenedYet = true;
m_pPath = path;
// It's possible to move this to audioFileOpsThread(), but effect isn't noticable + probably not compatible with our current cutscene audio handling
#if 1
FileOpen();
#endif
long rate = 0;
int channels = 0;
int encoding = 0;
m_buffer = (char*) memalign(0x40, IO_BUFFER_SIZE);
FILE* m_fileHandle = fopen(path, "rb");
if (!m_fileHandle) {
m_bOpened = false;
return;
}
setvbuf(m_fileHandle, m_buffer, _IOFBF, IO_BUFFER_SIZE);
m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, NULL) == MPG123_OK
&& mpg123_open_handle(m_pMH, m_fileHandle) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if (IsOpened())
{
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
}
}
void FileOpen()
{
if(!m_bFileNotOpenedYet) return;
long rate = 0;
int channels = 0;
int encoding = 0;
FILE *f = fopen(m_pPath, "rb");
m_bOpened = f && mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK
&& mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if(IsOpened()) {
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
m_bFileNotOpenedYet = false;
}
};
#endif
@ -872,7 +895,7 @@ public:
static short quantize(double sample)
{
int a = int(sample + 0.5);
return short(clamp(a, -32768, 32767));
return short(Clamp(a, -32768, 32767));
}
void Decode(void* _inbuf, int16* _outbuf, size_t size)
@ -966,6 +989,10 @@ public:
m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE];
}
void FileOpen()
{
}
~CVbFile()
{
if (m_pFile)
@ -1120,6 +1147,10 @@ public:
}
}
void FileOpen()
{
}
~COpusFile()
{
if (m_FileH)
@ -1184,11 +1215,173 @@ public:
};
#endif
// For multi-thread: Someone always acquire stream's mutex before entering here
void
CStream::BuffersShouldBeFilled()
{
#ifdef MULTITHREADED_AUDIO
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
std::queue<std::pair<ALuint, ALuint>> tempQueue;
for(int i = 0; i < NUM_STREAMBUFFERS / 2; i++) {
tempQueue.push(std::pair<ALuint, ALuint>(m_alBuffers[i * 2], m_alBuffers[i * 2 + 1]));
}
m_fillBuffers.swap(tempQueue);
FlagAsToBeProcessed();
m_bActive = true; // to allow Update() to queue the filled buffers & play
return;
}
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
#endif
if ( FillBuffers() != 0 )
{
SetPlay(true);
}
}
// returns whether it's queued (not on multi-thread)
bool
CStream::BufferShouldBeFilledAndQueued(std::pair<ALuint, ALuint>* bufs)
{
#ifdef MULTITHREADED_AUDIO
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE)
m_fillBuffers.push(*bufs);
else
#endif
{
ALuint alBuffers[2] = {(*bufs).first, (*bufs).second}; // left - right
if (FillBuffer(alBuffers)) {
alSourceQueueBuffers(m_pAlSources[0], 1, &alBuffers[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &alBuffers[1]);
return true;
}
}
return false;
}
#ifdef MULTITHREADED_AUDIO
void
CStream::FlagAsToBeProcessed(bool close)
{
if (!close && MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE)
return;
gAudioThreadQueueMutex.lock();
if (close)
gStreamsToClose.push(std::pair<IDecoder*, void*>(m_pSoundFile ? m_pSoundFile : nil, m_pBuffer ? m_pBuffer : nil));
else
gStreamsToProcess.push(this);
gAudioThreadQueueMutex.unlock();
gAudioThreadCv.notify_one();
}
void audioFileOpsThread()
{
do
{
CStream *stream;
{
// Just a semaphore
std::unique_lock<std::mutex> queueMutex(gAudioThreadQueueMutex);
gAudioThreadCv.wait(queueMutex, [] { return gStreamsToProcess.size() > 0 || gStreamsToClose.size() > 0 || gAudioThreadTerm; });
if (gAudioThreadTerm)
return;
if (!gStreamsToClose.empty()) {
auto streamToClose = gStreamsToClose.front();
gStreamsToClose.pop();
if (streamToClose.first) { // pSoundFile
delete streamToClose.first;
}
if (streamToClose.second) { // pBuffer
free(streamToClose.second);
}
}
if (!gStreamsToProcess.empty()) {
stream = gStreamsToProcess.front();
gStreamsToProcess.pop();
} else
continue;
}
std::unique_lock<std::mutex> lock(stream->m_mutex);
std::pair<ALuint, ALuint> buffers, *lastBufAddr;
bool insertBufsAfterCheck = false;
do {
if (!stream->IsOpened()) {
break;
}
if (stream->m_bReset)
break;
// We gave up this idea for now
/*
stream->m_pSoundFile->FileOpen();
// Deffered allocation, do it now
if (stream->m_pBuffer == nil) {
stream->m_pBuffer = malloc(stream->m_pSoundFile->GetBufferSize());
ASSERT(stream->m_pBuffer != nil);
}
*/
if (stream->m_bDoSeek) {
stream->m_bDoSeek = false;
int pos = stream->m_SeekPos;
lock.unlock();
stream->m_pSoundFile->Seek(pos);
lock.lock();
continue; // let's do the checks again, make sure we didn't miss anything while Seeking
}
if (insertBufsAfterCheck) {
stream->m_queueBuffers.push(buffers);
insertBufsAfterCheck = false;
}
if (!stream->m_fillBuffers.empty()) {
lastBufAddr = &stream->m_fillBuffers.front();
buffers = *lastBufAddr;
lock.unlock();
ALuint alBuffers[2] = {buffers.first, buffers.second}; // left - right
bool filled = stream->FillBuffer(alBuffers);
lock.lock();
// Make sure queue isn't touched after we released mutex
if (!stream->m_fillBuffers.empty() && lastBufAddr == &stream->m_fillBuffers.front()) {
stream->m_fillBuffers.pop();
if (filled)
insertBufsAfterCheck = true; // Also make sure stream's properties aren't changed. So make one more pass, and push it to m_queueBuffers only if it pass checks again.
}
} else
break;
} while (true);
} while(true);
}
#endif
void CStream::Initialise()
{
#ifdef AUDIO_OAL_USE_MPG123
mpg123_init();
#endif
#ifdef MULTITHREADED_AUDIO
gAudioThread = std::thread(audioFileOpsThread);
#endif
}
void CStream::Terminate()
@ -1196,14 +1389,27 @@ void CStream::Terminate()
#ifdef AUDIO_OAL_USE_MPG123
mpg123_exit();
#endif
#ifdef MULTITHREADED_AUDIO
gAudioThreadQueueMutex.lock();
gAudioThreadTerm = true;
gAudioThreadQueueMutex.unlock();
gAudioThreadCv.notify_one();
gAudioThread.join();
#endif
}
CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate) :
CStream::CStream(ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
m_pAlSources(sources),
m_alBuffers(buffers),
m_pBuffer(nil),
m_bPaused(false),
m_bActive(false),
#ifdef MULTITHREADED_AUDIO
m_bIExist(false),
m_bDoSeek(false),
m_SeekPos(0),
#endif
m_pSoundFile(nil),
m_bReset(false),
m_nVolume(0),
@ -1212,6 +1418,27 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
m_nLoopCount(1)
{
}
bool CStream::Open(const char* filename, uint32 overrideSampleRate)
{
if (IsOpened()) return false;
#ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex);
m_bDoSeek = false;
m_SeekPos = 0;
#endif
m_bPaused = false;
m_bActive = false;
m_bReset = false;
m_nVolume = 0;
m_nPan = 0;
m_nPosBeforeReset = 0;
m_nLoopCount = 1;
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
char *real = casepath(filename);
@ -1250,30 +1477,52 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
else
m_pSoundFile = nil;
if ( IsOpened() )
if ( m_pSoundFile && m_pSoundFile->IsOpened() )
{
m_pBuffer = malloc(m_pSoundFile->GetBufferSize());
ASSERT(m_pBuffer!=nil);
uint32 bufSize = m_pSoundFile->GetBufferSize();
if(bufSize != 0) { // Otherwise it's deferred
m_pBuffer = malloc(bufSize);
ASSERT(m_pBuffer != nil);
DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
DEV("Channels: %d\n", m_pSoundFile->GetChannels());
DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples());
DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate())));
DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
return;
DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
DEV("Channels: %d\n", m_pSoundFile->GetChannels());
DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples());
DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate())));
DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
}
#ifdef MULTITHREADED_AUDIO
m_bIExist = true;
#endif
return true;
}
return false;
}
CStream::~CStream()
{
Delete();
assert(!IsOpened());
}
void CStream::Delete()
void CStream::Close()
{
if(!IsOpened()) return;
#ifdef MULTITHREADED_AUDIO
{
std::lock_guard<std::mutex> lock(m_mutex);
Stop();
ClearBuffers();
m_bIExist = false;
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, mutex is acquired
}
FlagAsToBeProcessed(true);
#else
Stop();
ClearBuffers();
@ -1288,6 +1537,7 @@ void CStream::Delete()
free(m_pBuffer);
m_pBuffer = nil;
}
#endif
}
bool CStream::HasSource()
@ -1295,9 +1545,14 @@ bool CStream::HasSource()
return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE);
}
// m_bIExist only written in main thread, thus mutex is not needed on main thread
bool CStream::IsOpened()
{
#ifdef MULTITHREADED_AUDIO
return m_bIExist;
#else
return m_pSoundFile && m_pSoundFile->IsOpened();
#endif
}
bool CStream::IsPlaying()
@ -1311,6 +1566,14 @@ bool CStream::IsPlaying()
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
return true;
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
// Streams are designed in such a way that m_fillBuffers and m_queueBuffers will be *always* filled if audio is playing, and mutex is acquired
if (!m_fillBuffers.empty() || !m_queueBuffers.emptyNts())
return true;
#endif
}
return false;
@ -1372,10 +1635,10 @@ void CStream::SetVolume(uint32 nVol)
void CStream::SetPan(uint8 nPan)
{
m_nPan = clamp((int8)nPan - 63, 0, 63);
m_nPan = Clamp((int8)nPan - 63, 0, 63);
SetPosition(0, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
m_nPan = clamp((int8)nPan + 64, 64, 127);
m_nPan = Clamp((int8)nPan + 64, 64, 127);
SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
m_nPan = nPan;
@ -1385,8 +1648,24 @@ void CStream::SetPan(uint8 nPan)
void CStream::SetPosMS(uint32 nPos)
{
if ( !IsOpened() ) return;
m_pSoundFile->Seek(nPos);
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, second thread always access it when stream mutex acquired
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
m_bDoSeek = true;
m_SeekPos = nPos;
} else
#endif
{
m_pSoundFile->Seek(nPos);
}
ClearBuffers();
// adding to gStreamsToProcess not needed, someone always calls Start() / BuffersShouldBeFilled() after SetPosMS
}
uint32 CStream::GetPosMS()
@ -1394,10 +1673,16 @@ uint32 CStream::GetPosMS()
if ( !HasSource() ) return 0;
if ( !IsOpened() ) return 0;
// Deferred init causes division by zero
if (m_pSoundFile->GetChannels() == 0)
return 0;
ALint offset;
//alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset);
//std::lock_guard<std::mutex> lock(m_mutex);
return m_pSoundFile->Tell()
- m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels()
+ m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels();
@ -1411,6 +1696,7 @@ uint32 CStream::GetLengthMS()
bool CStream::FillBuffer(ALuint *alBuffer)
{
#ifndef MULTITHREADED_AUDIO
if ( !HasSource() )
return false;
if ( !IsOpened() )
@ -1419,6 +1705,7 @@ bool CStream::FillBuffer(ALuint *alBuffer)
return false;
if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) )
return false;
#endif
uint32 size = m_pSoundFile->Decode(m_pBuffer);
if( size == 0 )
@ -1435,6 +1722,26 @@ bool CStream::FillBuffer(ALuint *alBuffer)
return true;
}
#ifdef MULTITHREADED_AUDIO
bool CStream::QueueBuffers()
{
bool buffersQueued = false;
std::pair<ALuint, ALuint> buffers;
while (m_queueBuffers.peekPop(&buffers)) // beware: m_queueBuffers is tsQueue
{
ALuint leftBuf = buffers.first;
ALuint rightBuf = buffers.second;
alSourceQueueBuffers(m_pAlSources[0], 1, &leftBuf);
alSourceQueueBuffers(m_pAlSources[1], 1, &rightBuf);
buffersQueued = true;
}
return buffersQueued;
}
#endif
// Only used in single-threaded audio or cutscene audio
int32 CStream::FillBuffers()
{
int32 i = 0;
@ -1464,17 +1771,33 @@ void CStream::ClearBuffers()
alSourceUnqueueBuffers(m_pAlSources[1], 1, &value);
}
bool CStream::Setup(bool imSureQueueIsEmpty)
bool CStream::Setup(bool imSureQueueIsEmpty, bool lock)
{
if ( IsOpened() )
{
alSourcei(m_pAlSources[0], AL_LOOPING, AL_FALSE);
alSourcei(m_pAlSources[1], AL_LOOPING, AL_FALSE);
#ifdef MULTITHREADED_AUDIO
if (lock)
m_mutex.lock();
#endif
if (!imSureQueueIsEmpty) {
SetPlay(false);
Stop();
ClearBuffers();
}
#ifdef MULTITHREADED_AUDIO
if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) {
m_pSoundFile->Seek(0);
} else {
m_bDoSeek = true;
m_SeekPos = 0;
}
if (lock)
m_mutex.unlock();
#else
m_pSoundFile->Seek(0);
#endif
//SetPosition(0.0f, 0.0f, 0.0f);
SetPitch(1.0f);
//SetPan(m_nPan);
@ -1512,7 +1835,7 @@ void CStream::SetPlay(bool state)
{
ALint sourceState = AL_STOPPED;
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState);
if (sourceState != AL_STOPPED )
if (sourceState != AL_STOPPED)
alSourceStop(m_pAlSources[0]);
sourceState = AL_STOPPED;
@ -1527,8 +1850,12 @@ void CStream::SetPlay(bool state)
void CStream::Start()
{
if ( !HasSource() ) return;
if ( FillBuffers() != 0 )
SetPlay(true);
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, second thread always access it when stream mutex acquired
#endif
BuffersShouldBeFilled();
}
void CStream::Stop()
@ -1550,8 +1877,22 @@ void CStream::Update()
if ( !m_bPaused )
{
ALint totalBuffers[2] = { 0, 0 };
ALint buffersProcessed[2] = { 0, 0 };
bool buffersQueuedAndStarted = false;
bool buffersQueuedButNotStarted = false;
#ifdef MULTITHREADED_AUDIO
// Put it in here because we need totalBuffers after queueing to decide when to loop audio
if (m_bActive)
{
buffersQueuedAndStarted = QueueBuffers();
if(buffersQueuedAndStarted) {
SetPlay(true);
}
}
#endif
ALint totalBuffers[2] = {0, 0};
ALint buffersProcessed[2] = {0, 0};
// Relying a lot on left buffer states in here
@ -1572,36 +1913,58 @@ void CStream::Update()
// AL_BUFFERS_PROCESSED = Index of the buffer being processing right now. Buffers coming after that(have greater index) are pending buffers.
// which means: totalBuffers[0] - buffersProcessed[0] = pending buffers
bool buffersRefilled = false;
// We should wait queue to be cleared to loop track, because position calculation relies on queue.
if (m_nLoopCount != 1 && m_bActive && totalBuffers[0] == 0)
{
Setup(true);
buffersRefilled = FillBuffers() != 0;
if (m_nLoopCount != 0)
m_nLoopCount--;
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
if (m_fillBuffers.empty() && m_queueBuffers.emptyNts()) // we already acquired stream mutex, which is enough for second thread. thus Nts variant
#endif
{
Setup(true, false);
BuffersShouldBeFilled(); // will also call SetPlay(true)
if (m_nLoopCount != 0)
m_nLoopCount--;
}
}
else
{
while( buffersProcessed[0]-- )
static std::queue<std::pair<ALuint, ALuint>> tempFillBuffer;
while ( buffersProcessed[0]-- )
{
ALuint buffer[2];
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
if (m_bActive && FillBuffer(buffer))
if (m_bActive)
{
buffersRefilled = true;
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
tempFillBuffer.push(std::pair<ALuint, ALuint>(buffer[0], buffer[1]));
}
}
if (m_bActive && buffersProcessed[1])
{
#ifdef MULTITHREADED_AUDIO
m_mutex.lock();
#endif
while (!tempFillBuffer.empty()) {
auto elem = tempFillBuffer.front();
tempFillBuffer.pop();
buffersQueuedButNotStarted = BufferShouldBeFilledAndQueued(&elem);
}
#ifdef MULTITHREADED_AUDIO
m_mutex.unlock();
FlagAsToBeProcessed();
#endif
}
}
// Two reasons: 1-Source may be starved to audio and stopped itself, 2- We're already waiting it to starve and die for looping track!
if (m_bActive && (buffersRefilled || (totalBuffers[1] - buffersProcessed[1] != 0)))
// Source may be starved to audio and stopped itself
if (m_bActive && !buffersQueuedAndStarted && (buffersQueuedButNotStarted || (totalBuffers[1] - buffersProcessed[1] != 0)))
SetPlay(true);
}
}
@ -1610,28 +1973,45 @@ void CStream::ProviderInit()
{
if ( m_bReset )
{
if ( Setup(true) )
if ( Setup(true, false) ) // lock not needed, thread can't process streams with m_bReset set
{
SetPan(m_nPan);
SetVolume(m_nVolume);
SetLoopCount(m_nLoopCount);
SetPosMS(m_nPosBeforeReset);
if (m_bActive)
FillBuffers();
SetPlay(m_bActive);
if ( m_bPaused )
Pause();
}
#ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex);
#endif
if(m_bActive)
BuffersShouldBeFilled();
m_bReset = false;
if (m_bPaused)
Pause();
m_bReset = false;
} else {
#ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex);
#endif
m_bReset = false;
}
}
}
void CStream::ProviderTerm()
{
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
// unlike Close() we will reuse this stream, so clearing queues are important.
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // stream mutex is already acquired, thus Nts variant
#endif
m_bReset = true;
m_nPosBeforeReset = GetPosMS();
Stop();
ClearBuffers();
}

View File

@ -11,6 +11,7 @@ public:
virtual ~IDecoder() { }
virtual bool IsOpened() = 0;
virtual void FileOpen() = 0;
virtual uint32 GetSampleSize() = 0;
virtual uint32 GetSampleCount() = 0;
@ -48,12 +49,70 @@ public:
uint32 GetLength()
{
FileOpen(); // abort deferred init, we need length now - game has to cache audio file sizes
return float(GetSampleCount()) * 1000.0f / float(GetSampleRate());
}
virtual uint32 Decode(void *buffer) = 0;
};
#ifdef MULTITHREADED_AUDIO
template <typename T> class tsQueue
{
public:
tsQueue() : count(0) { }
void push(const T &value)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(value);
count++;
}
bool peekPop(T *retVal)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (count == 0)
return false;
*retVal = m_queue.front();
m_queue.pop();
count--;
return true;
}
void swapNts(tsQueue<T> &replaceWith)
{
m_queue.swap(replaceWith.m_queue);
replaceWith.count = count;
}
/*
void swapTs(tsQueue<T> &replaceWith)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock2(replaceWith.m_mutex);
swapNts(replaceWith);
}
*/
bool emptyNts()
{
return count == 0;
}
/*
bool emptyTs()
{
std::lock_guard<std::mutex> lock(m_mutex);
return emptyNts();
}
*/
std::queue<T> m_queue;
int count;
mutable std::mutex m_mutex;
};
#endif
class CStream
{
char m_aFilename[128];
@ -63,6 +122,17 @@ class CStream
bool m_bPaused;
bool m_bActive;
public:
#ifdef MULTITHREADED_AUDIO
std::mutex m_mutex;
std::queue<std::pair<ALuint, ALuint>> m_fillBuffers; // left and right buffer
tsQueue<std::pair<ALuint, ALuint>> m_queueBuffers;
// std::condition_variable m_closeCv;
bool m_bDoSeek;
uint32 m_SeekPos;
bool m_bIExist;
#endif
void *m_pBuffer;
bool m_bReset;
@ -73,6 +143,13 @@ class CStream
IDecoder *m_pSoundFile;
void BuffersShouldBeFilled(); // all
bool BufferShouldBeFilledAndQueued(std::pair<ALuint, ALuint>*); // two (left-right)
#ifdef MULTITHREADED_AUDIO
void FlagAsToBeProcessed(bool close = false);
bool QueueBuffers();
#endif
bool HasSource();
void SetPosition(int i, float x, float y, float z);
void SetPitch(float pitch);
@ -81,15 +158,17 @@ class CStream
void SetPlay(bool state);
bool FillBuffer(ALuint *alBuffer);
int32 FillBuffers();
int32 FillBuffers();
void ClearBuffers();
public:
//public:
static void Initialise();
static void Terminate();
CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate = 32000);
CStream(ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS]);
~CStream();
void Delete();
bool Open(const char *filename, uint32 overrideSampleRate = 32000);
void Close();
bool IsOpened();
bool IsPlaying();
@ -100,13 +179,12 @@ public:
uint32 GetPosMS();
uint32 GetLengthMS();
bool Setup(bool imSureQueueIsEmpty = false);
bool Setup(bool imSureQueueIsEmpty = false, bool lock = true);
void Start();
void Stop();
void Update(void);
void SetLoopCount(int32);
void ProviderInit();
void ProviderTerm();
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#include "AudioManager.h"
cSampleManager SampleManager;
bool _bSampmanInitialised = false;
bool8 _bSampmanInitialised = FALSE;
uint32 BankStartOffset[MAX_SFX_BANKS];
uint32 nNumMP3s;
@ -60,7 +60,7 @@ int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
return 0;
}
bool
bool8
cSampleManager::IsMP3RadioChannelAvailable(void)
{
return nNumMP3s != 0;
@ -75,10 +75,10 @@ void cSampleManager::ReacquireDigitalHandle(void)
{
}
bool
bool8
cSampleManager::Initialise(void)
{
return true;
return TRUE;
}
void
@ -87,9 +87,9 @@ cSampleManager::Terminate(void)
}
bool cSampleManager::CheckForAnAudioFileOnCD(void)
bool8 cSampleManager::CheckForAnAudioFileOnCD(void)
{
return true;
return TRUE;
}
char cSampleManager::GetCDAudioDriveLetter(void)
@ -114,7 +114,7 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
cSampleManager::SetMusicMasterVolume(uint8 nVolume)
cSampleManager::SetMP3BoostVolume(uint8 nVolume)
{
}
@ -129,15 +129,15 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
}
void
cSampleManager::SetMonoMode(uint8 nMode)
cSampleManager::SetMonoMode(bool8 nMode)
{
}
bool
bool8
cSampleManager::LoadSampleBank(uint8 nBank)
{
ASSERT( nBank < MAX_SFX_BANKS );
return false;
return FALSE;
}
void
@ -146,20 +146,20 @@ cSampleManager::UnloadSampleBank(uint8 nBank)
ASSERT( nBank < MAX_SFX_BANKS );
}
bool
bool8
cSampleManager::IsSampleBankLoaded(uint8 nBank)
{
ASSERT( nBank < MAX_SFX_BANKS );
return false;
return FALSE;
}
bool
bool8
cSampleManager::IsPedCommentLoaded(uint32 nComment)
{
ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
return false;
return FALSE;
}
@ -169,11 +169,11 @@ cSampleManager::_GetPedCommentSlot(uint32 nComment)
return -1;
}
bool
bool8
cSampleManager::LoadPedComment(uint32 nComment)
{
ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
return false;
return FALSE;
}
int32
@ -210,56 +210,56 @@ cSampleManager::GetSampleLength(uint32 nSample)
return 0;
}
bool cSampleManager::UpdateReverb(void)
bool8 cSampleManager::UpdateReverb(void)
{
return false;
return FALSE;
}
void
cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
cSampleManager::SetChannelReverbFlag(uint32 nChannel, bool8 nReverbFlag)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
bool
bool8
cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
return false;
return FALSE;
}
void
cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
{
ASSERT( nChannel != CHANNEL2D );
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
{
ASSERT( nChannel != CHANNEL2D );
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
{
ASSERT( nChannel != CHANNEL2D );
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
{
ASSERT( nChannel == CHANNEL2D );
ASSERT( nChannel >= MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
{
ASSERT(nChannel == CHANNEL2D);
ASSERT( nChannel >= MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
@ -281,12 +281,12 @@ cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
bool
bool8
cSampleManager::GetChannelUsedFlag(uint32 nChannel)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
return false;
return FALSE;
}
void
@ -308,7 +308,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
}
void
cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
cSampleManager::PauseStream(bool8 nPauseFlag, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@ -319,12 +319,12 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
ASSERT( nStream < MAX_STREAMS );
}
bool
bool8
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
return false;
return FALSE;
}
void
@ -342,7 +342,7 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
}
void
cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffectFlag, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@ -355,23 +355,23 @@ cSampleManager::GetStreamedFileLength(uint8 nStream)
return 1;
}
bool
bool8
cSampleManager::IsStreamPlaying(uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
return false;
return FALSE;
}
bool
bool8
cSampleManager::InitialiseSampleBanks(void)
{
return true;
return TRUE;
}
void
cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel)
cSampleManager::SetStreamedFileLoopFlag(bool8 nLoopFlag, uint8 nChannel)
{
}

File diff suppressed because it is too large Load Diff

View File

@ -54,8 +54,8 @@ enum eSound
SOUND_49,
SOUND_WEAPON_BAT_ATTACK,
SOUND_WEAPON_KNIFE_ATTACK,
SOUND_WEAPON_CHAINSAW_ATTACK,
SOUND_WEAPON_CHAINSAW_IDLE,
SOUND_WEAPON_CHAINSAW_ATTACK,
SOUND_WEAPON_CHAINSAW_MADECONTACT,
SOUND_WEAPON_SHOT_FIRED,
SOUND_WEAPON_RELOAD,
@ -116,8 +116,8 @@ enum eSound
SOUND_PED_MIAMIVICE_EXITING_CAR,
SOUND_PED_COP_HELIPILOTPHRASE,
SOUND_PED_PULLOUTWEAPON,
SOUND_PED_HELI_PLAYER_FOUND = 114,
SOUND_PED_VCPA_PLAYER_FOUND = 115,
SOUND_PED_HELI_PLAYER_FOUND,
SOUND_PED_VCPA_PLAYER_FOUND,
SOUND_PED_ON_FIRE,
SOUND_PED_AIMING,
SOUND_PED_HANDS_UP,
@ -128,15 +128,15 @@ enum eSound
SOUND_PED_CAR_JACKED,
SOUND_PED_ROBBED,
SOUND_PED_ACCIDENTREACTION1,
SOUND_PED_UNK_126,
SOUND_PED_INNOCENT,
SOUND_PED_PLAYER_AFTERSEX,
SOUND_PED_PLAYER_BEFORESEX,
SOUND_PED_COP_UNK_129, // also used for medics
SOUND_PED_COP_TARGETING, // also used for medics
SOUND_PED_COP_MANYCOPSAROUND, // also used for medics
SOUND_PED_GUNAIMEDAT2,
SOUND_PED_COP_ALONE, // also used for medics
SOUND_PED_GUNAIMEDAT3,
SOUND_PED_COP_REACTION,
SOUND_PED_COP_ASK_FOR_ID,
SOUND_PED_COP_LITTLECOPSAROUND, // also used for medics
SOUND_PED_PLAYER_FARFROMCOPS, // also used for medics
SOUND_PED_TAXI_WAIT,
@ -151,12 +151,12 @@ enum eSound
SOUND_PED_ANNOYED_DRIVER,
SOUND_PED_147,
SOUND_PED_SOLICIT,
SOUND_PED_149,
SOUND_PED_JEER,
SOUND_PED_150,
SOUND_PED_EXTINGUISHING_FIRE,
SOUND_PED_WAIT_DOUBLEBACK,
SOUND_153,
SOUND_PED_CHAT_SEXY,
SOUND_PED_CHAT_SEXY_FEMALE,
SOUND_PED_CHAT_SEXY_MALE,
SOUND_PED_CHAT_EVENT,
SOUND_PED_PED_COLLISION,
SOUND_PED_CHAT,

View File

@ -4,8 +4,8 @@
#include "Streaming.h"
#include "Pools.h"
void *CBuilding::operator new(size_t sz) { return CPools::GetBuildingPool()->New(); }
void CBuilding::operator delete(void *p, size_t sz) { CPools::GetBuildingPool()->Delete((CBuilding*)p); }
void *CBuilding::operator new(size_t sz) throw() { return CPools::GetBuildingPool()->New(); }
void CBuilding::operator delete(void *p, size_t sz) throw() { CPools::GetBuildingPool()->Delete((CBuilding*)p); }
void
CBuilding::ReplaceWithNewModel(int32 id)

View File

@ -9,8 +9,8 @@ public:
m_type = ENTITY_TYPE_BUILDING;
bUsesCollision = true;
}
static void *operator new(size_t);
static void operator delete(void*, size_t);
static void *operator new(size_t) throw();
static void operator delete(void*, size_t) throw();
void ReplaceWithNewModel(int32 id);

View File

@ -4,5 +4,5 @@
#include "Treadable.h"
#include "Pools.h"
void *CTreadable::operator new(size_t sz) { return CPools::GetTreadablePool()->New(); }
void CTreadable::operator delete(void *p, size_t sz) { CPools::GetTreadablePool()->Delete((CTreadable*)p); }
void *CTreadable::operator new(size_t sz) throw() { return CPools::GetTreadablePool()->New(); }
void CTreadable::operator delete(void *p, size_t sz) throw() { CPools::GetTreadablePool()->Delete((CTreadable*)p); }

View File

@ -5,8 +5,8 @@
class CTreadable : public CBuilding
{
public:
static void *operator new(size_t);
static void operator delete(void*, size_t);
static void *operator new(size_t) throw();
static void operator delete(void*, size_t) throw();
bool GetIsATreadable(void) { return true; }
};

View File

@ -27,7 +27,7 @@ CColModel::~CColModel(void)
}
void*
CColModel::operator new(size_t)
CColModel::operator new(size_t) throw()
{
CColModel* node = CPools::GetColModelPool()->New();
assert(node);
@ -35,7 +35,7 @@ CColModel::operator new(size_t)
}
void
CColModel::operator delete(void *p, size_t)
CColModel::operator delete(void *p, size_t) throw()
{
CPools::GetColModelPool()->Delete((CColModel*)p);
}

View File

@ -33,7 +33,7 @@ struct CColModel
void SetLinkPtr(CLink<CColModel*>*);
void GetTrianglePoint(CVector &v, int i) const;
void *operator new(size_t);
void operator delete(void *p, size_t);
void *operator new(size_t) throw();
void operator delete(void *p, size_t) throw();
CColModel& operator=(const CColModel& other);
};

View File

@ -186,7 +186,7 @@ CColStore::LoadCollision(const CVector2D &pos)
}else{
for (int j = 0; j < MAX_CLEANUP; j++) {
CPhysical* pEntity = nil;
cleanup_entity_struct* pCleanup = &CTheScripts::MissionCleanUp.m_sEntities[i];
cleanup_entity_struct* pCleanup = &CTheScripts::MissionCleanUp.m_sEntities[j];
if (pCleanup->type == CLEANUP_CAR) {
pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id);
if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED)

View File

@ -144,11 +144,10 @@ CCollision::SortOutCollisionAfterLoad(void)
void
CCollision::LoadCollisionScreen(eLevelName level)
{
static Const char *levelNames[4] = {
static Const char *levelNames[] = {
"",
"IND_ZON",
"COM_ZON",
"SUB_ZON"
};
// Why twice?

View File

@ -5,6 +5,7 @@
#include "CarCtrl.h"
#include "Curves.h"
#include "PathFind.h"
#include "SaveBuf.h"
void CAutoPilot::ModifySpeed(float speed)
{
@ -49,86 +50,87 @@ void CAutoPilot::RemoveOnePathNode()
#ifdef COMPATIBLE_SAVES
void CAutoPilot::Save(uint8*& buf)
{
WriteSaveBuf<int32>(buf, m_nCurrentRouteNode);
WriteSaveBuf<int32>(buf, m_nNextRouteNode);
WriteSaveBuf<int32>(buf, m_nPrevRouteNode);
WriteSaveBuf<int32>(buf, m_nTimeEnteredCurve);
WriteSaveBuf<int32>(buf, m_nTimeToSpendOnCurrentCurve);
WriteSaveBuf<uint32>(buf, m_nCurrentPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nNextPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nPreviousPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nAntiReverseTimer);
WriteSaveBuf<uint32>(buf, m_nTimeToStartMission);
WriteSaveBuf<int8>(buf, m_nPreviousDirection);
WriteSaveBuf<int8>(buf, m_nCurrentDirection);
WriteSaveBuf<int8>(buf, m_nNextDirection);
WriteSaveBuf<int8>(buf, m_nCurrentLane);
WriteSaveBuf<int8>(buf, m_nNextLane);
WriteSaveBuf<uint8>(buf, m_nDrivingStyle);
WriteSaveBuf<uint8>(buf, m_nCarMission);
WriteSaveBuf<uint8>(buf, m_nTempAction);
WriteSaveBuf<uint32>(buf, m_nTimeTempAction);
WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed);
WriteSaveBuf<uint8>(buf, m_nCruiseSpeed);
WriteSaveBuf<uint8>(buf, m_nCruiseSpeedMultiplierType);
SkipSaveBuf(buf, 2);
WriteSaveBuf<float>(buf, m_fCruiseSpeedMultiplier);
WriteSaveBuf(buf, m_nCurrentRouteNode);
WriteSaveBuf(buf, m_nNextRouteNode);
WriteSaveBuf(buf, m_nPrevRouteNode);
WriteSaveBuf(buf, m_nTimeEnteredCurve);
WriteSaveBuf(buf, m_nTimeToSpendOnCurrentCurve);
WriteSaveBuf(buf, m_nCurrentPathNodeInfo);
WriteSaveBuf(buf, m_nNextPathNodeInfo);
WriteSaveBuf(buf, m_nPreviousPathNodeInfo);
WriteSaveBuf(buf, m_nAntiReverseTimer);
WriteSaveBuf(buf, m_nTimeToStartMission);
WriteSaveBuf(buf, m_nPreviousDirection);
WriteSaveBuf(buf, m_nCurrentDirection);
WriteSaveBuf(buf, m_nNextDirection);
WriteSaveBuf(buf, m_nCurrentLane);
WriteSaveBuf(buf, m_nNextLane);
WriteSaveBuf(buf, m_nDrivingStyle);
WriteSaveBuf(buf, m_nCarMission);
WriteSaveBuf(buf, m_nTempAction);
WriteSaveBuf(buf, m_nTimeTempAction);
WriteSaveBuf(buf, m_fMaxTrafficSpeed);
WriteSaveBuf(buf, m_nCruiseSpeed);
WriteSaveBuf(buf, m_nCruiseSpeedMultiplierType);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_fCruiseSpeedMultiplier);
uint8 flags = 0;
if (m_bSlowedDownBecauseOfCars) flags |= BIT(0);
if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1);
if (m_bStayInCurrentLevel) flags |= BIT(2);
if (m_bStayInFastLane) flags |= BIT(3);
if (m_bIgnorePathfinding) flags |= BIT(4);
WriteSaveBuf<uint8>(buf, flags);
WriteSaveBuf<uint8>(buf, m_nSwitchDistance);
SkipSaveBuf(buf, 2);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.x);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.y);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.z);
SkipSaveBuf(buf, 32);
WriteSaveBuf<int16>(buf, m_nPathFindNodesCount);
SkipSaveBuf(buf, 6);
WriteSaveBuf(buf, flags);
WriteSaveBuf(buf, m_nSwitchDistance);
ZeroSaveBuf(buf, 2);
WriteSaveBuf(buf, m_vecDestinationCoors.x);
WriteSaveBuf(buf, m_vecDestinationCoors.y);
WriteSaveBuf(buf, m_vecDestinationCoors.z);
ZeroSaveBuf(buf, 32);
WriteSaveBuf(buf, m_nPathFindNodesCount);
ZeroSaveBuf(buf, 6);
}
void CAutoPilot::Load(uint8*& buf)
{
m_nCurrentRouteNode = ReadSaveBuf<int32>(buf);
m_nNextRouteNode = ReadSaveBuf<int32>(buf);
m_nPrevRouteNode = ReadSaveBuf<int32>(buf);
m_nTimeEnteredCurve = ReadSaveBuf<int32>(buf);
m_nTimeToSpendOnCurrentCurve = ReadSaveBuf<int32>(buf);
m_nCurrentPathNodeInfo = ReadSaveBuf<uint32>(buf);
m_nNextPathNodeInfo = ReadSaveBuf<uint32>(buf);
m_nPreviousPathNodeInfo = ReadSaveBuf<uint32>(buf);
m_nAntiReverseTimer = ReadSaveBuf<uint32>(buf);
m_nTimeToStartMission = ReadSaveBuf<uint32>(buf);
m_nPreviousDirection = ReadSaveBuf<int8>(buf);
m_nCurrentDirection = ReadSaveBuf<int8>(buf);
m_nNextDirection = ReadSaveBuf<int8>(buf);
m_nCurrentLane = ReadSaveBuf<int8>(buf);
m_nNextLane = ReadSaveBuf<int8>(buf);
m_nDrivingStyle = ReadSaveBuf<uint8>(buf);
m_nCarMission = ReadSaveBuf<uint8>(buf);
m_nTempAction = ReadSaveBuf<uint8>(buf);
m_nTimeTempAction = ReadSaveBuf<uint32>(buf);
m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf);
m_nCruiseSpeed = ReadSaveBuf<uint8>(buf);
m_nCruiseSpeedMultiplierType = ReadSaveBuf<uint8>(buf);
ReadSaveBuf(&m_nCurrentRouteNode, buf);
ReadSaveBuf(&m_nNextRouteNode, buf);
ReadSaveBuf(&m_nPrevRouteNode, buf);
ReadSaveBuf(&m_nTimeEnteredCurve, buf);
ReadSaveBuf(&m_nTimeToSpendOnCurrentCurve, buf);
ReadSaveBuf(&m_nCurrentPathNodeInfo, buf);
ReadSaveBuf(&m_nNextPathNodeInfo, buf);
ReadSaveBuf(&m_nPreviousPathNodeInfo, buf);
ReadSaveBuf(&m_nAntiReverseTimer, buf);
ReadSaveBuf(&m_nTimeToStartMission, buf);
ReadSaveBuf(&m_nPreviousDirection, buf);
ReadSaveBuf(&m_nCurrentDirection, buf);
ReadSaveBuf(&m_nNextDirection, buf);
ReadSaveBuf(&m_nCurrentLane, buf);
ReadSaveBuf(&m_nNextLane, buf);
ReadSaveBuf(&m_nDrivingStyle, buf);
ReadSaveBuf(&m_nCarMission, buf);
ReadSaveBuf(&m_nTempAction, buf);
ReadSaveBuf(&m_nTimeTempAction, buf);
ReadSaveBuf(&m_fMaxTrafficSpeed, buf);
ReadSaveBuf(&m_nCruiseSpeed, buf);
ReadSaveBuf(&m_nCruiseSpeedMultiplierType, buf);
SkipSaveBuf(buf, 2);
m_fCruiseSpeedMultiplier = ReadSaveBuf<float>(buf);
uint8 flags = ReadSaveBuf<uint8>(buf);
ReadSaveBuf(&m_fCruiseSpeedMultiplier, buf);
uint8 flags;
ReadSaveBuf(&flags, buf);
m_bSlowedDownBecauseOfCars = !!(flags & BIT(0));
m_bSlowedDownBecauseOfPeds = !!(flags & BIT(1));
m_bStayInCurrentLevel = !!(flags & BIT(2));
m_bStayInFastLane = !!(flags & BIT(3));
m_bIgnorePathfinding = !!(flags & BIT(4));
m_nSwitchDistance = ReadSaveBuf<uint8>(buf);
ReadSaveBuf(&m_nSwitchDistance, buf);
SkipSaveBuf(buf, 2);
m_vecDestinationCoors.x = ReadSaveBuf<float>(buf);
m_vecDestinationCoors.y = ReadSaveBuf<float>(buf);
m_vecDestinationCoors.z = ReadSaveBuf<float>(buf);
ReadSaveBuf(&m_vecDestinationCoors.x, buf);
ReadSaveBuf(&m_vecDestinationCoors.y, buf);
ReadSaveBuf(&m_vecDestinationCoors.z, buf);
SkipSaveBuf(buf, 32);
m_nPathFindNodesCount = ReadSaveBuf<int16>(buf);
ReadSaveBuf(&m_nPathFindNodesCount, buf);
SkipSaveBuf(buf, 6);
}
#endif

View File

@ -1581,8 +1581,8 @@ void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float
forward.Normalise();
float forwardAngle = CGeneral::GetATanOfXY(forward.x, forward.y);
float angleDiff = angleBetweenVehicles - forwardAngle;
float lenProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.y * sin(angleDiff));
float widthProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.x * cos(angleDiff));
float lenProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.y * Sin(angleDiff));
float widthProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.x * Cos(angleDiff));
float lengthToEvade = (2 * (lenProjection + widthProjection) + WIDTH_COEF_TO_WEAVE_SAFELY * 2 * pVehicle->GetColModel()->boundingBox.max.x) / distance;
float diffToLeftAngle = LimitRadianAngle(angleBetweenVehicles - *pAngleToWeaveLeft);
diffToLeftAngle = ABS(diffToLeftAngle);
@ -2575,7 +2575,7 @@ void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CVehicle* pVehicle, float
float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
float steerAngle = LimitRadianAngle(angleToTarget - angleForward);
steerAngle = clamp(steerAngle, -DEFAULT_MAX_STEER_ANGLE, DEFAULT_MAX_STEER_ANGLE);
steerAngle = Clamp(steerAngle, -DEFAULT_MAX_STEER_ANGLE, DEFAULT_MAX_STEER_ANGLE);
#ifdef FIX_BUGS
float speedTarget = pVehicle->AutoPilot.GetCruiseSpeed();
#else
@ -2735,7 +2735,7 @@ void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
{
CVector2D vecToTarget = pPlane->AutoPilot.m_vecDestinationCoors - pPlane->GetPosition();
float fForwardZ = (pPlane->AutoPilot.m_vecDestinationCoors.z - pPlane->GetPosition().z) / vecToTarget.Magnitude();
fForwardZ = clamp(fForwardZ, -0.3f, 0.3f);
fForwardZ = Clamp(fForwardZ, -0.3f, 0.3f);
float angle = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y);
while (angle > TWOPI)
angle -= TWOPI;
@ -3238,7 +3238,7 @@ bool CCarCtrl::GenerateOneEmergencyServicesCar(uint32 mi, CVector vecPos)
attempts += 1;
}
if (attempts >= 5)
return nil;
return false;
CAutomobile* pVehicle = new CAutomobile(mi, RANDOM_VEHICLE);
pVehicle->AutoPilot.m_vecDestinationCoors = vecPos;
pVehicle->SetPosition(spawnPos);

View File

@ -30,6 +30,7 @@
#include "Automobile.h"
#include "MBlur.h"
#include "screendroplets.h"
#include "SaveBuf.h"
uint8 CGameLogic::ActivePlayers;
uint8 CGameLogic::ShortCutState;
@ -157,7 +158,7 @@ CGameLogic::Update()
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, true);
CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
@ -190,7 +191,7 @@ CGameLogic::Update()
}
if (!CTheScripts::IsPlayerOnAMission() && pPlayerInfo.m_nBustedAudioStatus == 0) {
if (!CTheScripts::IsPlayerOnAMission() && pPlayerInfo.m_nBustedAudioStatus == BUSTEDAUDIO_NONE) {
if (CGeneral::GetRandomNumberInRange(0, 4) == 0)
pPlayerInfo.m_nBustedAudioStatus = BUSTEDAUDIO_DONE;
else {
@ -266,7 +267,7 @@ CGameLogic::Update()
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, true);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
@ -321,7 +322,7 @@ CGameLogic::Update()
#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, true);
CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat);
CRestart::OverridePoliceStationLevel = LEVEL_GENERIC;
CRestart::OverrideHospitalLevel = LEVEL_GENERIC;
@ -378,10 +379,10 @@ CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector
pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur;
pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur);
CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed);
CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1);
CWorld::ClearExcitingStuffFromArea(pos, 4000.0f, true);
pPlayerPed->RestoreHeadingRate();
CGame::currArea = AREA_MAIN_MAP;
CStreaming::RemoveBuildingsNotInArea(0);
CStreaming::RemoveBuildingsNotInArea(AREA_MAIN_MAP);
TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
TheCamera.Restore();
CReferences::RemoveReferencesToPlayer();
@ -488,7 +489,7 @@ CGameLogic::UpdateShortCut()
pShortCutTaxi->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
pShortCutTaxi->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2500;
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.5f, 0);
TheCamera.Fade(2.5f, FADE_OUT);
ShortCutState = SHORTCUT_TRANSITION;
ShortCutTimer = CTimer::GetTimeInMilliseconds() + 3000;
CMessages::AddBigMessage(TheText.Get("TAXI"), 4500, 1);
@ -508,7 +509,7 @@ CGameLogic::UpdateShortCut()
pShortCutTaxi->SetMoveSpeed(pShortCutTaxi->GetForward() * 0.4f);
ShortCutTimer = CTimer::GetTimeInMilliseconds() + 1500;
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(1.0f, 1);
TheCamera.Fade(1.0f, FADE_IN);
ShortCutState = SHORTCUT_ARRIVING;
CTimer::Resume();
}
@ -611,12 +612,12 @@ void
CGameLogic::Load(uint8* buf, uint32 size)
{
INITSAVEBUF
NumAfterDeathStartPoints = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&NumAfterDeathStartPoints, buf);
for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
AfterDeathStartPoints[i].x = ReadSaveBuf<float>(buf);
AfterDeathStartPoints[i].y = ReadSaveBuf<float>(buf);
AfterDeathStartPoints[i].z = ReadSaveBuf<float>(buf);
AfterDeathStartPointOrientation[i] = ReadSaveBuf<float>(buf);
ReadSaveBuf(&AfterDeathStartPoints[i].x, buf);
ReadSaveBuf(&AfterDeathStartPoints[i].y, buf);
ReadSaveBuf(&AfterDeathStartPoints[i].z, buf);
ReadSaveBuf(&AfterDeathStartPointOrientation[i], buf);
}
VALIDATESAVEBUF(size)
}

View File

@ -24,13 +24,7 @@
#include "Wanted.h"
#include "World.h"
#include "VarConsole.h"
#define CRUSHER_GARAGE_X1 (1135.5f)
#define CRUSHER_GARAGE_Y1 (57.0f)
#define CRUSHER_GARAGE_Z1 (-1.0f)
#define CRUSHER_GARAGE_X2 (1149.5f)
#define CRUSHER_GARAGE_Y2 (63.7f)
#define CRUSHER_GARAGE_Z2 (3.5f)
#include "SaveBuf.h"
#define ROTATED_DOOR_OPEN_SPEED (0.015f)
#define ROTATED_DOOR_CLOSE_SPEED (0.02f)
@ -158,7 +152,7 @@ void CGarages::Init(void)
}
hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (hGarages >= 0)
DMAudio.SetEntityStatus(hGarages, true);
DMAudio.SetEntityStatus(hGarages, TRUE);
}
void CGarages::Shutdown(void)
@ -1843,11 +1837,12 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
m_nRadioStation = pVehicle->m_nRadioStation;
m_nVariationA = pVehicle->m_aExtras[0];
m_nVariationB = pVehicle->m_aExtras[1];
m_bBulletproof = pVehicle->bBulletProof;
m_bFireproof = pVehicle->bFireProof;
m_bExplosionproof = pVehicle->bExplosionProof;
m_bCollisionproof = pVehicle->bCollisionProof;
m_bMeleeproof = pVehicle->bMeleeProof;
m_nFlags = 0;
if (pVehicle->bBulletProof) m_nFlags |= FLAG_BULLETPROOF;
if (pVehicle->bFireProof) m_nFlags |= FLAG_FIREPROOF;
if (pVehicle->bExplosionProof) m_nFlags |= FLAG_EXPLOSIONPROOF;
if (pVehicle->bCollisionProof) m_nFlags |= FLAG_COLLISIONPROOF;
if (pVehicle->bMeleeProof) m_nFlags |= FLAG_MELEEPROOF;
if (pVehicle->IsCar() || pVehicle->IsBike())
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour
}
@ -1896,11 +1891,11 @@ CVehicle* CStoredCar::RestoreCar()
}
pVehicle->bHasBeenOwnedByPlayer = true;
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
pVehicle->bBulletProof = m_bBulletproof;
pVehicle->bFireProof = m_bFireproof;
pVehicle->bExplosionProof = m_bExplosionproof;
pVehicle->bCollisionProof = m_bCollisionproof;
pVehicle->bMeleeProof = m_bMeleeproof;
if (m_nFlags & FLAG_BULLETPROOF) pVehicle->bBulletProof = true;
if (m_nFlags & FLAG_FIREPROOF) pVehicle->bFireProof = true;
if (m_nFlags & FLAG_EXPLOSIONPROOF) pVehicle->bExplosionProof = true;
if (m_nFlags & FLAG_COLLISIONPROOF) pVehicle->bCollisionProof = true;
if (m_nFlags & FLAG_MELEEPROOF) pVehicle->bMeleeProof = true;
return pVehicle;
}
@ -2279,8 +2274,53 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aCarsInSafeHouses[j][i]);
}
}
for (int i = 0; i < NUM_GARAGES; i++)
for (int i = 0; i < NUM_GARAGES; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aGarages[i].m_eGarageType);
WriteSaveBuf(buf, aGarages[i].m_eGarageState);
WriteSaveBuf(buf, aGarages[i].m_nMaxStoredCars);
WriteSaveBuf(buf, aGarages[i].field_2);
WriteSaveBuf(buf, aGarages[i].m_bClosingWithoutTargetCar);
WriteSaveBuf(buf, aGarages[i].m_bDeactivated);
WriteSaveBuf(buf, aGarages[i].m_bResprayHappened);
ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, aGarages[i].m_nTargetModelIndex);
ZeroSaveBuf(buf, 4 + 4);
WriteSaveBuf(buf, aGarages[i].m_bDoor1PoolIndex);
WriteSaveBuf(buf, aGarages[i].m_bDoor2PoolIndex);
WriteSaveBuf(buf, aGarages[i].m_bDoor1IsDummy);
WriteSaveBuf(buf, aGarages[i].m_bDoor2IsDummy);
WriteSaveBuf(buf, aGarages[i].m_bRecreateDoorOnNextRefresh);
WriteSaveBuf(buf, aGarages[i].m_bRotatedDoor);
WriteSaveBuf(buf, aGarages[i].m_bCameraFollowsPlayer);
ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, aGarages[i].m_vecCorner1);
WriteSaveBuf(buf, aGarages[i].m_fInfZ);
WriteSaveBuf(buf, aGarages[i].m_vDir1);
WriteSaveBuf(buf, aGarages[i].m_vDir2);
WriteSaveBuf(buf, aGarages[i].m_fSupZ);
WriteSaveBuf(buf, aGarages[i].m_fDir1Len);
WriteSaveBuf(buf, aGarages[i].m_fDir2Len);
WriteSaveBuf(buf, aGarages[i].m_fInfX);
WriteSaveBuf(buf, aGarages[i].m_fSupX);
WriteSaveBuf(buf, aGarages[i].m_fInfY);
WriteSaveBuf(buf, aGarages[i].m_fSupY);
WriteSaveBuf(buf, aGarages[i].m_fDoorPos);
WriteSaveBuf(buf, aGarages[i].m_fDoorHeight);
WriteSaveBuf(buf, aGarages[i].m_fDoor1X);
WriteSaveBuf(buf, aGarages[i].m_fDoor1Y);
WriteSaveBuf(buf, aGarages[i].m_fDoor2X);
WriteSaveBuf(buf, aGarages[i].m_fDoor2Y);
WriteSaveBuf(buf, aGarages[i].m_fDoor1Z);
WriteSaveBuf(buf, aGarages[i].m_fDoor2Z);
WriteSaveBuf(buf, aGarages[i].m_nTimeToStartAction);
WriteSaveBuf(buf, aGarages[i].m_bCollectedCarsState);
ZeroSaveBuf(buf, 3 + 4);
ZeroSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
WriteSaveBuf(buf, aGarages[i]);
#endif
}
//VALIDATESAVEBUF(*size);
}
@ -2289,11 +2329,7 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
m_nModelIndex = other.m_nModelIndex;
m_vecPos = other.m_vecPos;
m_vecAngle = other.m_vecAngle;
m_bBulletproof = other.m_bBulletproof;
m_bFireproof = other.m_bFireproof;
m_bExplosionproof = other.m_bExplosionproof;
m_bCollisionproof = other.m_bCollisionproof;
m_bMeleeproof = other.m_bMeleeproof;
m_nFlags = other.m_nFlags;
m_nPrimaryColor = other.m_nPrimaryColor;
m_nSecondaryColor = other.m_nSecondaryColor;
m_nRadioStation = other.m_nRadioStation;
@ -2306,25 +2342,72 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
void CGarages::Load(uint8* buf, uint32 size)
{
//INITSAVEBUF
assert(size = 7876);
assert(size == 7876);
//assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + TOTAL_HIDEOUT_GARAGES * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)));
CloseHideOutGaragesBeforeSave();
NumGarages = ReadSaveBuf<uint32>(buf);
BombsAreFree = ReadSaveBuf<uint32>(buf);
RespraysAreFree = ReadSaveBuf<uint32>(buf);
CarsCollected = ReadSaveBuf<int32>(buf);
BankVansCollected = ReadSaveBuf<int32>(buf);
PoliceCarsCollected = ReadSaveBuf<int32>(buf);
ReadSaveBuf(&NumGarages, buf);
int32 tempInt;
ReadSaveBuf(&tempInt, buf);
BombsAreFree = tempInt ? true : false;
ReadSaveBuf(&tempInt, buf);
RespraysAreFree = tempInt ? true : false;
ReadSaveBuf(&CarsCollected, buf);
ReadSaveBuf(&BankVansCollected, buf);
ReadSaveBuf(&PoliceCarsCollected, buf);
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
CarTypesCollected[i] = ReadSaveBuf<uint32>(buf);
LastTimeHelpMessage = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&CarTypesCollected[i], buf);
ReadSaveBuf(&LastTimeHelpMessage, buf);
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) {
aCarsInSafeHouses[j][i] = ReadSaveBuf<CStoredCar>(buf);
ReadSaveBuf(&aCarsInSafeHouses[j][i], buf);
}
}
for (int i = 0; i < NUM_GARAGES; i++) {
aGarages[i] = ReadSaveBuf<CGarage>(buf);
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aGarages[i].m_eGarageType, buf);
ReadSaveBuf(&aGarages[i].m_eGarageState, buf);
ReadSaveBuf(&aGarages[i].m_nMaxStoredCars, buf);
ReadSaveBuf(&aGarages[i].field_2, buf);
ReadSaveBuf(&aGarages[i].m_bClosingWithoutTargetCar, buf);
ReadSaveBuf(&aGarages[i].m_bDeactivated, buf);
ReadSaveBuf(&aGarages[i].m_bResprayHappened, buf);
SkipSaveBuf(buf, 1);
ReadSaveBuf(&aGarages[i].m_nTargetModelIndex, buf);
SkipSaveBuf(buf, 4 + 4);
ReadSaveBuf(&aGarages[i].m_bDoor1PoolIndex, buf);
ReadSaveBuf(&aGarages[i].m_bDoor2PoolIndex, buf);
ReadSaveBuf(&aGarages[i].m_bDoor1IsDummy, buf);
ReadSaveBuf(&aGarages[i].m_bDoor2IsDummy, buf);
ReadSaveBuf(&aGarages[i].m_bRecreateDoorOnNextRefresh, buf);
ReadSaveBuf(&aGarages[i].m_bRotatedDoor, buf);
ReadSaveBuf(&aGarages[i].m_bCameraFollowsPlayer, buf);
SkipSaveBuf(buf, 1);
ReadSaveBuf(&aGarages[i].m_vecCorner1, buf);
ReadSaveBuf(&aGarages[i].m_fInfZ, buf);
ReadSaveBuf(&aGarages[i].m_vDir1, buf);
ReadSaveBuf(&aGarages[i].m_vDir2, buf);
ReadSaveBuf(&aGarages[i].m_fSupZ, buf);
ReadSaveBuf(&aGarages[i].m_fDir1Len, buf);
ReadSaveBuf(&aGarages[i].m_fDir2Len, buf);
ReadSaveBuf(&aGarages[i].m_fInfX, buf);
ReadSaveBuf(&aGarages[i].m_fSupX, buf);
ReadSaveBuf(&aGarages[i].m_fInfY, buf);
ReadSaveBuf(&aGarages[i].m_fSupY, buf);
ReadSaveBuf(&aGarages[i].m_fDoorPos, buf);
ReadSaveBuf(&aGarages[i].m_fDoorHeight, buf);
ReadSaveBuf(&aGarages[i].m_fDoor1X, buf);
ReadSaveBuf(&aGarages[i].m_fDoor1Y, buf);
ReadSaveBuf(&aGarages[i].m_fDoor2X, buf);
ReadSaveBuf(&aGarages[i].m_fDoor2Y, buf);
ReadSaveBuf(&aGarages[i].m_fDoor1Z, buf);
ReadSaveBuf(&aGarages[i].m_fDoor2Z, buf);
ReadSaveBuf(&aGarages[i].m_nTimeToStartAction, buf);
ReadSaveBuf(&aGarages[i].m_bCollectedCarsState, buf);
SkipSaveBuf(buf, 3 + 4);
SkipSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
ReadSaveBuf(&aGarages[i], buf);
#endif
aGarages[i].m_pDoor1 = nil;
aGarages[i].m_pDoor2 = nil;
aGarages[i].m_pTarget = nil;

View File

@ -63,14 +63,17 @@ enum
class CStoredCar
{
enum {
FLAG_BULLETPROOF = 0x1,
FLAG_FIREPROOF = 0x2,
FLAG_EXPLOSIONPROOF = 0x4,
FLAG_COLLISIONPROOF = 0x8,
FLAG_MELEEPROOF = 0x10,
};
int32 m_nModelIndex;
CVector m_vecPos;
CVector m_vecAngle;
int32 m_bBulletproof : 1;
int32 m_bFireproof : 1;
int32 m_bExplosionproof : 1;
int32 m_bCollisionproof : 1;
int32 m_bMeleeproof : 1;
int32 m_nFlags;
int8 m_nPrimaryColor;
int8 m_nSecondaryColor;
int8 m_nRadioStation;
@ -100,7 +103,7 @@ public:
bool m_bClosingWithoutTargetCar;
bool m_bDeactivated;
bool m_bResprayHappened;
int m_nTargetModelIndex;
int32 m_nTargetModelIndex;
CEntity *m_pDoor1;
CEntity *m_pDoor2;
uint8 m_bDoor1PoolIndex;

View File

@ -9,14 +9,15 @@
#include "OnscreenTimer.h"
#include "Camera.h"
void COnscreenTimer::Init() {
void
COnscreenTimer::Init()
{
m_bDisabled = false;
for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
m_sCounters[i].m_nCounterOffset = 0;
for(uint32 j = 0; j < ARRAY_SIZE(m_sCounters[0].m_aCounterText); j++) {
m_sCounters[i].m_aCounterText[j] = 0;
}
for(uint32 j = 0; j < ARRAY_SIZE(m_sCounters[0].m_aCounterText); j++)
m_sCounters[i].m_aCounterText[j] = '\0';
m_sCounters[i].m_nType = COUNTER_DISPLAY_NUMBER;
m_sCounters[i].m_bCounterProcessed = false;
@ -24,24 +25,25 @@ void COnscreenTimer::Init() {
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
m_sClocks[i].m_nClockOffset = 0;
for(uint32 j = 0; j < ARRAY_SIZE(m_sClocks[0].m_aClockText); j++) {
m_sClocks[i].m_aClockText[j] = 0;
}
for(uint32 j = 0; j < ARRAY_SIZE(m_sClocks[0].m_aClockText); j++)
m_sClocks[i].m_aClockText[j] = '\0';
m_sClocks[i].m_bClockProcessed = false;
m_sClocks[i].m_bClockGoingDown = true;
}
}
void COnscreenTimer::Process() {
if(!CReplay::IsPlayingBack() && !m_bDisabled) {
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
void
COnscreenTimer::Process()
{
if(!CReplay::IsPlayingBack() && !m_bDisabled)
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++)
m_sClocks[i].Process();
}
}
}
void COnscreenTimer::ProcessForDisplay() {
void
COnscreenTimer::ProcessForDisplay()
{
if(CHud::m_Wants_To_Draw_Hud) {
m_bProcessed = false;
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
@ -63,67 +65,67 @@ void COnscreenTimer::ProcessForDisplay() {
}
}
void COnscreenTimer::ClearCounter(uint32 offset) {
void
COnscreenTimer::ClearCounter(uint32 offset)
{
for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
if(offset == m_sCounters[i].m_nCounterOffset) {
m_sCounters[i].m_nCounterOffset = 0;
m_sCounters[i].m_aCounterText[0] = 0;
m_sCounters[i].m_aCounterText[0] = '\0';
m_sCounters[i].m_nType = COUNTER_DISPLAY_NUMBER;
m_sCounters[i].m_bCounterProcessed = 0;
m_sCounters[i].m_bCounterProcessed = false;
}
}
}
void COnscreenTimer::ClearClock(uint32 offset) {
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
void
COnscreenTimer::ClearClock(uint32 offset)
{
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++)
if(offset == m_sClocks[i].m_nClockOffset) {
m_sClocks[i].m_nClockOffset = 0;
m_sClocks[i].m_aClockText[0] = 0;
m_sClocks[i].m_bClockProcessed = 0;
m_sClocks[i].m_aClockText[0] = '\0';
m_sClocks[i].m_bClockProcessed = false;
m_sClocks[i].m_bClockGoingDown = true;
}
}
}
void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text, uint16 pos) {
void
COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text, uint16 pos)
{
if (m_sCounters[pos].m_aCounterText[0] != '\0')
return;
m_sCounters[pos].m_nCounterOffset = offset;
if(text) {
if(text)
strncpy(m_sCounters[pos].m_aCounterText, text, ARRAY_SIZE(m_sCounters[0].m_aCounterText));
} else {
m_sCounters[pos].m_aCounterText[0] = 0;
}
else
m_sCounters[pos].m_aCounterText[0] = '\0';
m_sCounters[pos].m_nType = type;
}
void COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown) {
// dead code in here
uint32 i;
for(i = 0; i < NUMONSCREENCLOCKS; i++) {
void
COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown)
{
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
if(m_sClocks[i].m_nClockOffset == 0) {
m_sClocks[i].m_nClockOffset = offset;
m_sClocks[i].m_bClockGoingDown = bGoingDown;
if(text)
strncpy(m_sClocks[i].m_aClockText, text, ARRAY_SIZE(m_sClocks[0].m_aClockText));
else
m_sClocks[i].m_aClockText[0] = '\0';
break;
}
return;
}
m_sClocks[i].m_nClockOffset = offset;
m_sClocks[i].m_bClockGoingDown = bGoingDown;
if(text) {
strncpy(m_sClocks[i].m_aClockText, text, ARRAY_SIZE(m_sClocks[0].m_aClockText));
} else {
m_sClocks[i].m_aClockText[0] = 0;
}
}
void COnscreenTimerEntry::Process() {
if(m_nClockOffset == 0) {
void
COnscreenTimerEntry::Process()
{
if(m_nClockOffset == 0)
return;
}
int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nClockOffset);
int32 oldTime = BSWAP32(*timerPtr);
@ -147,13 +149,17 @@ void COnscreenTimerEntry::Process() {
*timerPtr = oldTime + int32(CTimer::GetTimeStepInMilliseconds());
}
void COnscreenTimerEntry::ProcessForDisplayClock() {
void
COnscreenTimerEntry::ProcessForDisplayClock()
{
uint32 time = BSWAP32(*CTheScripts::GetPointerToScriptVariable(m_nClockOffset));
sprintf(m_aClockBuffer, "%02d:%02d", time / 1000 / 60 % 100,
time / 1000 % 60);
}
void COnscreenCounterEntry::ProcessForDisplayCounter() {
void
COnscreenCounterEntry::ProcessForDisplayCounter()
{
uint32 counter = BSWAP32(*CTheScripts::GetPointerToScriptVariable(m_nCounterOffset));
sprintf(m_aCounterBuffer, "%d", counter);
}

View File

@ -200,8 +200,8 @@ CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *p
const float fBoundMaxY = boundingBox.max.y + 0.3f;
const float fBoundMinY = boundingBox.min.y - 0.3f;
const float fBoundMaxX = boundingBox.max.x + 0.3f;
const float fDistanceX = pPosition->x - pEntity->m_matrix.GetPosition().x;
const float fDistanceY = pPosition->y - pEntity->m_matrix.GetPosition().y;
const float fDistanceX = pPosition->x - pEntity->GetMatrix().GetPosition().x;
const float fDistanceY = pPosition->y - pEntity->GetMatrix().GetPosition().y;
const float fBoundRadius = pEntity->GetBoundRadius();
CVector vecBoundCentre;
pEntity->GetBoundCentre(vecBoundCentre);
@ -215,8 +215,8 @@ CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *p
if (!pathNodes[x][y].bBlockade) {
const float pointY = y * 0.7f + fDistanceY;
CVector2D point(pointX, pointY);
if (fBoundMaxX > Abs(DotProduct2D(point, pEntity->m_matrix.GetRight()))) {
float fDotProduct = DotProduct2D(point, pEntity->m_matrix.GetForward());
if (fBoundMaxX > Abs(DotProduct2D(point, pEntity->GetMatrix().GetRight()))) {
float fDotProduct = DotProduct2D(point, pEntity->GetMatrix().GetForward());
if (fBoundMaxY > fDotProduct && fBoundMinY < fDotProduct)
pathNodes[x][y].bBlockade = true;
}

View File

@ -13,10 +13,17 @@
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "soundlist.h"
#include "SaveBuf.h"
#ifdef FIX_BUGS
#include "Replay.h"
#endif
#ifdef COMPATIBLE_SAVES
#define PHONEINFO_SAVE_SIZE 0xA30
#else
#define PHONEINFO_SAVE_SIZE sizeof(CPhoneInfo)
#endif
CPhoneInfo gPhoneInfo;
bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up
@ -197,14 +204,27 @@ void
CPhoneInfo::Load(uint8 *buf, uint32 size)
{
INITSAVEBUF
m_nMax = ReadSaveBuf<int32>(buf);
m_nScriptPhonesMax = ReadSaveBuf<int32>(buf);
ReadSaveBuf(&m_nMax, buf);
ReadSaveBuf(&m_nScriptPhonesMax, buf);
for (int i = 0; i < NUMPHONES; i++) {
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&m_aPhones[i].m_vecPos, buf);
SkipSaveBuf(buf, 6 * 4);
ReadSaveBuf(&m_aPhones[i].m_repeatedMessagePickupStart, buf);
int32 tmp;
ReadSaveBuf(&tmp, buf);
// It's saved as building pool index in save file, convert it to true entity
m_aPhones[i].m_pEntity = tmp != 0 ? CPools::GetBuildingPool()->GetSlot(tmp - 1) : nil;
ReadSaveBuf(&m_aPhones[i].m_nState, buf);
ReadSaveBuf(&m_aPhones[i].m_visibleToCam, buf);
SkipSaveBuf(buf, 3);
#else
ReadSaveBuf(&m_aPhones[i], buf);
// It's saved as building pool index in save file, convert it to true entity
if (m_aPhones[i].m_pEntity) {
m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
}
#endif
}
VALIDATESAVEBUF(size)
}
@ -298,17 +318,29 @@ CPhoneInfo::Initialise(void)
void
CPhoneInfo::Save(uint8 *buf, uint32 *size)
{
*size = sizeof(CPhoneInfo);
*size = PHONEINFO_SAVE_SIZE;
INITSAVEBUF
WriteSaveBuf(buf, m_nMax);
WriteSaveBuf(buf, m_nScriptPhonesMax);
for(int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, m_aPhones[phoneId].m_vecPos);
ZeroSaveBuf(buf, 6 * 4);
WriteSaveBuf(buf, m_aPhones[phoneId].m_repeatedMessagePickupStart);
// Convert entity pointer to building pool index while saving
int32 tmp = m_aPhones[phoneId].m_pEntity ? CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)m_aPhones[phoneId].m_pEntity) + 1 : 0;
WriteSaveBuf(buf, tmp);
WriteSaveBuf(buf, m_aPhones[phoneId].m_nState);
WriteSaveBuf(buf, m_aPhones[phoneId].m_visibleToCam);
ZeroSaveBuf(buf, 3);
#else
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
// Convert entity pointer to building pool index while saving
if (phone->m_pEntity) {
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1);
}
#endif
}
VALIDATESAVEBUF(*size)
}

View File

@ -33,6 +33,13 @@
#include "Hud.h"
#include "Messages.h"
#include "Streaming.h"
#include "SaveBuf.h"
#ifdef COMPATIBLE_SAVES
#define PICKUPS_SAVE_SIZE 0x4440
#else
#define PICKUPS_SAVE_SIZE sizeof(aPickUps)
#endif
CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages;
@ -1008,8 +1015,7 @@ CPickups::DoPickUpEffects(CEntity *entity)
entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame;
if (!entity->bDoNotRender) {
float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
float modifiedSin = 0.3f * (s + 1.0f);
float modifiedSin = 0.3f * (Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)) + 1.0f);
#ifdef FIX_BUGS
int16 colorId = 0;
@ -1149,7 +1155,20 @@ CPickups::DoPickUpEffects(CEntity *entity)
if (model == MI_MINIGUN || model == MI_MINIGUN2)
scale = 1.2f;
entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), scale);
float angle = (float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800);
float c = Cos(angle) * scale;
float s = Sin(angle) * scale;
// we know from SA they were setting each field manually like this
entity->GetMatrix().rx = c;
entity->GetMatrix().ry = s;
entity->GetMatrix().rz = 0.0f;
entity->GetMatrix().fx = -s;
entity->GetMatrix().fy = c;
entity->GetMatrix().fz = 0.0f;
entity->GetMatrix().ux = 0.0f;
entity->GetMatrix().uy = 0.0f;
entity->GetMatrix().uz = scale;
if (entity->GetModelIndex() == MI_MINIGUN2) {
CMatrix matrix1;
@ -1429,7 +1448,32 @@ CPickups::Load(uint8 *buf, uint32 size)
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
aPickUps[i] = ReadSaveBuf<CPickup>(buf);
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
ReadSaveBuf(&aPickUps[i].m_fRevenue, buf);
int32 tmp_pObject;
ReadSaveBuf(&tmp_pObject, buf);
int32 tmp_pExtraObject;
ReadSaveBuf(&tmp_pExtraObject, buf);
ReadSaveBuf(&aPickUps[i].m_nQuantity, buf);
ReadSaveBuf(&aPickUps[i].m_nTimer, buf);
ReadSaveBuf(&aPickUps[i].m_nMoneySpeed, buf);
ReadSaveBuf(&aPickUps[i].m_eModelIndex, buf);
ReadSaveBuf(&aPickUps[i].m_nIndex, buf);
memcpy(aPickUps[i].m_sTextKey, buf, sizeof(aPickUps[i].m_sTextKey));
SkipSaveBuf(buf, sizeof(aPickUps[i].m_sTextKey));
ReadSaveBuf(&aPickUps[i].m_eType, buf);
ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
uint8 flags;
ReadSaveBuf(&flags, buf);
aPickUps[i].m_bWasAmmoCollected = !!(flags & BIT(0));
aPickUps[i].m_bWasControlMessageShown = !!(flags & BIT(1));
SkipSaveBuf(buf, 3);
aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp_pObject != 0 ? CPools::GetObjectPool()->GetSlot(tmp_pObject - 1) : nil;
aPickUps[i].m_pExtraObject = aPickUps[i].m_eType != PICKUP_NONE && tmp_pExtraObject != 0 ? CPools::GetObjectPool()->GetSlot(tmp_pExtraObject - 1) : nil;
#else
ReadSaveBuf(&aPickUps[i], buf);
if (aPickUps[i].m_eType != PICKUP_NONE) {
if (aPickUps[i].m_pObject != nil)
@ -1437,15 +1481,15 @@ INITSAVEBUF
if (aPickUps[i].m_pExtraObject != nil)
aPickUps[i].m_pExtraObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pExtraObject - 1);
}
#endif
}
CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
ReadSaveBuf<uint16>(buf);
ReadSaveBuf(&CollectedPickUpIndex, buf);
SkipSaveBuf(buf, 2);
NumMessages = 0;
for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
aPickUpsCollected[i] = ReadSaveBuf<int32>(buf);
ReadSaveBuf(&aPickUpsCollected[i], buf);
VALIDATESAVEBUF(size)
}
@ -1453,12 +1497,34 @@ VALIDATESAVEBUF(size)
void
CPickups::Save(uint8 *buf, uint32 *size)
{
*size = sizeof(aPickUps);
*size = PICKUPS_SAVE_SIZE;
*size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aPickUps[i].m_vecPos);
WriteSaveBuf(buf, aPickUps[i].m_fRevenue);
int32 tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pObject) + 1 : 0;
WriteSaveBuf(buf, tmp);
tmp = aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pExtraObject != nil ? CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(aPickUps[i].m_pExtraObject) + 1 : 0;
WriteSaveBuf(buf, tmp);
WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
WriteSaveBuf(buf, aPickUps[i].m_nTimer);
WriteSaveBuf(buf, aPickUps[i].m_nMoneySpeed);
WriteSaveBuf(buf, aPickUps[i].m_eModelIndex);
WriteSaveBuf(buf, aPickUps[i].m_nIndex);
memcpy(buf, aPickUps[i].m_sTextKey, sizeof(aPickUps[i].m_sTextKey));
SkipSaveBuf(buf, sizeof(aPickUps[i].m_sTextKey));
WriteSaveBuf(buf, aPickUps[i].m_eType);
WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
uint8 flags = 0;
if (aPickUps[i].m_bWasAmmoCollected) flags |= BIT(0);
if (aPickUps[i].m_bWasControlMessageShown) flags |= BIT(1);
WriteSaveBuf(buf, flags);
ZeroSaveBuf(buf, 3);
#else
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE) {
if (buf_pickup->m_pObject != nil)
@ -1466,6 +1532,7 @@ INITSAVEBUF
if (buf_pickup->m_pExtraObject != nil)
buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1);
}
#endif
}
WriteSaveBuf(buf, CollectedPickUpIndex);

View File

@ -425,9 +425,9 @@ void CReplay::RecordParticle(tParticleType type, const CVector& vecPos, const CV
pp->pos_x = 4.0f * vecPos.x;
pp->pos_y = 4.0f * vecPos.y;
pp->pos_z = 4.0f * vecPos.z;
pp->dir_x = 120.0f * clamp(vecDir.x, -1.0f, 1.0f);
pp->dir_y = 120.0f * clamp(vecDir.y, -1.0f, 1.0f);
pp->dir_z = 120.0f * clamp(vecDir.z, -1.0f, 1.0f);
pp->dir_x = 120.0f * Clamp(vecDir.x, -1.0f, 1.0f);
pp->dir_y = 120.0f * Clamp(vecDir.y, -1.0f, 1.0f);
pp->dir_z = 120.0f * Clamp(vecDir.z, -1.0f, 1.0f);
pp->size = fSize;
pp->r = color.red;
pp->g = color.green;
@ -463,8 +463,8 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
CAnimBlendAssociation* main = RpAnimBlendClumpGetMainAssociation((RpClump*)ped->m_rwObject, &second, &blend_amount);
if (main){
state->animId = main->animId;
state->time = 255.0f / 4.0f * clamp(main->currentTime, 0.0f, 4.0f);
state->speed = 255.0f / 3.0f * clamp(main->speed, 0.0f, 3.0f);
state->time = 255.0f / 4.0f * Clamp(main->currentTime, 0.0f, 4.0f);
state->speed = 255.0f / 3.0f * Clamp(main->speed, 0.0f, 3.0f);
state->groupId = main->groupId;
}else{
state->animId = 3;
@ -474,9 +474,9 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
}
if (second) {
state->secAnimId = second->animId;
state->secTime = 255.0f / 4.0f * clamp(second->currentTime, 0.0f, 4.0f);
state->secSpeed = 255.0f / 3.0f * clamp(second->speed, 0.0f, 3.0f);
state->blendAmount = 255.0f / 2.0f * clamp(blend_amount, 0.0f, 2.0f);
state->secTime = 255.0f / 4.0f * Clamp(second->currentTime, 0.0f, 4.0f);
state->secSpeed = 255.0f / 3.0f * Clamp(second->speed, 0.0f, 3.0f);
state->blendAmount = 255.0f / 2.0f * Clamp(blend_amount, 0.0f, 2.0f);
state->secGroupId = second->groupId;
}else{
state->secAnimId = 0;
@ -488,9 +488,9 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
CAnimBlendAssociation* partial = RpAnimBlendClumpGetMainPartialAssociation((RpClump*)ped->m_rwObject);
if (partial) {
state->partAnimId = partial->animId;
state->partAnimTime = 255.0f / 4.0f * clamp(partial->currentTime, 0.0f, 4.0f);
state->partAnimSpeed = 255.0f / 3.0f * clamp(partial->speed, 0.0f, 3.0f);
state->partBlendAmount = 255.0f / 2.0f * clamp(partial->blendAmount, 0.0f, 2.0f);
state->partAnimTime = 255.0f / 4.0f * Clamp(partial->currentTime, 0.0f, 4.0f);
state->partAnimSpeed = 255.0f / 3.0f * Clamp(partial->speed, 0.0f, 3.0f);
state->partBlendAmount = 255.0f / 2.0f * Clamp(partial->blendAmount, 0.0f, 2.0f);
state->partGroupId = partial->groupId;
}else{
state->partAnimId = 0;
@ -507,10 +507,10 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainAssociation_N((RpClump*)ped->m_rwObject, i);
if (assoc){
state->aAnimId[i] = assoc->animId;
state->aCurTime[i] = 255.0f / 4.0f * clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed[i] = 255.0f / 3.0f * clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount[i] = 255.0f / 2.0f * clamp(assoc->blendAmount, 0.0f, 2.0f);
state->aBlendDelta[i] = 127.0f / 32.0f * clamp(assoc->blendDelta, -16.0f, 16.0f);
state->aCurTime[i] = 255.0f / 4.0f * Clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed[i] = 255.0f / 3.0f * Clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount[i] = 255.0f / 2.0f * Clamp(assoc->blendAmount, 0.0f, 2.0f);
state->aBlendDelta[i] = 127.0f / 32.0f * Clamp(assoc->blendDelta, -16.0f, 16.0f);
state->aFlags[i] = assoc->flags;
state->aGroupId[i] = assoc->groupId;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
@ -533,10 +533,10 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainPartialAssociation_N((RpClump*)ped->m_rwObject, i);
if (assoc) {
state->aAnimId2[i] = assoc->animId;
state->aCurTime2[i] = 255.0f / 4.0f * clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed2[i] = 255.0f / 3.0f * clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount2[i] = 255.0f / 2.0f * clamp(assoc->blendAmount, 0.0f, 2.0f);
state->aBlendDelta2[i] = 127.0f / 16.0f * clamp(assoc->blendDelta, -16.0f, 16.0f);
state->aCurTime2[i] = 255.0f / 4.0f * Clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed2[i] = 255.0f / 3.0f * Clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount2[i] = 255.0f / 2.0f * Clamp(assoc->blendAmount, 0.0f, 2.0f);
state->aBlendDelta2[i] = 127.0f / 16.0f * Clamp(assoc->blendDelta, -16.0f, 16.0f);
state->aFlags2[i] = assoc->flags;
state->aGroupId2[i] = assoc->groupId;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
@ -1463,7 +1463,7 @@ void CReplay::RestoreStuffFromMem(void)
ped->SetModelIndex(mi);
ped->m_pVehicleAnim = nil;
ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped);
DMAudio.SetEntityStatus(ped->m_audioEntityId, true);
DMAudio.SetEntityStatus(ped->m_audioEntityId, TRUE);
CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false);
for (int j = 0; j < TOTAL_WEAPON_SLOTS; j++) {
int mi1 = CWeaponInfo::GetWeaponInfo(ped->m_weapons[j].m_eWeaponType)->m_nModelId;
@ -1529,7 +1529,7 @@ void CReplay::RestoreStuffFromMem(void)
car->SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT, true);
}
vehicle->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, vehicle);
DMAudio.SetEntityStatus(vehicle->m_audioEntityId, true);
DMAudio.SetEntityStatus(vehicle->m_audioEntityId, TRUE);
CCarCtrl::UpdateCarCount(vehicle, false);
if ((mi == MI_AIRTRAIN || mi == MI_DEADDODO) && vehicle->m_rwObject){
CVehicleModelInfo* info = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi);

View File

@ -3,6 +3,7 @@
#include "Restart.h"
#include "Zones.h"
#include "PathFind.h"
#include "SaveBuf.h"
uint8 CRestart::OverrideHospitalLevel;
uint8 CRestart::OverridePoliceStationLevel;
@ -173,29 +174,28 @@ INITSAVEBUF
CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE);
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
HospitalRestartPoints[i] = ReadSaveBuf<CVector>(buf);
HospitalRestartHeadings[i] = ReadSaveBuf<float>(buf);
ReadSaveBuf(&HospitalRestartPoints[i], buf);
ReadSaveBuf(&HospitalRestartHeadings[i], buf);
}
for (int i = 0; i < NUM_RESTART_POINTS; i++) {
PoliceRestartPoints[i] = ReadSaveBuf<CVector>(buf);
PoliceRestartHeadings[i] = ReadSaveBuf<float>(buf);
ReadSaveBuf(&PoliceRestartPoints[i], buf);
ReadSaveBuf(&PoliceRestartHeadings[i], buf);
}
NumberOfHospitalRestarts = ReadSaveBuf<uint16>(buf);
NumberOfPoliceRestarts = ReadSaveBuf<uint16>(buf);
bOverrideRestart = ReadSaveBuf<bool>(buf);
ReadSaveBuf(&NumberOfHospitalRestarts, buf);
ReadSaveBuf(&NumberOfPoliceRestarts, buf);
ReadSaveBuf(&bOverrideRestart, buf);
// skip something unused
ReadSaveBuf<uint8>(buf);
ReadSaveBuf<uint16>(buf);
SkipSaveBuf(buf, 3);
OverridePosition = ReadSaveBuf<CVector>(buf);
OverrideHeading = ReadSaveBuf<float>(buf);
bFadeInAfterNextDeath = ReadSaveBuf<bool>(buf);
bFadeInAfterNextArrest = ReadSaveBuf<bool>(buf);
OverrideHospitalLevel = ReadSaveBuf<uint8>(buf);
OverridePoliceStationLevel = ReadSaveBuf<uint8>(buf);
ReadSaveBuf(&OverridePosition, buf);
ReadSaveBuf(&OverrideHeading, buf);
ReadSaveBuf(&bFadeInAfterNextDeath, buf);
ReadSaveBuf(&bFadeInAfterNextArrest, buf);
ReadSaveBuf(&OverrideHospitalLevel, buf);
ReadSaveBuf(&OverridePoliceStationLevel, buf);
VALIDATESAVEBUF(size);
}

View File

@ -64,7 +64,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius;
for (int32 i = 0; i < 2; i++) {
const int32 roadBlockIndex = i + 2 * roadBlockType;
CVector posForZ = pVehicle->m_matrix * (fRadius * vecRoadBlockOffets[roadBlockIndex]);
CVector posForZ = pVehicle->GetMatrix() * (fRadius * vecRoadBlockOffets[roadBlockIndex]);
int32 modelInfoId = MI_COP;
eCopType copType = COP_STREET;
switch (pVehicle->GetModelIndex())
@ -239,10 +239,10 @@ CRoadBlocks::CreateRoadBlockBetween2Points(CVector point1, CVector point2)
pVehicle->SetStatus(STATUS_ABANDONED);
// pVehicle->GetHeightAboveRoad(); // called but return value is ignored?
tmp.GetPosition().z += fModelRadius - 0.6f;
pVehicle->m_matrix = tmp;
pVehicle->SetMatrix(tmp);
pVehicle->PlaceOnRoadProperly();
pVehicle->SetIsStatic(false);
pVehicle->m_matrix.UpdateRW();
pVehicle->GetMatrix().UpdateRW();
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
pVehicle->bIsLocked = false;

View File

@ -1829,7 +1829,7 @@ void CMissionCleanup::Process()
CWorld::Players[0].m_pPed->m_nDrunkCountdown = 0;
CPad::GetPad(0)->SetDrunkInputDelay(0);
CWorld::Players[0].m_bDriveByAllowed = true;
DMAudio.ShutUpPlayerTalking(0);
DMAudio.ShutUpPlayerTalking(FALSE);
CVehicle::bDisableRemoteDetonation = false;
CVehicle::bDisableRemoteDetonationOnContact = false;
CGameLogic::ClearShortCut();
@ -2208,20 +2208,16 @@ void CRunningScript::Init()
int scriptToLoad = 0;
const char *scriptfile = "main.scm";
#ifdef _WIN32
#include <Windows.h>
#endif
int open_script()
{
// glfwGetKey doesn't work because of CGame::Initialise is blocking
#ifdef _WIN32
if (GetAsyncKeyState('G') & 0x8000)
CPad::UpdatePads();
if (CPad::GetPad(0)->GetChar('G'))
scriptToLoad = 0;
if (GetAsyncKeyState('R') & 0x8000)
if (CPad::GetPad(0)->GetChar('R'))
scriptToLoad = 1;
if (GetAsyncKeyState('D') & 0x8000)
if (CPad::GetPad(0)->GetChar('D'))
scriptToLoad = 2;
#endif
switch (scriptToLoad) {
case 0: scriptfile = "main.scm"; break;
case 1: scriptfile = "freeroam_miami.scm"; break;

View File

@ -431,8 +431,8 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
float length = *(float*)&ScriptParams[5];
float x, y;
if (angle != 0.0f){
y = cos(angle) * length;
x = sin(angle) * length;
y = Cos(angle) * length;
x = Sin(angle) * length;
}else{
y = length;
x = 0.0f;

View File

@ -749,7 +749,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2);
CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPlayerPed);
pPlayerPed->m_fArmour = clamp(pPlayerPed->m_fArmour + ScriptParams[1], 0.0f, CWorld::Players[ScriptParams[0]].m_nMaxArmour);
pPlayerPed->m_fArmour = Clamp(pPlayerPed->m_fArmour + ScriptParams[1], 0.0f, CWorld::Players[ScriptParams[0]].m_nMaxArmour);
return 0;
}
case COMMAND_ADD_ARMOUR_TO_CHAR:
@ -757,7 +757,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
pPed->m_fArmour = clamp(pPed->m_fArmour + ScriptParams[1], 0.0f, 100.0f);
pPed->m_fArmour = Clamp(pPed->m_fArmour + ScriptParams[1], 0.0f, 100.0f);
return 0;
}
case COMMAND_OPEN_GARAGE:
@ -1398,7 +1398,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
{
CollectParameters(&m_nIp, 1);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.PlayFrontEndTrack(ScriptParams[0] + STREAMED_SOUND_MISSION_COMPLETED - 1, 0);
DMAudio.PlayFrontEndTrack(ScriptParams[0] + STREAMED_SOUND_MISSION_COMPLETED - 1, FALSE);
return 0;
}
case COMMAND_CLEAR_AREA:

View File

@ -16,6 +16,7 @@
#include "SpecialFX.h"
#include "World.h"
#include "main.h"
#include "SaveBuf.h"
void CRunningScript::UpdateCompareFlag(bool flag)
{
@ -1006,10 +1007,10 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
initAngle -= TWOPI;
// it looks like the idea is to use a rectangle using the diagonal of the rectangle as
// the side of new rectangle, with "length" being the length of second side
float rotatedSupX = supX + side2length * sin(initAngle);
float rotatedSupY = supY - side2length * cos(initAngle);
float rotatedInfX = infX + side2length * sin(initAngle);
float rotatedInfY = infY - side2length * cos(initAngle);
float rotatedSupX = supX + side2length * Sin(initAngle);
float rotatedSupY = supY - side2length * Cos(initAngle);
float rotatedInfX = infX + side2length * Sin(initAngle);
float rotatedInfY = infY - side2length * Cos(initAngle);
float side1X = supX - infX;
float side1Y = supY - infY;
float side1Length = CVector2D(side1X, side1Y).Magnitude();
@ -2184,15 +2185,19 @@ void CTheScripts::LoadAllScripts(uint8* buf, uint32 size)
Init();
INITSAVEBUF
CheckSaveHeader(buf, 'S', 'C', 'R', '\0', size - SAVE_HEADER_SIZE);
uint32 varSpace = ReadSaveBuf<uint32>(buf);
uint32 varSpace, type, handle;
uint32 tmp;
ReadSaveBuf(&varSpace, buf);
for (uint32 i = 0; i < varSpace; i++)
ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE);
OnAMissionFlag = ReadSaveBuf<uint32>(buf);
LastMissionPassedTime = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&ScriptSpace[i], buf);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == SCRIPT_DATA_SIZE);
ReadSaveBuf(&OnAMissionFlag, buf);
ReadSaveBuf(&LastMissionPassedTime, buf);
for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
uint32 handle = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&type, buf);
ReadSaveBuf(&handle, buf);
switch (type) {
case 0:
BuildingSwapArray[i].m_pBuilding = nil;
@ -2206,14 +2211,14 @@ INITSAVEBUF
default:
script_assert(false);
}
BuildingSwapArray[i].m_nNewModel = ReadSaveBuf<uint32>(buf);
BuildingSwapArray[i].m_nOldModel = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&BuildingSwapArray[i].m_nNewModel, buf);
ReadSaveBuf(&BuildingSwapArray[i].m_nOldModel, buf);
if (BuildingSwapArray[i].m_pBuilding)
BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nNewModel);
}
for (uint32 i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
uint32 handle = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&type, buf);
ReadSaveBuf(&handle, buf);
switch (type) {
case 0:
InvisibilitySettingArray[i] = nil;
@ -2236,14 +2241,22 @@ INITSAVEBUF
if (InvisibilitySettingArray[i])
InvisibilitySettingArray[i]->bIsVisible = false;
}
script_assert(ReadSaveBuf<bool>(buf) == bUsingAMultiScriptFile);
bPlayerHasMetDebbieHarry = ReadSaveBuf<uint8>(buf);
ReadSaveBuf<uint16>(buf);
script_assert(ReadSaveBuf<uint32>(buf) == MainScriptSize);
script_assert(ReadSaveBuf<uint32>(buf) == LargestMissionScriptSize);
script_assert(ReadSaveBuf<uint16>(buf) == NumberOfMissionScripts);
script_assert(ReadSaveBuf<uint16>(buf) == NumberOfExclusiveMissionScripts);
uint32 runningScripts = ReadSaveBuf<uint32>(buf);
bool tmpBool;
ReadSaveBuf(&tmpBool, buf);
script_assert(tmpBool == bUsingAMultiScriptFile);
ReadSaveBuf(&bPlayerHasMetDebbieHarry, buf);
SkipSaveBuf(buf, 2);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == MainScriptSize);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == LargestMissionScriptSize);
uint16 tmp16;
ReadSaveBuf(&tmp16, buf);
script_assert(tmp16 == NumberOfMissionScripts);
ReadSaveBuf(&tmp16, buf);
script_assert(tmp16 == NumberOfExclusiveMissionScripts);
uint32 runningScripts;
ReadSaveBuf(&runningScripts, buf);
for (uint32 i = 0; i < runningScripts; i++)
StartNewScript(0)->Load(buf);
VALIDATESAVEBUF(size)
@ -2254,33 +2267,33 @@ VALIDATESAVEBUF(size)
void CRunningScript::Save(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
ZeroSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
WriteSaveBuf<char>(buf, m_abScriptName[i]);
WriteSaveBuf<uint32>(buf, m_nIp);
WriteSaveBuf(buf, m_abScriptName[i]);
WriteSaveBuf(buf, m_nIp);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
WriteSaveBuf<uint32>(buf, m_anStack[i]);
WriteSaveBuf<uint16>(buf, m_nStackPointer);
SkipSaveBuf(buf, 2);
WriteSaveBuf(buf, m_anStack[i]);
WriteSaveBuf(buf, m_nStackPointer);
ZeroSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
WriteSaveBuf<bool>(buf, m_bIsActive);
WriteSaveBuf<bool>(buf, m_bCondResult);
WriteSaveBuf<bool>(buf, m_bIsMissionScript);
WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
WriteSaveBuf<uint32>(buf, m_nWakeTime);
WriteSaveBuf<uint16>(buf, m_nAndOrState);
WriteSaveBuf<bool>(buf, m_bNotFlag);
WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled);
WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted);
WriteSaveBuf<bool>(buf, m_bMissionFlag);
SkipSaveBuf(buf, 2);
WriteSaveBuf(buf, m_anLocalVariables[i]);
WriteSaveBuf(buf, m_bIsActive);
WriteSaveBuf(buf, m_bCondResult);
WriteSaveBuf(buf, m_bIsMissionScript);
WriteSaveBuf(buf, m_bSkipWakeTime);
WriteSaveBuf(buf, m_nWakeTime);
WriteSaveBuf(buf, m_nAndOrState);
WriteSaveBuf(buf, m_bNotFlag);
WriteSaveBuf(buf, m_bDeatharrestEnabled);
WriteSaveBuf(buf, m_bDeatharrestExecuted);
WriteSaveBuf(buf, m_bMissionFlag);
ZeroSaveBuf(buf, 2);
#else
WriteSaveBuf(buf, *this);
#endif
@ -2291,35 +2304,35 @@ void CRunningScript::Load(uint8*& buf)
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
m_abScriptName[i] = ReadSaveBuf<char>(buf);
m_nIp = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&m_abScriptName[i], buf);
ReadSaveBuf(&m_nIp, buf);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
m_anStack[i] = ReadSaveBuf<uint32>(buf);
m_nStackPointer = ReadSaveBuf<uint16>(buf);
ReadSaveBuf(&m_anStack[i], buf);
ReadSaveBuf(&m_nStackPointer, buf);
SkipSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
m_bIsActive = ReadSaveBuf<bool>(buf);
m_bCondResult = ReadSaveBuf<bool>(buf);
m_bIsMissionScript = ReadSaveBuf<bool>(buf);
m_bSkipWakeTime = ReadSaveBuf<bool>(buf);
m_nWakeTime = ReadSaveBuf<uint32>(buf);
m_nAndOrState = ReadSaveBuf<uint16>(buf);
m_bNotFlag = ReadSaveBuf<bool>(buf);
m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf);
m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf);
m_bMissionFlag = ReadSaveBuf<bool>(buf);
ReadSaveBuf(&m_anLocalVariables[i], buf);
ReadSaveBuf(&m_bIsActive, buf);
ReadSaveBuf(&m_bCondResult, buf);
ReadSaveBuf(&m_bIsMissionScript, buf);
ReadSaveBuf(&m_bSkipWakeTime, buf);
ReadSaveBuf(&m_nWakeTime, buf);
ReadSaveBuf(&m_nAndOrState, buf);
ReadSaveBuf(&m_bNotFlag, buf);
ReadSaveBuf(&m_bDeatharrestEnabled, buf);
ReadSaveBuf(&m_bDeatharrestExecuted, buf);
ReadSaveBuf(&m_bMissionFlag, buf);
SkipSaveBuf(buf, 2);
#else
CRunningScript* n = next;
CRunningScript* p = prev;
*this = ReadSaveBuf<CRunningScript>(buf);
ReadSaveBuf(this, buf);
next = n;
prev = p;
#endif

View File

@ -387,7 +387,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
#if (defined GTAVC_JP_PATCH || defined SUPPORT_JAPANESE_SCRIPT)
case COMMAND_IS_JAPANESE_GAME:
#ifdef MORE_LANGUAGES
UpdateCompareFlag(FrontEndMenuManager.m_PrefsLanguage == LANGUAGE_JAPANESE);
UpdateCompareFlag(FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_JAPANESE);
#elif (defined GTAVC_JP_PATCH)
UpdateCompareFlag(true);
#else

View File

@ -11,6 +11,7 @@
#include "Wanted.h"
#include "World.h"
#include "VarConsole.h"
#include "SaveBuf.h"
#define TIME_BETWEEN_SETPIECE_SPAWNS 20000
@ -67,9 +68,9 @@ VALIDATESAVEBUF(*size)
void CSetPieces::Load(uint8* buf, uint32 size)
{
INITSAVEBUF
NumSetPieces = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&NumSetPieces, buf);
for (int i = 0; i < NUM_SETPIECES; i++)
aSetPieces[i] = ReadSaveBuf<CSetPiece>(buf);
ReadSaveBuf(&aSetPieces[i], buf);
VALIDATESAVEBUF(size)
}

View File

@ -1183,7 +1183,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
float ReqSpeed = DeltaBeta * SpeedMultiplier;
// this is also added
ReqSpeed = clamp(ReqSpeed, -SpeedLimit, SpeedLimit);
ReqSpeed = Clamp(ReqSpeed, -SpeedLimit, SpeedLimit);
// Add or subtract absolute depending on sign, genius!
if(ReqSpeed - BetaSpeed > 0.0f)
@ -1678,7 +1678,7 @@ CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, floa
Test.z = TargetCoors.z + 0.2f + Length*Sin(CarAlpha+AlphaOffset) + m_fCloseInCarHeightOffset;
if(CWorld::ProcessVerticalLine(Test, CamTargetEntity->GetPosition().z, point, entity, true, false, false, false, false, false, nil)){
float sin = (point.point.z - TargetCoors.z - 0.2f - m_fCloseInCarHeightOffset)/Length;
CarAlpha = Asin(clamp(sin, -1.0f, 1.0f)) - AlphaOffset;
CarAlpha = Asin(Clamp(sin, -1.0f, 1.0f)) - AlphaOffset;
if(CarAlpha < 0.0f)
AlphaOffset += CarAlpha;
}
@ -1828,7 +1828,7 @@ CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientati
if(DeltaBeta > PI) DeltaBeta -= TWOPI;
else if(DeltaBeta < -PI) DeltaBeta += TWOPI;
float dist = (TargetCoors - Source).Magnitude();
dist = FIRETRUCK_TRACKING_MULT*dist*clamp(DeltaBeta, -0.8f, 0.8f);
dist = FIRETRUCK_TRACKING_MULT*dist*Clamp(DeltaBeta, -0.8f, 0.8f);
Source += dist*CrossProduct(Front, CVector(0.0f, 0.0f, 1.0f));
}
@ -2801,7 +2801,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
if(BetaOffset > PI) BetaOffset -= TWOPI;
else if(BetaOffset < PI) BetaOffset += TWOPI;
BetaOffset = clamp(BetaOffset, -pedTarget->m_attachRotStep, pedTarget->m_attachRotStep);
BetaOffset = Clamp(BetaOffset, -pedTarget->m_attachRotStep, pedTarget->m_attachRotStep);
Beta = NewBeta + BetaOffset;
}
@ -3271,7 +3271,7 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f
// useless call
//CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &Water);
Water = (WaterLevel + WATER_Z_ADDITION_MIN - WaterLevelBuffered - WATER_Z_ADDITION)/(BoatDimensions.z/2.0f + MaxHeightUp);
TargetAlpha = Asin(clamp(Water, -1.0f, 1.0f));
TargetAlpha = Asin(Clamp(Water, -1.0f, 1.0f));
}
if(ResetStatics){
@ -3457,7 +3457,7 @@ FindSplinePathPositionFloat(float *out, float *spline, uint32 time, uint32 &mark
}
}
float a = ((float)time - (float)MS(spline[marker-4])) / (float)MS(spline[marker] - spline[marker-4]);
a = clamp(a, 0.0f, 1.0f);
a = Clamp(a, 0.0f, 1.0f);
float b = 1.0f - a;
*out = b*b*b * spline[marker-3] +
3.0f*a*b*b * spline[marker-1] +
@ -3495,7 +3495,7 @@ FindSplinePathPositionVector(CVector *out, float *spline, uint32 time, uint32 &m
}
float a = ((float)time - (float)MS(spline[marker-10])) / (float)MS(spline[marker] - spline[marker-10]);
a = clamp(a, 0.0f, 1.0f);
a = Clamp(a, 0.0f, 1.0f);
float b = 1.0f - a;
out->x =
b*b*b * spline[marker-9] +
@ -4921,7 +4921,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// 0.98f: CAR_FOV_FADE_MULT
FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV;
FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f);
FOV = Clamp(FOV, DefaultFOV, DefaultFOV + 30.0f);
}
// WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta)
@ -4952,9 +4952,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
AlphaSpeed = 0.0;
Distance = 1000.0;
Front.x = -(cos(Beta) * cos(Alpha));
Front.y = -(sin(Beta) * cos(Alpha));
Front.z = sin(Alpha);
Front.x = -(Cos(Beta) * Cos(Alpha));
Front.y = -(Sin(Beta) * Cos(Alpha));
Front.z = Sin(Alpha);
m_aTargetHistoryPosOne = TargetCoors - nextDistance * Front;
@ -5040,7 +5040,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
}
}
float targetAlpha = Asin(clamp(Front.z, -1.0f, 1.0f)) - zoomModeAlphaOffset;
float targetAlpha = Asin(Clamp(Front.z, -1.0f, 1.0f)) - zoomModeAlphaOffset;
if (targetAlpha <= maxAlphaAllowed) {
if (targetAlpha < -CARCAM_SET[camSetArrPos][14])
targetAlpha = -CARCAM_SET[camSetArrPos][14];
@ -5228,9 +5228,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
lastBeta = Beta;
Front.x = -(cos(Beta) * cos(Alpha));
Front.y = -(sin(Beta) * cos(Alpha));
Front.z = sin(Alpha);
Front.x = -(Cos(Beta) * Cos(Alpha));
Front.y = -(Sin(Beta) * Cos(Alpha));
Front.z = Sin(Alpha);
GetVectorsReadyForRW();
TheCamera.m_bCamDirectlyBehind = false;
TheCamera.m_bCamDirectlyInFront = false;
@ -5240,9 +5240,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
m_cvecTargetCoorsForFudgeInter = TargetCoors;
m_aTargetHistoryPosThree = m_aTargetHistoryPosOne;
float nextAlpha = alphaWithSpeedAccounted + zoomModeAlphaOffset;
float nextFrontX = -(cos(Beta) * cos(nextAlpha));
float nextFrontY = -(sin(Beta) * cos(nextAlpha));
float nextFrontZ = sin(nextAlpha);
float nextFrontX = -(Cos(Beta) * Cos(nextAlpha));
float nextFrontY = -(Sin(Beta) * Cos(nextAlpha));
float nextFrontZ = Sin(nextAlpha);
m_aTargetHistoryPosOne.x = TargetCoors.x - nextFrontX * nextDistance;
m_aTargetHistoryPosOne.y = TargetCoors.y - nextFrontY * nextDistance;
@ -5395,7 +5395,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float alphaToFace = Atan2(hi.z, hi.Magnitude2D()) + DEGTORAD(15.0f);
float neededAlphaTurn = alphaToFace - carGunUD;
float alphaTurnPerFrame = CTimer::GetTimeStep() * 0.02f;
float alphaTurnPerFrame = CTimer::GetTimeStepInSeconds();
if (neededAlphaTurn > alphaTurnPerFrame) {
neededTurn = alphaTurnPerFrame;

View File

@ -213,7 +213,7 @@ CCamera::Init(void)
m_iModeToGoTo = CCam::MODE_FOLLOWPED;
m_bJust_Switched = false;
m_bUseTransitionBeta = false;
m_matrix.SetScale(1.0f);
GetMatrix().SetScale(1.0f);
m_bTargetJustBeenOnTrain = false;
m_bInitialNoNodeStaticsSet = false;
m_uiLongestTimeInMill = 5000;
@ -347,7 +347,7 @@ CCamera::Process(void)
currentTime = m_uiTransitionDuration;
float fractionInter = (float) currentTime / m_uiTransitionDuration;
float fractionInterTarget = (float) currentTime / m_uiTransitionDurationTargetCoors;
fractionInterTarget = clamp(fractionInterTarget, 0.0f, 1.0f);
fractionInterTarget = Clamp(fractionInterTarget, 0.0f, 1.0f);
// Interpolate target separately
if(fractionInterTarget <= m_fFractionInterToStopMovingTarget){
@ -551,7 +551,7 @@ CCamera::Process(void)
// Process Shake
float shakeStrength = m_fCamShakeForce - 0.28f*(CTimer::GetTimeInMilliseconds()-m_uiCamShakeStart)/1000.0f;
shakeStrength = clamp(shakeStrength, 0.0f, 2.0f);
shakeStrength = Clamp(shakeStrength, 0.0f, 2.0f);
int shakeRand = CGeneral::GetRandomNumber();
float shakeOffset = shakeStrength*0.1f;
GetMatrix().GetPosition().x += shakeOffset * ((shakeRand & 0xF) - 7);
@ -1913,7 +1913,7 @@ CCamera::CamShake(float strength, float x, float y, float z)
float curForce = mult*(m_fCamShakeForce - (CTimer::GetTimeInMilliseconds() - m_uiCamShakeStart)/1000.0f);
strength = mult*strength;
if(clamp(curForce, 0.0f, 2.0f) < strength){
if(Clamp(curForce, 0.0f, 2.0f) < strength){
m_fCamShakeForce = strength;
m_uiCamShakeStart = CTimer::GetTimeInMilliseconds();
}
@ -1924,7 +1924,7 @@ void
CamShakeNoPos(CCamera *cam, float strength)
{
float curForce = cam->m_fCamShakeForce - (CTimer::GetTimeInMilliseconds() - cam->m_uiCamShakeStart)/1000.0f;
if(clamp(curForce, 0.0f, 2.0f) < strength){
if(Clamp(curForce, 0.0f, 2.0f) < strength){
cam->m_fCamShakeForce = strength;
cam->m_uiCamShakeStart = CTimer::GetTimeInMilliseconds();
}
@ -3985,7 +3985,7 @@ CCamera::Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source,
float
CCamera::Find3rdPersonQuickAimPitch(void)
{
float clampedFrontZ = clamp(Cams[ActiveCam].Front.z, -1.0f, 1.0f);
float clampedFrontZ = Clamp(Cams[ActiveCam].Front.z, -1.0f, 1.0f);
float rot = Asin(clampedFrontZ);
@ -4017,7 +4017,7 @@ CCamera::SetRwCamera(RwCamera *cam)
void
CCamera::CalculateDerivedValues(void)
{
m_cameraMatrix = Invert(m_matrix);
m_cameraMatrix = Invert(GetMatrix());
float hfov = DEGTORAD(CDraw::GetScaledFOV()/2.0f);
float c = Cos(hfov);
@ -4101,16 +4101,11 @@ CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat
bool
CCamera::IsSphereVisible(const CVector &center, float radius)
{
CMatrix mat = m_cameraMatrix;
return IsSphereVisible(center, radius, &mat);
return IsSphereVisible(center, radius, &GetCameraMatrix());
}
bool
#ifdef GTA_PS2
CCamera::IsBoxVisible(CVuVector *box, const CMatrix *mat)
#else
CCamera::IsBoxVisible(CVector *box, const CMatrix *mat)
#endif
CCamera::IsBoxVisible(CVUVECTOR *box, const CMatrix *mat)
{
int i;
int frustumTests[6] = { 0 };

View File

@ -633,11 +633,7 @@ public:
bool IsPointVisible(const CVector &center, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius, const CMatrix *mat);
bool IsSphereVisible(const CVector &center, float radius);
#ifdef GTA_PS2
bool IsBoxVisible(CVuVector *box, const CMatrix *mat);
#else
bool IsBoxVisible(CVector *box, const CMatrix *mat);
#endif
bool IsBoxVisible(CVUVECTOR *box, const CMatrix *mat);
};
VALIDATE_SIZE(CCamera, 0xE9D8);

View File

@ -20,6 +20,7 @@
#include <fcntl.h>
#include <sys/resource.h>
#include <stdarg.h>
#include <limits.h>
#ifdef __linux__
#include <sys/syscall.h>

View File

@ -28,7 +28,7 @@ class CCrimeBeingQd
{
public:
eCrimeType m_nType;
uint32 m_nId;
int32 m_nId;
uint32 m_nTime;
CVector m_vecPosn;
bool m_bReported;

View File

@ -1122,7 +1122,7 @@ CFileLoader::Load2dEffect(const char *line)
&probability);
effect->attractor.type = flags;
#ifdef FIX_BUGS
effect->attractor.probability = clamp(probability, 0, 255);
effect->attractor.probability = Clamp(probability, 0, 255);
#else
effect->attractor.probability = probability;
#endif
@ -1254,7 +1254,7 @@ CFileLoader::LoadObjectInstance(const char *line)
if(!CStreaming::IsObjectInCdImage(id))
debug("Not in cdimage %s\n", mi->GetModelName());
angle = -RADTODEG(2.0f * acosf(angle));
angle = -RADTODEG(2.0f * Acos(angle));
xform = RwMatrixCreate();
RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
RwMatrixTranslate(xform, &trans, rwCOMBINEPOSTCONCAT);

View File

@ -457,7 +457,7 @@ CFireManager::StartScriptFire(const CVector &pos, CEntity *target, float strengt
if (target) {
if (target->IsPed()) {
ped->m_pFire = fire;
if (target != (CVehicle *)FindPlayerPed()) {
if (target != FindPlayerPed()) {
CVector2D pos = target->GetPosition();
ped->SetFlee(pos, 10000);
ped->SetMoveAnim();

View File

@ -181,7 +181,7 @@ const char* FrontendFilenames[][2] = {
#ifdef XBOX_MESSAGE_SCREEN
bool CMenuManager::m_bDialogOpen = false;
uint32 CMenuManager::m_nDialogHideTimer = 0;
PauseModeTime CMenuManager::m_nDialogHideTimerPauseMode = 0;
uint32 CMenuManager::m_nDialogHideTimerPauseMode = 0;
bool CMenuManager::m_bSaveWasSuccessful = false;
wchar* CMenuManager::m_pDialogText = nil;
#endif
@ -701,27 +701,27 @@ CMenuManager::CheckSliderMovement(int value)
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
m_PrefsBrightness += value * 24.19f;
m_PrefsBrightness = clamp(m_PrefsBrightness, 0, 384);
m_PrefsBrightness = Clamp(m_PrefsBrightness, 0, 384);
break;
case MENUACTION_DRAWDIST:
if(value > 0)
m_PrefsLOD += ((1.8f - 0.925f) / 16.0f);
else
m_PrefsLOD -= ((1.8f - 0.925f) / 16.0f);
m_PrefsLOD = clamp(m_PrefsLOD, 0.925f, 1.8f);
m_PrefsLOD = Clamp(m_PrefsLOD, 0.925f, 1.8f);
CRenderer::ms_lodDistScale = m_PrefsLOD;
break;
case MENUACTION_MUSICVOLUME:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_PrefsMusicVolume += value * (128 / 32);
m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65);
m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 65);
DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
}
break;
case MENUACTION_SFXVOLUME:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_PrefsSfxVolume += value * (128 / 32);
m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 65);
m_PrefsSfxVolume = Clamp(m_PrefsSfxVolume, 0, 65);
DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
}
break;
@ -729,14 +729,14 @@ CMenuManager::CheckSliderMovement(int value)
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
if (DMAudio.IsMP3RadioChannelAvailable()) {
m_PrefsMP3BoostVolume += value * (128 / 32);
m_PrefsMP3BoostVolume = clamp(m_PrefsMP3BoostVolume, 0, 65);
m_PrefsMP3BoostVolume = Clamp(m_PrefsMP3BoostVolume, 0, 65);
DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
}
}
break;
case MENUACTION_MOUSESENS:
TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ???
TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
#endif
@ -754,7 +754,7 @@ CMenuManager::DisplayHelperText(char *text)
return;
// there was a unused static bool
static PauseModeTime LastFlash = 0;
static uint32 LastFlash = 0;
int32 alpha = 255;
CFont::SetRightJustifyOn();
@ -1429,19 +1429,21 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
}
static PauseModeTime lastBlendChange = 0;
static uint32 lastBlendChange = 0;
if (m_nOptionHighlightTransitionBlend <= 255) {
static uint32 blendChangeCounter = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastBlendChange > 20
#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack
|| blendChangeCounter > 20
#endif
) {
m_nOptionHighlightTransitionBlend += 50;
lastBlendChange = CTimer::GetTimeInMillisecondsPauseMode();
blendChangeCounter = 0;
}
#ifdef FIX_BUGS
blendChangeCounter += CTimer::GetLogicalFramesPassed();
#else
++blendChangeCounter;
#endif
}
}
@ -1932,7 +1934,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
CFont::PrintString(nextX, nextY, seperator);
nextX += CFont::GetStringWidth(seperator, true) + bindingMargin;
}
static PauseModeTime lastWaitingTextFlash = 0;
static uint32 lastWaitingTextFlash = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastWaitingTextFlash > 150) {
showWaitingText = !showWaitingText;
lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode();
@ -1997,7 +1999,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig
CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_IBT"));
nextX = CFont::GetStringWidth(TheText.Get("FEC_IBT"), true) + spacing + nextX;
}
static PauseModeTime lastStateChange = 0;
static uint32 lastStateChange = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastStateChange > 150) {
waitingTextVisible = !waitingTextVisible;
lastStateChange = CTimer::GetTimeInMillisecondsPauseMode();
@ -2381,22 +2383,27 @@ CMenuManager::DrawBackground(bool transitionCall)
m_nOptionHighlightTransitionBlend = 0;
}
static PauseModeTime LastFade = 0;
static uint32 LastFade = 0;
if (m_nMenuFadeAlpha < 255) {
static uint8 forceFadeInCounter = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 30
#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack
|| forceFadeInCounter > 30
#endif
) {
m_nMenuFadeAlpha += 20;
if (m_firstStartCounter < 255) {
m_firstStartCounter = Min(m_firstStartCounter + 20, 255);
}
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
#ifdef FIX_BUGS
forceFadeInCounter = 0;
#endif
}
#ifdef FIX_BUGS
forceFadeInCounter += CTimer::GetLogicalFramesPassed();
#else
forceFadeInCounter++;
#endif
} else if (m_nMenuFadeAlpha > 255)
m_nMenuFadeAlpha = 255;
@ -2452,7 +2459,7 @@ CMenuManager::DrawBackground(bool transitionCall)
}
if (m_ShowEmptyBindingError) {
static PauseModeTime lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
static uint32 lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
static bool bindingErrorShown = false;
if (bindingErrorShown) {
lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
@ -2899,9 +2906,15 @@ CMenuManager::InitialiseChangedLanguageSettings()
{
if (m_bFrontEnd_ReloadObrTxtGxt) {
m_bFrontEnd_ReloadObrTxtGxt = false;
#ifdef FIX_BUGS
if (gGameState > GS_INIT_ONCE)
#endif
CTimer::Stop();
TheText.Unload();
TheText.Load();
#ifdef FIX_BUGS
if (gGameState > GS_INIT_ONCE)
#endif
CTimer::Update();
CGame::frenchGame = false;
CGame::germanGame = false;
@ -3112,11 +3125,10 @@ CMenuManager::LoadSettings()
#ifdef LOAD_INI_SETTINGS
if (LoadINISettings()) {
LoadINIControllerSettings();
} else {
// no re3.ini, create it
SaveINISettings();
SaveINIControllerSettings();
}
// if no reVC.ini, create it, or update it with new values
SaveINISettings();
SaveINIControllerSettings();
#endif
#ifdef FIX_BUGS
@ -3348,7 +3360,7 @@ CMenuManager::PrintStats()
else
CFont::SetScale(MENU_X(0.37f), MENU_Y(0.75f));
static PauseModeTime lastCheck = 0;
static uint32 lastCheck = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastCheck > 40) {
@ -3476,8 +3488,8 @@ CMenuManager::Process(void)
break; \
\
m_fMapSize *= z2; \
m_fMapCenterX = clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2); \
m_fMapCenterY = clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2); \
m_fMapCenterX = Clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2); \
m_fMapCenterY = Clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2); \
} while(0)
#endif
@ -3489,7 +3501,7 @@ CMenuManager::AdditionalOptionInput(bool &goBack)
switch (m_nCurrScreen) {
case MENUPAGE_MAP:
{
static PauseModeTime lastMapTick = 0;
static uint32 lastMapTick = 0;
// FIX: All those macros were hardcoded values originally.
@ -3515,8 +3527,8 @@ CMenuManager::AdditionalOptionInput(bool &goBack)
m_fMapCenterX += (SCREEN_WIDTH/2 - m_fMapCenterX) / ((m_fMapSize - MENU_X(MAP_MIN_SIZE)) * 1/15.f);
m_fMapSize = Max(MENU_Y(MAP_MIN_SIZE), m_fMapSize - MENU_Y(15.f));
m_fMapCenterX = clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2);
m_fMapCenterY = clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2);
m_fMapCenterX = Clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2);
m_fMapCenterY = Clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2);
} else {
m_fMapSize = MENU_Y(MAP_MIN_SIZE);
}
@ -3557,8 +3569,8 @@ CMenuManager::AdditionalOptionInput(bool &goBack)
if (!justResetPointer) {
m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX;
m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY;
m_fMapCenterX = clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2);
m_fMapCenterY = clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2);
m_fMapCenterX = Clamp(m_fMapCenterX, SCREEN_WIDTH/2 - (m_fMapSize - MENU_X(MAP_MIN_SIZE)), m_fMapSize - MENU_X(MAP_MIN_SIZE) + SCREEN_WIDTH/2);
m_fMapCenterY = Clamp(m_fMapCenterY, SCREEN_HEIGHT/2 - (m_fMapSize - MENU_Y(MAP_MIN_SIZE)), m_fMapSize - MENU_Y(MAP_MIN_SIZE) + SCREEN_HEIGHT/2);
}
justResetPointer = false;
@ -3818,7 +3830,7 @@ CMenuManager::ExportStats()
void
CMenuManager::PrintRadioSelector(void)
{
static PauseModeTime lastRadioChange = 0;
static uint32 lastRadioChange = 0;
CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(418.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
MENU_X_LEFT_ALIGNED(228.f), MENU_Y(MENURADIO_SELECTOR_START_Y + MENURADIO_SELECTOR_HEIGHT),
@ -3941,7 +3953,7 @@ CMenuManager::PrintRadioSelector(void)
#endif
static bool radioChangeRequested = false;
static PauseModeTime lastScrollCheck = 0;
static uint32 lastScrollCheck = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastScrollCheck > 17) {
if (m_ScrollRadioBy == 1) {
if (m_LeftMostRadioX > MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - MENURADIO_ICON_SIZE)) {
@ -3984,7 +3996,7 @@ CMenuManager::PrintRadioSelector(void)
if (radioChangeRequested) {
if (CTimer::GetTimeInMillisecondsPauseMode() - lastRadioChange > 50) {
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
lastRadioChange = CTimer::GetTimeInMillisecondsPauseMode();
radioChangeRequested = false;
@ -4025,7 +4037,7 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack)
field_159 = false;
}
static PauseModeTime lastTimeClickedScrollButton = 0;
static uint32 lastTimeClickedScrollButton = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastTimeClickedScrollButton >= 200) {
m_bPressedPgUpOnList = false;
@ -4411,7 +4423,7 @@ CMenuManager::UserInput(void)
int curAction = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetPedWalkLeftRight() < 0 || CPad::GetPad(0)->GetDPadLeft()) {
static PauseModeTime lastSliderDecrease = 0;
static uint32 lastSliderDecrease = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderDecrease > 150) {
if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
@ -4422,7 +4434,7 @@ CMenuManager::UserInput(void)
lastSliderDecrease = CTimer::GetTimeInMillisecondsPauseMode();
}
} else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetPedWalkLeftRight() > 0 || CPad::GetPad(0)->GetDPadRight()) {
static PauseModeTime lastSliderIncrease = 0;
static uint32 lastSliderIncrease = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastSliderIncrease > 150) {
if (curAction == MENUACTION_BRIGHTNESS || curAction == MENUACTION_MUSICVOLUME ||
curAction == MENUACTION_SFXVOLUME || curAction == MENUACTION_RADIO ||
@ -4561,19 +4573,11 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
#ifdef USE_DEBUG_SCRIPT_LOADER
if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
#ifdef RW_GL3
if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
if (CPad::GetPad(0)->GetChar('R')) {
scriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
#elif defined _WIN32
if (GetAsyncKeyState('R') & 0x8000) {
scriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
#endif
}
#endif
@ -4718,7 +4722,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
case MENUACTION_LOADRADIO:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
SwitchToNewScreen(MENUPAGE_SOUND_SETTINGS);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
}
break;
@ -4823,7 +4827,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
SaveSettings();
} else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
m_PrefsBrightness = 256;
@ -5059,7 +5063,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
case MENUACTION_SPEAKERCONF:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_PrefsSpeakers -= changeAmount;
m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2);
m_PrefsSpeakers = Clamp(m_PrefsSpeakers, 0, 2);
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
SaveSettings();
}
@ -5418,7 +5422,7 @@ CMenuManager::ProcessFileActions()
{
#ifdef XBOX_MESSAGE_SCREEN
if (m_bDialogOpen && DialogTextCmp("FESZ_WR")) {
PauseModeTime startTime = CTimer::GetTimeInMillisecondsPauseMode();
uint32 startTime = CTimer::GetTimeInMillisecondsPauseMode();
int8 SaveSlot = PcSaveHelper.SaveSlot(m_nCurrSaveSlot);
PcSaveHelper.PopulateSlotInfo();
@ -5683,19 +5687,19 @@ CMenuManager::DrawQuitGameScreen(void)
static int32 exitSignalTimer = 0;
#ifdef FIX_BUGS
int alpha = clamp(m_nMenuFadeAlpha, 0, 255);
int alpha = Clamp(m_nMenuFadeAlpha, 0, 255);
#else
int alpha = m_nMenuFadeAlpha;
#endif
#ifndef MUCH_SHORTER_OUTRO_SCREEN
static PauseModeTime lastTickIncrease = 0;
static uint32 lastTickIncrease = 0;
if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) {
exitSignalTimer++;
lastTickIncrease = CTimer::GetTimeInMillisecondsPauseMode();
}
#else
static PauseModeTime firstTick = CTimer::GetTimeInMillisecondsPauseMode();
static uint32 firstTick = CTimer::GetTimeInMillisecondsPauseMode();
if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - firstTick > 750) {
exitSignalTimer = 150;
}

View File

@ -738,7 +738,7 @@ public:
#ifdef XBOX_MESSAGE_SCREEN
static uint32 m_nDialogHideTimer;
static PauseModeTime m_nDialogHideTimerPauseMode;
static uint32 m_nDialogHideTimerPauseMode;
static bool m_bDialogOpen;
static wchar *m_pDialogText;
static bool m_bSaveWasSuccessful;

View File

@ -779,7 +779,7 @@ TriggerAudio_RadioStation(CMenuMultiChoicePicturedTriggered *widget)
if ( CMenuManager::m_PrefsRadioStation != widget->GetMenuSelection() )
{
CMenuManager::m_PrefsRadioStation = widget->GetMenuSelection();
DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, TRUE);
DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
}
}

View File

@ -1375,7 +1375,7 @@ CMenuManager::DrawFrontEndNormal(void)
if ((m_nStartPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) <= 1600)
alpha = float(m_nStartPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) / 400.0f;
m_someAlpha = 255 - clamp(alpha, 0.0f, 1.0f) * 255.0f;
m_someAlpha = 255 - Clamp(alpha, 0.0f, 1.0f) * 255.0f;
switch ( m_nSlidingDir )
{
@ -1392,7 +1392,7 @@ CMenuManager::DrawFrontEndNormal(void)
float slide = float(m_nEndPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) / 800.0f;
float alpha = float((int32)(m_nEndPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) + -266) / 533.0f;
m_someAlpha = clamp(alpha, 0.0f, 1.0f) * 255.0f;
m_someAlpha = Clamp(alpha, 0.0f, 1.0f) * 255.0f;
switch ( m_nSlidingDir )
{
@ -2858,7 +2858,7 @@ CMenuManager::ProcessDPadCrossJustDown(void)
{
if ( !gMusicPlaying )
{
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
gMusicPlaying = true;
}
}

View File

@ -245,10 +245,16 @@ CGame::InitialiseRenderWare(void)
#ifdef LIBRW
#ifdef PS2_MATFX
rw::MatFX::modulateEnvMap = true;
rw::MatFX::envMapApplyLight = true;
rw::MatFX::envMapUseMatColor = true;
rw::MatFX::envMapFlipU = true;
#else
rw::MatFX::modulateEnvMap = false;
rw::MatFX::envMapApplyLight = false;
rw::MatFX::envMapUseMatColor = false;
rw::MatFX::envMapFlipU = false;
#endif
rw::RGBA envcol = { 64, 64, 64, 255 };
rw::MatFX::envMapColor = envcol;
#else
#ifdef PS2_MATFX
ReplaceMatFxCallback();
@ -571,7 +577,7 @@ bool CGame::Initialise(const char* datFile)
#endif
DMAudio.SetStartingTrackPositions(true);
DMAudio.SetStartingTrackPositions(TRUE);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
return true;
}

View File

@ -56,7 +56,7 @@ public:
static float LimitRadianAngle(float angle)
{
float result = clamp(angle, -25.0f, 25.0f);
float result = Clamp(angle, -25.0f, 25.0f);
while (result >= PI) {
result -= 2 * PI;

View File

@ -26,6 +26,7 @@
#include "ModelInfo.h"
#include "Pad.h"
#include "ControllerConfig.h"
#include "DMAudio.h"
// Menu screens array is at the bottom of the file.
@ -181,38 +182,6 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
}
#endif
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangRusSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangJapSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
#endif
#ifndef MULTISAMPLING
void GraphicsGoBack() {
}
@ -226,6 +195,8 @@ void MultiSamplingButtonPress(int8 action) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.Service();
FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings();
}
@ -287,6 +258,8 @@ const char* screenModes[] = { "FED_FLS", "FED_WND" };
void ScreenModeAfterChange(int8 before, int8 after)
{
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.Service();
FrontEndMenuManager.SetHelperText(0);
}
@ -471,11 +444,6 @@ CMenuScreenCustom aScreens[] = {
MENUACTION_LANG_GER, "FEL_GER", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_LANG_ITA, "FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
MENUACTION_LANG_SPA, "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#ifdef MORE_LANGUAGES
MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER,
MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER
MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER,
#endif
MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},

View File

@ -2,12 +2,13 @@
class CPlaceable
{
protected:
CMatrix m_matrix;
public:
// disable allocation
static void *operator new(size_t);
CMatrix m_matrix;
CPlaceable(void);
const CVector &GetPosition(void) { return m_matrix.GetPosition(); }
void SetPosition(float x, float y, float z) {
@ -20,6 +21,7 @@ public:
CVector &GetForward(void) { return m_matrix.GetForward(); }
CVector &GetUp(void) { return m_matrix.GetUp(); }
CMatrix &GetMatrix(void) { return m_matrix; }
void SetMatrix(CMatrix &newMatrix) { m_matrix = newMatrix; }
void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); }
void SetHeading(float angle);
void SetOrientation(float x, float y, float z){
@ -31,4 +33,4 @@ public:
bool IsWithinArea(float x1, float y1, float z1, float x2, float y2, float z2);
};
VALIDATE_SIZE(CPlaceable, 0x4C);
VALIDATE_SIZE(CPlaceable, 0x48);

View File

@ -299,7 +299,7 @@ CPlayerInfo::Process(void)
m_fRoadDensity = ThePaths.CalcRoadDensity(playerPos.x, playerPos.y);
}
m_fRoadDensity = clamp(m_fRoadDensity, 0.5f, 1.45f);
m_fRoadDensity = Clamp(m_fRoadDensity, 0.5f, 1.45f);
// Because vehicle enter/exit use same key binding.
bool enterOrExitVeh;

View File

@ -14,6 +14,7 @@
#include "Wanted.h"
#include "World.h"
#include "MemoryHeap.h"
#include "SaveBuf.h"
CCPtrNodePool *CPools::ms_pPtrNodePool;
CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool;
@ -105,7 +106,7 @@ CPools::CheckPoolsEmpty()
printf("pools have been cleared\n");
}
// Thankfully unused, it would break the game!
void
CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
{
@ -137,15 +138,20 @@ CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
void CPools::LoadVehiclePool(uint8* buf, uint32 size)
{
INITSAVEBUF
int nNumCars = ReadSaveBuf<int>(buf);
int nNumBoats = ReadSaveBuf<int>(buf);
int nNumBikes = ReadSaveBuf<int>(buf);
int nNumCars, nNumBoats, nNumBikes;
ReadSaveBuf(&nNumCars, buf);
ReadSaveBuf(&nNumBoats, buf);
ReadSaveBuf(&nNumBikes, buf);
for (int i = 0; i < nNumCars + nNumBoats + nNumBikes; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
int16 model = ReadSaveBuf<int16>(buf);
uint32 type;
int16 model;
int32 slot;
ReadSaveBuf(&type, buf);
ReadSaveBuf(&model, buf);
CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
CStreaming::LoadAllRequestedModels(false);
int32 slot = ReadSaveBuf<int32>(buf);
ReadSaveBuf(&slot, buf);
CVehicle* pVehicle;
#ifdef COMPATIBLE_SAVES
if (type == VEHICLE_TYPE_BOAT)
@ -304,9 +310,9 @@ INITSAVEBUF
#else
if ((pVehicle->IsCar() || pVehicle->IsBoat() || pVehicle->IsBike()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf<uint32>(buf, pVehicle->m_vehType);
WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex());
WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle));
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
pVehicle->Save(buf);
}
#else
@ -315,7 +321,7 @@ INITSAVEBUF
#else
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CAutomobile));
@ -326,7 +332,7 @@ INITSAVEBUF
#else
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CBoat));
@ -337,7 +343,7 @@ INITSAVEBUF
#else
if (pVehicle->IsBike() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CBike));

View File

@ -19,6 +19,7 @@
#include "Streaming.h"
#include "SpecialFX.h"
#include "Font.h"
#include "SaveBuf.h"
float CRadar::m_radarRange;
sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS];
@ -184,6 +185,75 @@ void GetTextureCorners(int32 x, int32 y, CVector2D *out)
out[3].y = RADAR_TILE_SIZE * (y);
}
uint8 CRadar::CalculateBlipAlpha(float dist)
{
if (FrontEndMenuManager.m_bMenuMapActive)
return 255;
if (dist <= 1.0f)
return 255;
if (dist <= 10.0f)
return (128.0f * ((dist - 1.0f) / 9.0f)) + ((1.0f - (dist - 1.0f) / 9.0f) * 255.0f);
return 128;
}
void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_bDim = bright != 1;
}
void CRadar::ChangeBlipColour(int32 i, int32 color)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_nColor = color;
}
void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_eBlipDisplay = display;
}
void CRadar::ChangeBlipScale(int32 i, int32 scale)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_wScale = scale;
}
void CRadar::ClearBlip(int32 i)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1) {
SetRadarMarkerState(index, false);
ms_RadarTrace[index].m_bInUse = false;
ms_RadarTrace[index].m_eBlipType = BLIP_NONE;
ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE;
}
}
void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
if (type == ms_RadarTrace[i].m_eBlipType && id == ms_RadarTrace[i].m_nEntityHandle) {
SetRadarMarkerState(i, false);
ms_RadarTrace[i].m_bInUse = false;
ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE;
}
};
}
// Why not a proper clipping algorithm?
#ifdef THIS_IS_STUPID
bool IsPointInsideRadar(const CVector2D &point)
{
@ -264,74 +334,6 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &
return edge;
}
uint8 CRadar::CalculateBlipAlpha(float dist)
{
if (FrontEndMenuManager.m_bMenuMapActive)
return 255;
if (dist <= 1.0f)
return 255;
if (dist <= 10.0f)
return (128.0f * ((dist - 1.0f) / 9.0f)) + ((1.0f - (dist - 1.0f) / 9.0f) * 255.0f);
return 128;
}
void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_bDim = bright != 1;
}
void CRadar::ChangeBlipColour(int32 i, int32 color)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_nColor = color;
}
void CRadar::ChangeBlipDisplay(int32 i, eBlipDisplay display)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_eBlipDisplay = display;
}
void CRadar::ChangeBlipScale(int32 i, int32 scale)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1)
ms_RadarTrace[index].m_wScale = scale;
}
void CRadar::ClearBlip(int32 i)
{
int index = GetActualBlipArrayIndex(i);
if (index != -1) {
SetRadarMarkerState(index, false);
ms_RadarTrace[index].m_bInUse = false;
ms_RadarTrace[index].m_eBlipType = BLIP_NONE;
ms_RadarTrace[index].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[index].m_eRadarSprite = RADAR_SPRITE_NONE;
}
}
void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
if (type == ms_RadarTrace[i].m_eBlipType && id == ms_RadarTrace[i].m_nEntityHandle) {
SetRadarMarkerState(i, false);
ms_RadarTrace[i].m_bInUse = false;
ms_RadarTrace[i].m_eBlipType = BLIP_NONE;
ms_RadarTrace[i].m_eBlipDisplay = BLIP_DISPLAY_NEITHER;
ms_RadarTrace[i].m_eRadarSprite = RADAR_SPRITE_NONE;
}
};
}
// Why not a proper clipping algorithm?
int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
{
CVector2D corners[4] = {
@ -410,6 +412,50 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
return n;
}
#else
int
ClipPolyPlane(const CVector2D *in, int nin, CVector2D *out, CVector *plane)
{
int j;
int nout;
int x1, x2;
float d1, d2, t;
nout = 0;
for(j = 0; j < nin; j++){
x1 = j;
x2 = (j+1) % nin;
d1 = plane->x*in[x1].x + plane->y*in[x1].y + plane->z;
d2 = plane->x*in[x2].x + plane->y*in[x2].y + plane->z;
if(d1*d2 < 0.0f){
t = d1/(d1 - d2);
out[nout++] = in[x1]*(1.0f-t) + in[x2]*t;
}
if(d2 >= 0.0f)
out[nout++] = in[x2];
}
return nout;
}
int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
{
CVector planes[4] = {
CVector(-1.0f, 0.0f, 1.0f),
CVector( 1.0f, 0.0f, 1.0f),
CVector(0.0f, -1.0f, 1.0f),
CVector(0.0f, 1.0f, 1.0f)
};
CVector2D tmp[8];
int n;
if(n = ClipPolyPlane(rect, 4, tmp, &planes[0]), n == 0) return 0;
if(n = ClipPolyPlane(tmp, n, poly, &planes[1]), n == 0) return 0;
if(n = ClipPolyPlane(poly, n, tmp, &planes[2]), n == 0) return 0;
if(n = ClipPolyPlane(tmp, n, poly, &planes[3]), n == 0) return 0;
return n;
}
#endif
bool CRadar::DisplayThisBlip(int32 counter)
{
@ -433,7 +479,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f;
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@ -447,7 +493,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += 3.0f;
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, CHARBLIP_MARKER_COLOR_R, CHARBLIP_MARKER_COLOR_G, CHARBLIP_MARKER_COLOR_B, CHARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 1.5f, CHARBLIP_MARKER_COLOR_R, CHARBLIP_MARKER_COLOR_G, CHARBLIP_MARKER_COLOR_B, CHARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@ -457,7 +503,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f;
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_ARROW, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@ -466,7 +512,7 @@ void CRadar::Draw3dMarkers()
case BLIP_CONTACT_POINT:
if (!CTheScripts::IsPlayerOnAMission()) {
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY)
C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, COORDBLIP_MARKER_COLOR_R, COORDBLIP_MARKER_COLOR_G, COORDBLIP_MARKER_COLOR_B, COORDBLIP_MARKER_COLOR_A, 2048, 0.2f, 0);
C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), MARKERTYPE_CYLINDER, ms_RadarTrace[i].m_vecPos, 2.0f, COORDBLIP_MARKER_COLOR_R, COORDBLIP_MARKER_COLOR_G, COORDBLIP_MARKER_COLOR_B, COORDBLIP_MARKER_COLOR_A, 2048, 0.2f, 0);
}
break;
}
@ -928,21 +974,21 @@ INITSAVEBUF
CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
for (int i = 0; i < NUMRADARBLIPS; i++) {
ms_RadarTrace[i].m_nColor = ReadSaveBuf<uint32>(buf);
ms_RadarTrace[i].m_Radius = ReadSaveBuf<float>(buf);
ms_RadarTrace[i].m_eBlipType = ReadSaveBuf<uint32>(buf);
ms_RadarTrace[i].m_nEntityHandle = ReadSaveBuf<int32>(buf);
ms_RadarTrace[i].m_vec2DPos.x = ReadSaveBuf<float>(buf); // CVector2D
ms_RadarTrace[i].m_vec2DPos.y = ReadSaveBuf<float>(buf);
ms_RadarTrace[i].m_vecPos = ReadSaveBuf<CVector>(buf);
ms_RadarTrace[i].m_BlipIndex = ReadSaveBuf<uint16>(buf);
ms_RadarTrace[i].m_bDim = ReadSaveBuf<bool>(buf);
ms_RadarTrace[i].m_bInUse = ReadSaveBuf<bool>(buf);
ms_RadarTrace[i].m_bShortRange = ReadSaveBuf<bool>(buf);
ms_RadarTrace[i].m_unused = ReadSaveBuf<bool>(buf);
ms_RadarTrace[i].m_wScale = ReadSaveBuf<int16>(buf);
ms_RadarTrace[i].m_eBlipDisplay = ReadSaveBuf<uint16>(buf);
ms_RadarTrace[i].m_eRadarSprite = ReadSaveBuf<uint16>(buf);
ReadSaveBuf(&ms_RadarTrace[i].m_nColor, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_Radius, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_eBlipType, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_nEntityHandle, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_vec2DPos.x, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_vec2DPos.y, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_vecPos, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_BlipIndex, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_bDim, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_bInUse, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_bShortRange, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_unused, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_wScale, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_eBlipDisplay, buf);
ReadSaveBuf(&ms_RadarTrace[i].m_eRadarSprite, buf);
}
VALIDATESAVEBUF(size);
@ -1337,7 +1383,7 @@ CRadar::InitFrontEndMap()
void
CRadar::DrawYouAreHereSprite(float x, float y)
{
static PauseModeTime lastChange = 0;
static uint32 lastChange = 0;
static bool show = true;
if (show) {
@ -1537,7 +1583,7 @@ void
CRadar::DrawLegend(int32 x, int32 y, int32 sprite)
{
if (sprite < 0) {
static PauseModeTime lastChange = 0;
static uint32 lastChange = 0;
static int8 blipMode = 0;
CRGBA color;

View File

@ -39,9 +39,7 @@ CEntity::RegisterReference(CEntity **pent)
ref->pentity = pent;
ref->next = m_pFirstReference;
m_pFirstReference = ref;
return;
}
return;
}
// Clean up the reference from *pent -> 'this'

View File

@ -1,5 +1,6 @@
#include "common.h"
#include "main.h"
#include "Timer.h"
#include "ModelIndices.h"
#include "Streaming.h"
@ -91,9 +92,11 @@ void
CRopes::Render(void)
{
int i;
PUSH_RENDERGROUP("CRopes::Render");
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive)
aRopes[i].Render();
POP_RENDERGROUP();
}
bool
@ -147,7 +150,7 @@ CRopes::FindCoorsAlongRope(uintptr id, float t, CVector *coors)
float f;
for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive && aRopes[i].m_id == id){
t = (ARRAY_SIZE(aRopes[0].m_pos)-1)*clamp(t, 0.0f, 0.999f);
t = (ARRAY_SIZE(aRopes[0].m_pos)-1)*Clamp(t, 0.0f, 0.999f);
j = t;
f = t - j;
*coors = (1.0f-f)*aRopes[i].m_pos[j] + f*aRopes[i].m_pos[j+1];

View File

@ -1229,7 +1229,11 @@ CStats::ConstructStatLine(int rowIdx)
FASTEST_TIME(20, "STFT_21");
if (FastestTimes[21])
#ifdef FIX_BUGS
STAT_LINE_1(float, "STFT_22", Floor(FastestTimes[21] / 10) / 100, 1);
#else
STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1);
#endif
if (TopShootingRangeScore > 0.0f)
STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0);

View File

@ -1732,7 +1732,13 @@ CStreaming::StreamVehiclesAndPeds(void)
for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){
if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq &&
((i == 0 && zone.carThreshold[0] != 0) ||
#ifdef FIX_BUGS
(i < CCarCtrl::NUM_CAR_CLASSES && zone.carThreshold[i] != zone.carThreshold[i-1]) ||
(i == CCarCtrl::NUM_CAR_CLASSES && zone.boatThreshold[i - CCarCtrl::NUM_CAR_CLASSES] != 0) ||
(i > CCarCtrl::NUM_CAR_CLASSES && i < CCarCtrl::TOTAL_CUSTOM_CLASSES && zone.boatThreshold[i - CCarCtrl::NUM_CAR_CLASSES] != zone.boatThreshold[i - CCarCtrl::NUM_CAR_CLASSES - 1]))) {
#else
(i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) {
#endif
maxReq = CCarCtrl::NumRequestsOfCarRating[i];
mostRequestedRating = i;
}
@ -1875,8 +1881,7 @@ CStreaming::RemoveCurrentZonesModels(void)
if (ms_currentPedGrp != -1)
for (i = 0; i < NUMMODELSPERPEDGROUP; i++) {
ms_bIsPedFromPedGroupLoaded[i] = false;
if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1 &&
CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) {
if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1) {
SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
}

View File

@ -8,7 +8,7 @@
#include "SpecialFX.h"
uint32 CTimer::m_snTimeInMilliseconds;
PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1;
uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
uint32 CTimer::m_snTimeInMillisecondsNonClipped;
uint32 CTimer::m_snPreviousTimeInMilliseconds;
@ -18,6 +18,10 @@ float CTimer::ms_fTimeStep;
float CTimer::ms_fTimeStepNonClipped;
bool CTimer::m_UserPause;
bool CTimer::m_CodePause;
#ifdef FIX_BUGS
uint32 CTimer::m_LogicalFrameCounter;
uint32 CTimer::m_LogicalFramesPassed;
#endif
uint32 _nCyclesPerMS = 1;
@ -35,10 +39,6 @@ RsTimerType suspendPcTimer;
uint32 suspendDepth;
#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double frameTime;
#endif
void CTimer::Initialise(void)
{
debug("Initialising CTimer...\n");
@ -51,6 +51,10 @@ void CTimer::Initialise(void)
m_snTimeInMillisecondsNonClipped = 0;
m_snPreviousTimeInMilliseconds = 0;
m_snTimeInMilliseconds = 1;
#ifdef FIX_BUGS
m_LogicalFrameCounter = 0;
m_LogicalFramesPassed = 0;
#endif
#ifdef _WIN32
LARGE_INTEGER perfFreq;
@ -82,6 +86,94 @@ void CTimer::Shutdown(void)
;
}
#ifdef FIX_BUGS
void CTimer::Update(void)
{
static double frameTimeLogical = 0.0;
static double frameTimeFraction = 0.0;
static double frameTimeFractionScaled = 0.0;
double frameTime;
double dblUpdInMs;
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
#ifdef _WIN32
if ( (double)_nCyclesPerMS != 0.0 )
{
LARGE_INTEGER pc;
QueryPerformanceCounter(&pc);
int32 updInCycles = (pc.LowPart - _oldPerfCounter.LowPart); // & 0x7FFFFFFF; pointless
_oldPerfCounter = pc;
float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
dblUpdInMs = (double)updInCycles / (double)_nCyclesPerMS;
}
else
#endif
{
RsTimerType timer = RsTimer();
RsTimerType updInMs = timer - oldPcTimer;
frameTime = (double)updInMs * ms_fTimeScale;
oldPcTimer = timer;
dblUpdInMs = (double)updInMs;
}
// count frames as if we're running at 30 fps
m_LogicalFramesPassed = 0;
frameTimeLogical += dblUpdInMs;
while (frameTimeLogical >= 1000.0 / 30.0) {
frameTimeLogical -= 1000.0 / 30.0;
m_LogicalFramesPassed++;
}
m_LogicalFrameCounter += m_LogicalFramesPassed;
frameTimeFraction += dblUpdInMs;
frameTimeFractionScaled += frameTime;
m_snTimeInMillisecondsPauseMode += uint32(frameTimeFraction);
if ( GetIsPaused() )
ms_fTimeStep = 0.0f;
else
{
m_snTimeInMilliseconds += uint32(frameTimeFractionScaled);
m_snTimeInMillisecondsNonClipped += uint32(frameTimeFractionScaled);
ms_fTimeStep = frameTime / 1000.0f * 50.0f;
}
frameTimeFraction -= uint32(frameTimeFraction);
frameTimeFractionScaled -= uint32(frameTimeFractionScaled);
if ( ms_fTimeStep < 0.01f && !GetIsPaused() && !CSpecialFX::bSnapShotActive)
ms_fTimeStep = 0.01f;
ms_fTimeStepNonClipped = ms_fTimeStep;
if ( !CRecordDataForGame::IsPlayingBack() )
{
ms_fTimeStep = Min(3.0f, ms_fTimeStep);
if ( (m_snTimeInMilliseconds - m_snPreviousTimeInMilliseconds) > 60 )
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 60;
}
if ( CRecordDataForChase::IsRecording() )
{
ms_fTimeStep = 1.0f;
m_snTimeInMilliseconds = m_snPreviousTimeInMilliseconds + 16;
}
m_FrameCounter++;
}
#else
void CTimer::Update(void)
{
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
@ -98,11 +190,7 @@ void CTimer::Update(void)
float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
// We need that real frame time to fix transparent menu bug.
#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double
#endif
frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
double frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
@ -122,11 +210,7 @@ void CTimer::Update(void)
RsTimerType updInMs = timer - oldPcTimer;
// We need that real frame time to fix transparent menu bug.
#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double
#endif
frameTime = (double)updInMs * ms_fTimeScale;
double frameTime = (double)updInMs * ms_fTimeScale;
oldPcTimer = timer;
@ -163,6 +247,7 @@ void CTimer::Update(void)
m_FrameCounter++;
}
#endif
void CTimer::Suspend(void)
{

View File

@ -1,22 +1,20 @@
#pragma once
#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
#define PauseModeTime double
#else
#define PauseModeTime uint32
#endif
class CTimer
{
static uint32 m_snTimeInMilliseconds;
static PauseModeTime m_snTimeInMillisecondsPauseMode;
static uint32 m_snTimeInMillisecondsPauseMode;
static uint32 m_snTimeInMillisecondsNonClipped;
static uint32 m_snPreviousTimeInMilliseconds;
static uint32 m_FrameCounter;
static float ms_fTimeScale;
static float ms_fTimeStep;
static float ms_fTimeStepNonClipped;
#ifdef FIX_BUGS
static uint32 m_LogicalFrameCounter;
static uint32 m_LogicalFramesPassed;
#endif
public:
static bool m_UserPause;
static bool m_CodePause;
@ -35,7 +33,7 @@ public:
static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
static PauseModeTime GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; }
static uint32 GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; }
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
@ -67,9 +65,7 @@ public:
#ifdef FIX_BUGS
static float GetDefaultTimeStep(void) { return 50.0f / 30.0f; }
static float GetTimeStepFix(void) { return GetTimeStep() / GetDefaultTimeStep(); }
static uint32 GetLogicalFrameCounter(void) { return m_LogicalFrameCounter; }
static uint32 GetLogicalFramesPassed(void) { return m_LogicalFramesPassed; }
#endif
};
#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
extern double frameTime;
#endif

View File

@ -65,7 +65,7 @@ CWorld::Initialise()
void
CWorld::Add(CEntity *ent)
{
if(ent->IsVehicle() || ent->IsPed()) DMAudio.SetEntityStatus(((CPhysical *)ent)->m_audioEntityId, true);
if(ent->IsVehicle() || ent->IsPed()) DMAudio.SetEntityStatus(((CPhysical *)ent)->m_audioEntityId, TRUE);
if(ent->bIsBIGBuilding)
ms_bigBuildingsList[ent->m_level].InsertItem(ent);
@ -80,7 +80,7 @@ CWorld::Add(CEntity *ent)
void
CWorld::Remove(CEntity *ent)
{
if(ent->IsVehicle() || ent->IsPed()) DMAudio.SetEntityStatus(((CPhysical *)ent)->m_audioEntityId, false);
if(ent->IsVehicle() || ent->IsPed()) DMAudio.SetEntityStatus(((CPhysical *)ent)->m_audioEntityId, FALSE);
if(ent->bIsBIGBuilding)
ms_bigBuildingsList[ent->m_level].RemoveItem(ent);
@ -399,8 +399,8 @@ CWorld::ProcessVerticalLine(const CVector &point1, float z2, CColPoint &point, C
CVector point2(point1.x, point1.y, z2);
int secX = GetSectorIndexX(point1.x);
int secY = GetSectorIndexY(point1.y);
secX = clamp(secX, 0, NUMSECTORS_X-1);
secY = clamp(secY, 0, NUMSECTORS_Y-1);
secX = Clamp(secX, 0, NUMSECTORS_X-1);
secY = Clamp(secY, 0, NUMSECTORS_Y-1);
return ProcessVerticalLineSector(*GetSector(secX, secY),
CColLine(point1, point2), point, entity, checkBuildings, checkVehicles,
checkPeds, checkObjects, checkDummies, ignoreSeeThrough, poly);
@ -1486,7 +1486,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1
CColModel *pColModel = pVehicle->GetColModel();
bool bInsideSphere = false;
for(int32 i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->m_matrix * pColModel->spheres[i].center;
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float fRadius = pColModel->spheres[i].radius;
if(pos.x + fRadius > x1 && pos.x - fRadius < x2 && pos.y + fRadius > y1 &&
pos.y - fRadius < y2)
@ -1803,7 +1803,7 @@ CWorld::RepositionOneObject(CEntity *pEntity)
position.z = FindGroundZFor3DCoord(position.x, position.y,
position.z + fHeight, nil) -
fBoundingBoxMinZ;
pEntity->m_matrix.UpdateRW();
pEntity->GetMatrix().UpdateRW();
pEntity->UpdateRwFrame();
} else if(IsLightThatNeedsRepositioning(modelId)) {
CVector position = pEntity->GetMatrix().GetPosition();

View File

@ -8,6 +8,7 @@
#include "Text.h"
#include "World.h"
#include "Timer.h"
#include "SaveBuf.h"
eLevelName CTheZones::m_CurrLevel;
int16 CTheZones::FindIndex;
@ -452,6 +453,7 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
assert(d >= 0.0f && d <= 1.0f);
n = 1.0f - d;
}
#ifdef FIX_BUGS
info->carDensity = day->carDensity * d + night->carDensity * n;
for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++)
info->carThreshold[i] = day->carThreshold[i] * d + night->carThreshold[i] * n;
@ -465,6 +467,22 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
info->copPedThreshold = day->copPedThreshold * d + night->copPedThreshold * n;
for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++)
info->gangPedThreshold[i] = day->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n;
#else
// This is a complete mess.
info->carDensity = day->carDensity * n + night->carDensity * d;
for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++)
info->carThreshold[i] = night->carThreshold[i] * d + night->carThreshold[i] * n;
for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++)
info->boatThreshold[i] = night->boatThreshold[i] * d + night->boatThreshold[i] * n;
for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++)
info->gangThreshold[i] = night->gangThreshold[i] * d + night->gangThreshold[i] * n;
info->copThreshold = night->copThreshold * d + night->copThreshold * n;
info->pedDensity = night->pedDensity * d + night->pedDensity * n;
info->copPedThreshold = night->copPedThreshold * d + night->copPedThreshold * n;
for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++)
info->gangPedThreshold[i] = night->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n;
#endif
}
if(CClock::GetIsTimeInRange(5, 19))
info->pedGroup = day->pedGroup;
@ -697,11 +715,11 @@ CTheZones::SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zo
WriteSaveBuf(*buffer, *length, zone->zoneinfoNight);
int32 zoneId;
zoneId = GetIndexForZonePointer(zone->child);
zoneId = GetIndexForNavigationZonePointer(zone->child);
WriteSaveBuf(*buffer, *length, zoneId);
zoneId = GetIndexForZonePointer(zone->parent);
zoneId = GetIndexForNavigationZonePointer(zone->parent);
WriteSaveBuf(*buffer, *length, zoneId);
zoneId = GetIndexForZonePointer(zone->next);
zoneId = GetIndexForNavigationZonePointer(zone->next);
WriteSaveBuf(*buffer, *length, zoneId);
}
@ -714,9 +732,9 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
uint32 length = 0;
CheckSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
m_CurrLevel = ReadSaveBuf<eLevelName>(buffer, length);
FindIndex = ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf(&m_CurrLevel, buffer);
ReadSaveBuf(&FindIndex, buffer);
SkipSaveBuf(buffer, 2);
for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++)
LoadOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG);
@ -725,21 +743,21 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
LoadOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer, length);
ReadSaveBuf(&ZoneInfoArray[i], buffer);
TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer, length);
TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer, length);
TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf(&TotalNumberOfNavigationZones, buffer);
ReadSaveBuf(&TotalNumberOfInfoZones, buffer);
ReadSaveBuf(&TotalNumberOfZoneInfos, buffer);
SkipSaveBuf(buffer, 2);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++)
LoadOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE);
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
AudioZoneArray[i] = ReadSaveBuf<int16>(buffer, length);
ReadSaveBuf(&AudioZoneArray[i], buffer);
TotalNumberOfMapZones = ReadSaveBuf<uint16>(buffer, length);
NumberOfAudioZones = ReadSaveBuf<uint16>(buffer, length);
ReadSaveBuf(&TotalNumberOfMapZones, buffer);
ReadSaveBuf(&NumberOfAudioZones, buffer);
VALIDATESAVEBUF(size)
}
@ -747,26 +765,36 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
void
CTheZones::LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
{
*(uint32*)&zone->name[0] = ReadSaveBuf<uint32>(*buffer, *length);
*(uint32*)&zone->name[4] = ReadSaveBuf<uint32>(*buffer, *length);
#ifdef THIS_IS_STUPID
uint32 part1, part2;
ReadSaveBuf(&part1, *buffer, *length);
ReadSaveBuf(&part2, *buffer, *length);
zone->minx = ReadSaveBuf<float>(*buffer, *length);
zone->miny = ReadSaveBuf<float>(*buffer, *length);
zone->minz = ReadSaveBuf<float>(*buffer, *length);
zone->maxx = ReadSaveBuf<float>(*buffer, *length);
zone->maxy = ReadSaveBuf<float>(*buffer, *length);
zone->maxz = ReadSaveBuf<float>(*buffer, *length);
*(uint64 *)&zone->name[0] = (uint64)part2;
*(uint64 *)&zone->name[0] <<= 32;
*(uint64 *)&zone->name[0] |= (uint64)part1;
#else
for(int i = 0; i < sizeof(zone->name); i++)
ReadSaveBuf(&zone->name[i], *buffer, *length);
#endif
zone->type = ReadSaveBuf<eZoneType>(*buffer, *length);
zone->level = ReadSaveBuf<eLevelName>(*buffer, *length);
zone->zoneinfoDay = ReadSaveBuf<int16>(*buffer, *length);
zone->zoneinfoNight = ReadSaveBuf<int16>(*buffer, *length);
ReadSaveBuf(&zone->minx, *buffer, *length);
ReadSaveBuf(&zone->miny, *buffer, *length);
ReadSaveBuf(&zone->minz, *buffer, *length);
ReadSaveBuf(&zone->maxx, *buffer, *length);
ReadSaveBuf(&zone->maxy, *buffer, *length);
ReadSaveBuf(&zone->maxz, *buffer, *length);
ReadSaveBuf(&zone->type, *buffer, *length);
ReadSaveBuf(&zone->level, *buffer, *length);
ReadSaveBuf(&zone->zoneinfoDay, *buffer, *length);
ReadSaveBuf(&zone->zoneinfoNight, *buffer, *length);
int32 zoneId;
zoneId = ReadSaveBuf<int32>(*buffer, *length);
zone->child = GetPointerForZoneIndex(zoneId);
zoneId = ReadSaveBuf<int32>(*buffer, *length);
zone->parent = GetPointerForZoneIndex(zoneId);
zoneId = ReadSaveBuf<int32>(*buffer, *length);
zone->next = GetPointerForZoneIndex(zoneId);
ReadSaveBuf(&zoneId, *buffer, *length);
zone->child = GetPointerForNavigationZoneIndex(zoneId);
ReadSaveBuf(&zoneId, *buffer, *length);
zone->parent = GetPointerForNavigationZoneIndex(zoneId);
ReadSaveBuf(&zoneId, *buffer, *length);
zone->next = GetPointerForNavigationZoneIndex(zoneId);
}

View File

@ -103,8 +103,8 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos);
static CZone *GetPointerForZoneIndex(ssize_t i) { return i == -1 ? nil : &NavigationZoneArray[i]; }
static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; }
static CZone *GetPointerForNavigationZoneIndex(ssize_t i) { return i == -1 ? nil : &NavigationZoneArray[i]; }
static ssize_t GetIndexForNavigationZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length);

View File

@ -244,6 +244,12 @@ inline uint32 ldb(uint32 p, uint32 s, uint32 w)
#include "maths.h"
#include "Vector.h"
#ifdef GTA_PS2
#include "VuVector.h"
#define CVUVECTOR CVuVector
#else
#define CVUVECTOR CVector
#endif
#include "Vector2D.h"
#include "Matrix.h"
#include "Rect.h"
@ -313,9 +319,9 @@ extern int strncasecmp(const char *str1, const char *str2, size_t len);
extern wchar *AllocUnicode(const char*src);
#define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
#define Clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
#define clamp2(v, center, radius) ((v) < (center) ? Max(v, center - radius) : Min(v, center + radius))
#define Clamp2(v, center, radius) ((v) < (center) ? Max(v, center - radius) : Min(v, center + radius))
inline float sq(float x) { return x*x; }
#define SQR(x) ((x) * (x))
@ -420,214 +426,3 @@ __inline__ void TRACE(char *f, ...) { } // this is re3 only, and so the function
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)
#ifdef DEBUGMENU
// Tweaking stuff for debugmenu
#define TWEAKPATH ___tw___TWEAKPATH
#define SETTWEAKPATH(path) static const char *___tw___TWEAKPATH = path;
#define TWEAKFUNC(v) static CTweakFunc CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), TWEAKPATH);
#define TWEAKFUNCN(v, name) static CTweakFunc CONCAT(___tw___tweak, __COUNTER__)(&v, name, TWEAKPATH);
#define TWEAKBOOL(v) static CTweakBool CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), TWEAKPATH);
#define TWEAKBOOLN(v, name) static CTweakBool CONCAT(___tw___tweak, __COUNTER__)(&v, name, TWEAKPATH);
#define TWEAKINT32(v, lower, upper, step) static CTweakInt32 CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKINT32N(v, lower, upper, step, name) static CTweakInt32 CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKUINT32(v, lower, upper, step) static CTweakUInt32 CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKUINT32N(v, lower, upper, step, name) static CTweakUInt32 CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKINT16(v, lower, upper, step) static CTweakInt16 CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKINT16N(v, lower, upper, step, name) static CTweakInt16 CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKUINT16(v, lower, upper, step) static CTweakUInt16 CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKUINT16N(v, lower, upper, step, name) static CTweakUInt16 CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKINT8(v, lower, upper, step) static CTweakInt8 CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKINT8N(v, lower, upper, step, name) static CTweakInt8 CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKUINT8(v, lower, upper, step) static CTweakUInt8 CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKUINT8N(v, lower, upper, step, name) static CTweakUInt8 CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKFLOAT(v, lower, upper, step) static CTweakFloat CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, step, TWEAKPATH);
#define TWEAKFLOATN(v, lower, upper, step, name) static CTweakFloat CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, step, TWEAKPATH);
#define TWEAKSWITCH(v, lower, upper, str, f) static CTweakSwitch CONCAT(___tw___tweak, __COUNTER__)(&v, STR(v), lower, upper, str, f, TWEAKPATH);
#define TWEAKSWITCHN(v, lower, upper, str, f, name) static CTweakSwitch CONCAT(___tw___tweak, __COUNTER__)(&v, name, lower, upper, str, f, TWEAKPATH);
// interface
class CTweakVar
{
public:
virtual void AddDBG(const char *path) = 0;
};
class CTweakVars
{
public:
static void Add(CTweakVar *var);
static void AddDBG(const char *path);
};
class CTweakFunc : public CTweakVar
{
const char *m_pPath, *m_pVarName;
void (*m_pFunc)();
public:
CTweakFunc(void (*pFunc)(), const char *strName, const char *strPath) :
m_pPath(strPath), m_pVarName(strName), m_pFunc(pFunc)
{
CTweakVars::Add(this);
}
void AddDBG(const char *path);
};
class CTweakBool : public CTweakVar
{
const char *m_pPath, *m_pVarName;
bool *m_pBoolVar;
public:
CTweakBool(bool *pBool, const char *strName, const char *strPath) :
m_pPath(strPath), m_pVarName(strName), m_pBoolVar(pBool)
{
CTweakVars::Add(this);
}
void AddDBG(const char *path);
};
class CTweakSwitch : public CTweakVar
{
const char *m_pPath, *m_pVarName;
void *m_pIntVar;
int32 m_nMin, m_nMax;
const char **m_aStr;
void (*m_pFunc)();
public:
CTweakSwitch(void *pInt, const char *strName, int32 nMin, int32 nMax, const char **aStr,
void (*pFunc)(), const char *strPath)
: m_pPath(strPath), m_pVarName(strName), m_pIntVar(pInt), m_nMin(nMin), m_nMax(nMax),
m_aStr(aStr)
{
CTweakVars::Add(this);
}
void AddDBG(const char *path);
};
#define _TWEEKCLASS(name, type) \
class name : public CTweakVar \
{ \
public: \
const char *m_pPath, *m_pVarName; \
type *m_pIntVar, m_nLoawerBound, m_nUpperBound, m_nStep; \
\
name(type *pInt, const char *strName, type nLower, type nUpper, type nStep, \
const char *strPath) \
: m_pPath(strPath), m_pVarName(strName), m_pIntVar(pInt), \
m_nLoawerBound(nLower), m_nUpperBound(nUpper), m_nStep(nStep) \
\
{ \
CTweakVars::Add(this); \
} \
\
void AddDBG(const char *path); \
};
_TWEEKCLASS(CTweakInt8, int8);
_TWEEKCLASS(CTweakUInt8, uint8);
_TWEEKCLASS(CTweakInt16, int16);
_TWEEKCLASS(CTweakUInt16, uint16);
_TWEEKCLASS(CTweakInt32, int32);
_TWEEKCLASS(CTweakUInt32, uint32);
_TWEEKCLASS(CTweakFloat, float);
#undef _TWEEKCLASS
#endif
#ifdef VALIDATE_SAVE_SIZE
extern int32 _saveBufCount;
#define INITSAVEBUF _saveBufCount = 0;
#define VALIDATESAVEBUF(b) assert(_saveBufCount == b);
#else
#define INITSAVEBUF
#define VALIDATESAVEBUF(b)
#endif
inline void SkipSaveBuf(uint8 *&buf, int32 skip)
{
buf += skip;
#ifdef VALIDATE_SAVE_SIZE
_saveBufCount += skip;
#endif
}
inline void SkipSaveBuf(uint8*& buf, uint32 &length, int32 skip)
{
buf += skip;
length += skip;
#ifdef VALIDATE_SAVE_SIZE
_saveBufCount += skip;
#endif
}
template<typename T>
inline const T ReadSaveBuf(uint8 *&buf)
{
T value;
memcpy(&value, buf, sizeof(T));
SkipSaveBuf(buf, sizeof(T));
return value;
}
template<typename T>
inline const T ReadSaveBuf(uint8 *&buf, uint32 &length)
{
T value;
memcpy(&value, buf, sizeof(T));
SkipSaveBuf(buf, length, sizeof(T));
return value;
}
template<typename T>
inline T *WriteSaveBuf(uint8 *&buf, const T &value)
{
memcpy(buf, &value, sizeof(T));
T* result = (T*)buf;
SkipSaveBuf(buf, sizeof(T));
return result;
}
template<typename T>
inline T *WriteSaveBuf(uint8 *&buf, uint32 &length, const T &value)
{
memcpy(buf, &value, sizeof(T));
T* result = (T*)buf;
SkipSaveBuf(buf, length, sizeof(T));
return result;
}
#define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32))
#define WriteSaveHeader(buf,a,b,c,d,size) \
WriteSaveBuf(buf, a);\
WriteSaveBuf(buf, b);\
WriteSaveBuf(buf, c);\
WriteSaveBuf(buf, d);\
WriteSaveBuf<uint32>(buf, size);
#define WriteSaveHeaderWithLength(buf,len,a,b,c,d,size) \
WriteSaveBuf(buf, len, a);\
WriteSaveBuf(buf, len, b);\
WriteSaveBuf(buf, len, c);\
WriteSaveBuf(buf, len, d);\
WriteSaveBuf<uint32>(buf, len, size);
#define CheckSaveHeader(buf,a,b,c,d,size)\
assert(ReadSaveBuf<char>(buf) == a);\
assert(ReadSaveBuf<char>(buf) == b);\
assert(ReadSaveBuf<char>(buf) == c);\
assert(ReadSaveBuf<char>(buf) == d);\
assert(ReadSaveBuf<uint32>(buf) == size);
#define CheckSaveHeaderWithLength(buf,len,a,b,c,d,size)\
assert(ReadSaveBuf<char>(buf,len) == a);\
assert(ReadSaveBuf<char>(buf,len) == b);\
assert(ReadSaveBuf<char>(buf,len) == c);\
assert(ReadSaveBuf<char>(buf,len) == d);\
assert(ReadSaveBuf<uint32>(buf,len) == size);
void cprintf(char*, ...);

View File

@ -1,7 +1,9 @@
#pragma once
// disables (most) stuff that wasn't in original gta-vc.exe - check section at the bottom of this file
//#define VANILLA_DEFINES
// disables (most) stuff that wasn't in original gta-vc.exe
#ifdef __MWERKS__
#define VANILLA_DEFINES
#endif
enum Config {
NUMPLAYERS = 1,
@ -131,7 +133,6 @@ enum Config {
NUM_PED_COMMENTS_SLOTS = 20,
NUM_SOUNDS_SAMPLES_BANKS = 2,
NUM_SOUNDS_SAMPLES_SLOTS = 27,
NUM_AUDIOENTITIES = 250,
NUM_AUDIO_REFLECTIONS = 8,
@ -155,8 +156,33 @@ enum Config {
//#define GTA_PS2
//#define GTA_XBOX
// This enables things from the PS2 version on PC
#define GTA_PS2_STUFF
// Version defines
#define GTAVC_PS2 400
#define GTAVC_PC_10 410
#define GTAVC_PC_11 411
#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
#define GTA_VERSION GTAVC_PC_11
// TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
# define PS2_MENU
#elif defined GTA_PC
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# define GTA_REPLAY
# define GTA_SCENE_EDIT
# define PC_MENU
# define PC_WATER
#elif defined GTA_XBOX
#endif
// This is enabled for all released games.
// any debug stuff that isn't left in any game is not in FINAL
@ -175,28 +201,35 @@ enum Config {
#define FINAL
#endif
// Version defines
#define GTAVC_PS2 400
#define GTAVC_PC_10 410
#define GTAVC_PC_11 411
#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
// these are placed here to work with VANILLA_DEFINES for compatibility
#define NO_CDCHECK // skip audio CD check
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define GTA_VERSION GTAVC_PC_11
#ifdef VANILLA_DEFINES
#if !defined(_WIN32) || defined(__LP64__) || defined(_WIN64)
#error Vanilla can only be built for win-x86
#endif
// TODO(MIAMI): someone ought to find and check out uses of these defines:
//#define GTA3_STEAM_PATCH
//#define GTAVC_JP_PATCH
#define FINAL
#define MASTER
//#define USE_MY_DOCUMENTS
#define THIS_IS_STUPID
#define DONT_FIX_REPLAY_BUGS
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
//#define USE_TEXTURE_POOL // not possible because R* used custom RW33
#else
// This enables things from the PS2 version on PC
#define GTA_PS2_STUFF
// quality of life fixes that should also be in FINAL
#define NASTY_GAME // nasty game for all languages
#define NO_CDCHECK
// those infamous texts
#define DRAW_GAME_VERSION_TEXT
#ifdef DRAW_GAME_VERSION_TEXT
// unlike R* development builds, ours has runtime switch on debug menu & .ini, and disabled as default.
#define USE_OUR_VERSIONING // If you disable this then game will fetch version from peds.col, as R* did while in development
// If you disable this then game will fetch version from peds.col, as R* did while in development.
//#define USE_OUR_VERSIONING // enabled from buildfiles by default
#endif
// Memory allocation and compression
@ -204,21 +237,10 @@ enum Config {
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
#elif defined GTA_PC
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
# endif
# define PC_PLAYER_CONTROLS // mouse player/cam mode
# define GTA_REPLAY
# define GTA_SCENE_EDIT
#elif defined GTA_XBOX
#if defined GTA_PC && defined GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
#endif
#ifdef VU_COLLISION
@ -232,7 +254,6 @@ enum Config {
// not in master builds
#define VALIDATE_SAVE_SIZE
#define NO_MOVIES // disable intro videos
#define DEBUGMENU
#endif
@ -246,10 +267,12 @@ enum Config {
#endif
#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds.
//#define MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#define MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible, and keeps saves compatible between platforms
#define FIX_INCOMPATIBLE_SAVES // try to fix incompatible saves, requires COMPATIBLE_SAVES
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
#define FIX_HIGH_FPS_BUGS_ON_FRONTEND
#define NO_MOVIES // add option to disable intro videos
#if defined(__LP64__) || defined(_WIN64)
#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build
@ -257,7 +280,7 @@ enum Config {
#define ASCII_STRCMP // use faster ascii str comparisons
#if !defined _WIN32 || defined __MWERKS__ || defined __MINGW32__ || defined VANILLA_DEFINES
#if !defined _WIN32 || defined __MINGW32__
#undef ASCII_STRCMP
#endif
@ -294,11 +317,11 @@ enum Config {
#endif
// Water & Particle
// #define PC_WATER
#undef PC_WATER
#define WATER_CHEATS
//#define USE_CUTSCENE_SHADOW_FOR_PED
#define DISABLE_CUTSCENE_SHADOWS
//#define USE_CUTSCENE_SHADOW_FOR_PED // requires COMPATIBLE_SAVES
//#define DISABLE_CUTSCENE_SHADOWS
// Pad
#if !defined(RW_GL3) && defined(_WIN32)
@ -399,9 +422,12 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
// Audio
#define RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
//#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
#define PS2_AUDIO_CHANNELS // increases the maximum number of audio channels to PS2 value of 43 (PC has 28 originally)
#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
#define MULTITHREADED_AUDIO // for streams. requires C++11 or later
#define PAUSE_RADIO_IN_FRONTEND // pause radio when game is paused
#ifdef AUDIO_OPUS
#define AUDIO_OAL_USE_OPUS // enable support of opus files
@ -426,6 +452,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#ifdef SQUEEZE_PERFORMANCE
#undef PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING
#undef PS2_AUDIO_CHANNELS
#endif
#ifdef __WIIU__
@ -438,92 +465,9 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define INI_BUFFER_SIZE (8*1024) // 8k should be enough for the ini file
#endif
// -------
#if defined __MWERKS__ || defined VANILLA_DEFINES
#define FINAL
#undef CHATTYSPLASH
#undef TIMEBARS
#define MASTER
#undef VALIDATE_SAVE_SIZE
#undef NO_MOVIES
#undef DEBUGMENU
#undef DRAW_GAME_VERSION_TEXT
//#undef NASTY_GAME
//#undef NO_CDCHECK
#undef GTA_PS2_STUFF
#undef USE_PS2_RAND
#undef RANDOMSPLASH
#undef PS2_MATFX
#undef FIX_BUGS
#define THIS_IS_STUPID
#undef MORE_LANGUAGES
#undef COMPATIBLE_SAVES
#undef LOAD_INI_SETTINGS
#undef FIX_HIGH_FPS_BUGS_ON_FRONTEND
#undef ASPECT_RATIO_SCALE
#undef PROPER_SCALING
//#undef DEFAULT_NATIVE_RESOLUTION
#undef PS2_ALPHA_TEST
#undef IMPROVED_VIDEOMODE
#undef DISABLE_LOADING_SCREEN
#undef DISABLE_VSYNC_ON_TEXTURE_CONVERSION
#undef FIX_SPRITES
#define PC_WATER
#undef WATER_CHEATS
// if these defines are enabled saves are not vanilla compatible without COMPATIBLE_SAVES
#ifndef COMPATIBLE_SAVES
#undef USE_CUTSCENE_SHADOW_FOR_PED
#undef DISABLE_CUTSCENE_SHADOWS
#undef XINPUT
#undef DETECT_PAD_INPUT_SWITCH
#undef KANGAROO_CHEAT
#undef RESTORE_ALLCARSHELI_CHEAT
#undef BETTER_ALLCARSAREDODO_CHEAT
#undef WALLCLIMB_CHEAT
#undef REGISTER_START_BUTTON
#undef BIND_VEHICLE_FIREWEAPON
#undef BUTTON_ICONS
#undef FIX_RADAR
#undef RADIO_OFF_TEXT
#undef MAP_ENHANCEMENTS
#undef GAMEPAD_MENU
#undef MUCH_SHORTER_OUTRO_SCREEN
#undef CUSTOM_FRONTEND_OPTIONS
#undef GRAPHICS_MENU_OPTIONS
#undef NO_ISLAND_LOADING
#undef CUTSCENE_BORDERS_SWITCH
#undef MULTISAMPLING
#undef INVERT_LOOK_FOR_PAD
#undef USE_DEBUG_SCRIPT_LOADER
#undef USE_MEASUREMENTS_IN_METERS
#undef USE_PRECISE_MEASUREMENT_CONVERTION
#undef SUPPORT_JAPANESE_SCRIPT
#undef MISSION_REPLAY
#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
#define DONT_FIX_REPLAY_BUGS
#undef EXPLODING_AIRTRAIN
#undef CPLANE_ROTORS
#undef CAMERA_PICKUP
#undef CANCELLABLE_CAR_ENTER
#undef IMPROVED_CAMERA
#undef FREE_CAM
#undef BIG_IMG
#undef RADIO_SCROLL_TO_PREV_STATION
#endif
#endif // VANILLA_DEFINES

View File

@ -95,7 +95,10 @@ bool gbModelViewer;
bool gbShowTimebars;
#endif
#ifdef DRAW_GAME_VERSION_TEXT
bool gDrawVersionText; // Our addition, we think it was always enabled on !MASTER builds
bool gbDrawVersionText; // Our addition, we think it was always enabled on !MASTER builds
#endif
#ifdef NO_MOVIES
bool gbNoMovies;
#endif
volatile int32 frameCount;
@ -376,7 +379,7 @@ DoRWStuffEndOfFrame(void)
}
#else
if (CPad::GetPad(1)->GetLeftShockJustDown() || CPad::GetPad(0)->GetFJustDown(11)) {
sprintf(s, "screen_%11lld.png", time(nil));
sprintf(s, "screen_%011lld.png", time(nil));
RwGrabScreen(Scene.camera, s);
}
#endif
@ -1068,7 +1071,7 @@ DisplayGameDebugText()
#ifdef DRAW_GAME_VERSION_TEXT
wchar ver[200];
if(gDrawVersionText) // This realtime switch is our thing
if(gbDrawVersionText) // This realtime switch is our thing
{
#ifdef USE_OUR_VERSIONING
@ -1128,11 +1131,14 @@ DisplayGameDebugText()
#endif // #ifdef DRAW_GAME_VERSION_TEXT
FrameSamples++;
#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
FramesPerSecondCounter += frameTime / 1000.f; // convert to seconds
#ifdef FIX_BUGS
// this is inaccurate with over 1000 fps
static uint32 PreviousTimeInMillisecondsPauseMode = 0;
FramesPerSecondCounter += (CTimer::GetTimeInMillisecondsPauseMode() - PreviousTimeInMillisecondsPauseMode) / 1000.0f; // convert to seconds
PreviousTimeInMillisecondsPauseMode = CTimer::GetTimeInMillisecondsPauseMode();
FramesPerSecond = FrameSamples / FramesPerSecondCounter;
#else
FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
FramesPerSecondCounter += 1000.0f / CTimer::GetTimeStepNonClippedInMilliseconds();
FramesPerSecond = FramesPerSecondCounter / FrameSamples;
#endif
@ -1261,6 +1267,7 @@ if(gbRenderEverythingBarRoads)
void
RenderScene_new(void)
{
PUSH_RENDERGROUP("RenderScene_new");
CClouds::Render();
DoRWRenderHorizon();
@ -1268,6 +1275,7 @@ RenderScene_new(void)
DefinedState();
// CMattRenderer::ResetRenderStates
// moved CRenderer::RenderBoats to before transparent water
POP_RENDERGROUP();
}
// TODO
@ -1275,11 +1283,14 @@ bool FredIsInFirstPersonCam(void) { return false; }
void
RenderEffects_new(void)
{
PUSH_RENDERGROUP("RenderEffects_new");
/* // stupid to do this before the whole world is drawn!
CShadows::RenderStaticShadows();
// CRenderer::GenerateEnvironmentMap
CShadows::RenderStoredShadows();
CSkidmarks::Render();
CRubbish::Render();
*/
// these aren't really effects
DefinedState();
@ -1302,6 +1313,13 @@ if(gbRenderFadingInEntities)
CRenderer::RenderFadingInEntities();
// actual effects here
// from above
CShadows::RenderStaticShadows();
CShadows::RenderStoredShadows();
CSkidmarks::Render();
CRubbish::Render();
CGlass::Render();
// CMattRenderer::ResetRenderStates
DefinedState();
@ -1319,6 +1337,7 @@ if(gbRenderFadingInEntities)
CPointLights::RenderFogEffect();
CMovingThings::Render();
CRenderer::RenderFirstPersonVehicle();
POP_RENDERGROUP();
}
#endif
@ -1331,6 +1350,7 @@ RenderScene(void)
return;
}
#endif
PUSH_RENDERGROUP("RenderScene");
CClouds::Render();
DoRWRenderHorizon();
CRenderer::RenderRoads();
@ -1346,11 +1366,13 @@ RenderScene(void)
RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
CWeather::RenderRainStreaks();
CCoronas::RenderSunReflection();
POP_RENDERGROUP();
}
void
RenderDebugShit(void)
{
PUSH_RENDERGROUP("RenderDebugShit");
CTheScripts::RenderTheScriptDebugLines();
#ifndef FINAL
if(gbShowCollisionLines)
@ -1359,6 +1381,7 @@ RenderDebugShit(void)
CDebug::DrawLines();
DefinedState();
#endif
POP_RENDERGROUP();
}
void
@ -1370,6 +1393,7 @@ RenderEffects(void)
return;
}
#endif
PUSH_RENDERGROUP("RenderEffects");
CGlass::Render();
CWaterCannons::Render();
CSpecialFX::Render();
@ -1386,11 +1410,13 @@ RenderEffects(void)
CPointLights::RenderFogEffect();
CMovingThings::Render();
CRenderer::RenderFirstPersonVehicle();
POP_RENDERGROUP();
}
void
Render2dStuff(void)
{
PUSH_RENDERGROUP("Render2dStuff");
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
@ -1462,6 +1488,7 @@ Render2dStuff(void)
#ifdef DEBUGMENU
DebugMenuRender();
#endif
POP_RENDERGROUP();
}
void
@ -1469,7 +1496,9 @@ RenderMenus(void)
{
if (FrontEndMenuManager.m_bMenuActive)
{
PUSH_RENDERGROUP("RenderMenus");
FrontEndMenuManager.DrawFrontEnd();
POP_RENDERGROUP();
}
#ifndef MASTER
else
@ -1480,6 +1509,7 @@ RenderMenus(void)
void
Render2dStuffAfterFade(void)
{
PUSH_RENDERGROUP("Render2dStuffAfterFade");
#ifndef MASTER
DisplayGameDebugText();
#endif
@ -1490,6 +1520,7 @@ Render2dStuffAfterFade(void)
CHud::DrawAfterFade();
CFont::DrawFonts();
CCredits::Render();
POP_RENDERGROUP();
}
void

View File

@ -1,5 +1,16 @@
#pragma once
#ifndef FINAL
// defined in RwHelpder.cpp
void PushRendergroup(const char *name);
void PopRendergroup(void);
#define PUSH_RENDERGROUP(str) PushRendergroup(str)
#define POP_RENDERGROUP() PopRendergroup()
#else
#define PUSH_RENDERGROUP(str)
#define POP_RENDERGROUP()
#endif
struct GlobalScene
{
RpWorld *world;
@ -55,3 +66,11 @@ void SaveINIControllerSettings();
extern bool gbNewRenderer;
bool FredIsInFirstPersonCam(void);
#endif
#ifdef DRAW_GAME_VERSION_TEXT
extern bool gbDrawVersionText;
#endif
#ifdef NO_MOVIES
extern bool gbNoMovies;
#endif

View File

@ -95,16 +95,51 @@ mysrand(unsigned int seed)
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h"
#ifdef MORE_LANGUAGES
void LangPolSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangRusSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
void LangJapSelect(int8 action)
{
if (action == FEOPTION_ACTION_SELECT) {
FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
FrontEndMenuManager.InitialiseChangedLanguageSettings();
FrontEndMenuManager.SaveSettings();
}
}
#endif
void
CustomFrontendOptionsPopulate(void)
{
// Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h
int fd;
// These work only if we have neo folder, so they're dynamically added
#ifdef EXTENDED_PIPELINES
const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" };
const char *off_on[] = { "FEM_OFF", "FEM_ON" };
int fd = CFileMgr::OpenFile("neo/neo.txd","r");
fd = CFileMgr::OpenFile("neo/neo.txd","r");
if (fd) {
#ifdef GRAPHICS_MENU_OPTIONS
FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
@ -121,22 +156,72 @@ CustomFrontendOptionsPopulate(void)
#endif
CFileMgr::CloseFile(fd);
}
#endif
// Add outsourced language translations, if files are found
#ifdef MORE_LANGUAGES
int fd2;
FrontendOptionSetCursor(MENUPAGE_LANGUAGE_SETTINGS, 5, false);
#if 0
if (fd = CFileMgr::OpenFile("text/polish.gxt")) {
if (fd2 = CFileMgr::OpenFile("models/fonts_p.txd")) {
FrontendOptionAddDynamic("FEL_POL", 0, 0, MENUALIGN_CENTER, nil, nil, LangPolSelect, nil, nil);
CFileMgr::CloseFile(fd2);
}
CFileMgr::CloseFile(fd);
}
#endif
if (fd = CFileMgr::OpenFile("text/russian.gxt")) {
if (fd2 = CFileMgr::OpenFile("models/fonts_r.txd")) {
FrontendOptionAddDynamic("FEL_RUS", 0, 0, MENUALIGN_CENTER, nil, nil, LangRusSelect, nil, nil);
CFileMgr::CloseFile(fd2);
}
CFileMgr::CloseFile(fd);
}
#if 0
if (fd = CFileMgr::OpenFile("text/japanese.gxt")) {
if (fd2 = CFileMgr::OpenFile("models/fonts_j.txd")) {
FrontendOptionAddDynamic("FEL_JAP", 0, 0, MENUALIGN_CENTER, nil, nil, LangJapSelect, nil, nil);
CFileMgr::CloseFile(fd2);
}
CFileMgr::CloseFile(fd);
}
#endif
#endif
}
#endif
#ifdef LOAD_INI_SETTINGS
#include "ini_parser.hpp"
#define MINI_CASE_SENSITIVE
#include "ini.h"
#ifdef WIIU_CHANNEL
mINI::INIFile ini("/vol/external01/wiiu/apps/reVC/reVC.ini");
#else
mINI::INIFile ini("reVC.ini");
#endif
mINI::INIStructure cfg;
linb::ini cfg;
bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtoul(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtoul(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
}
bool ReadIniIfExists(const char *cat, const char *key, uint8 *out)
{
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtoul(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -144,11 +229,10 @@ bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
bool ReadIniIfExists(const char *cat, const char *key, bool *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtoul(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtoul(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -156,11 +240,10 @@ bool ReadIniIfExists(const char *cat, const char *key, bool *out)
bool ReadIniIfExists(const char *cat, const char *key, int32 *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtol(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtol(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -168,11 +251,10 @@ bool ReadIniIfExists(const char *cat, const char *key, int32 *out)
bool ReadIniIfExists(const char *cat, const char *key, int8 *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
char *endPtr;
if (value && value[0] != '\xBA') {
*out = strtol(value, &endPtr, 0);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtol(section.get(key).c_str(), &endPtr, 0);
return true;
}
return false;
@ -180,10 +262,10 @@ bool ReadIniIfExists(const char *cat, const char *key, int8 *out)
bool ReadIniIfExists(const char *cat, const char *key, float *out)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
if (value && value[0] != '\xBA') {
*out = atof(value);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
char *endPtr;
*out = strtof(section.get(key).c_str(), &endPtr);
return true;
}
return false;
@ -191,10 +273,10 @@ bool ReadIniIfExists(const char *cat, const char *key, float *out)
bool ReadIniIfExists(const char *cat, const char *key, char *out, int size)
{
std::string strval = cfg.get(cat, key, "\xBA");
const char *value = strval.c_str();
if (value && value[0] != '\xBA') {
strncpy(out, value, size);
mINI::INIMap<std::string> section = cfg.get(cat);
if (section.has(key)) {
strncpy(out, section.get(key).c_str(), size - 1);
out[size - 1] = '\0';
return true;
}
return false;
@ -202,42 +284,42 @@ bool ReadIniIfExists(const char *cat, const char *key, char *out, int size)
void StoreIni(const char *cat, const char *key, uint32 val)
{
char temp[10];
sprintf(temp, "%u", val);
cfg.set(cat, key, temp);
char temp[11];
sprintf(temp, "%u", val);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, uint8 val)
{
char temp[10];
sprintf(temp, "%u", (uint32)val);
cfg.set(cat, key, temp);
char temp[11];
sprintf(temp, "%u", val);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, int32 val)
{
char temp[10];
char temp[11];
sprintf(temp, "%d", val);
cfg.set(cat, key, temp);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, int8 val)
{
char temp[10];
sprintf(temp, "%d", (int32)val);
cfg.set(cat, key, temp);
char temp[11];
sprintf(temp, "%d", val);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, float val)
{
char temp[10];
char temp[50];
sprintf(temp, "%f", val);
cfg.set(cat, key, temp);
cfg[cat][key] = temp;
}
void StoreIni(const char *cat, const char *key, char *val, int size)
{
cfg.set(cat, key, val);
cfg[cat][key] = val;
}
const char *iniControllerActions[] = { "PED_FIREWEAPON", "PED_CYCLE_WEAPON_RIGHT", "PED_CYCLE_WEAPON_LEFT", "GO_FORWARD", "GO_BACK", "GO_LEFT", "GO_RIGHT", "PED_SNIPER_ZOOM_IN",
@ -299,7 +381,7 @@ void LoadINIControllerSettings()
#endif
// force to default GTA behaviour (never overwrite bindings on joy change/initialization) if user init'ed/set bindings before we introduced that
if (!ReadIniIfExists("Controller", "PadButtonsInited", &ControlsManager.ms_padButtonsInited)) {
ControlsManager.ms_padButtonsInited = cfg.category_size("Bindings") != 0 ? 16 : 0;
ControlsManager.ms_padButtonsInited = cfg.get("Bindings").size() != 0 ? 16 : 0;
}
for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) {
@ -401,20 +483,13 @@ void SaveINIControllerSettings()
#endif
#endif
StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited);
#ifdef WIIU_CHANNEL
cfg.write_file("/vol/external01/wiiu/apps/reVC/reVC.ini");
#else
cfg.write_file("reVC.ini");
#endif
ini.write(cfg);
}
bool LoadINISettings()
{
#ifdef WIIU_CHANNEL
if (!cfg.load_file("/vol/external01/wiiu/apps/reVC/reVC.ini"))
#else
if (!cfg.load_file("reVC.ini"))
#endif
if (!ini.read(cfg))
return false;
#ifdef IMPROVED_VIDEOMODE
@ -479,12 +554,14 @@ bool LoadINISettings()
ReadIniIfExists("Draw", "FixSprites", &CDraw::ms_bFixSprites);
#endif
#ifdef DRAW_GAME_VERSION_TEXT
extern bool gDrawVersionText;
ReadIniIfExists("General", "DrawVersionText", &gDrawVersionText);
ReadIniIfExists("General", "DrawVersionText", &gbDrawVersionText);
#endif
#ifdef NO_MOVIES
ReadIniIfExists("General", "NoMovies", &gbNoMovies);
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
bool migrate = cfg.category_size("FrontendOptions") != 0;
bool migrate = cfg.get("FrontendOptions").size() != 0;
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
@ -497,7 +574,7 @@ bool LoadINISettings()
// Migrate from old .ini to new .ini
if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value))
cfg.remove("FrontendOptions", option.m_CFO->save);
cfg["FrontendOptions"].remove(option.m_CFO->save);
else
ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value);
@ -576,8 +653,10 @@ void SaveINISettings()
StoreIni("Draw", "FixSprites", CDraw::ms_bFixSprites);
#endif
#ifdef DRAW_GAME_VERSION_TEXT
extern bool gDrawVersionText;
StoreIni("General", "DrawVersionText", gDrawVersionText);
StoreIni("General", "DrawVersionText", gbDrawVersionText);
#endif
#ifdef NO_MOVIES
StoreIni("General", "NoMovies", gbNoMovies);
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
for (int i = 0; i < MENUPAGES; i++) {
@ -594,11 +673,7 @@ void SaveINISettings()
}
#endif
#ifdef WIIU_CHANNEL
cfg.write_file("/vol/external01/wiiu/apps/reVC/reVC.ini");
#else
cfg.write_file("reVC.ini");
#endif
ini.write(cfg);
}
#endif
@ -983,6 +1058,11 @@ extern bool gbRenderWorld2;
#ifndef MASTER
DebugMenuAddVarBool8("Render", "Occlusion debug", &bDispayOccDebugStuff, nil);
#endif
#ifdef LIBRW
DebugMenuAddVarBool32("Render", "MatFX env map apply light", &rw::MatFX::envMapApplyLight, nil);
DebugMenuAddVarBool32("Render", "MatFX env map flip U", &rw::MatFX::envMapFlipU, nil);
DebugMenuAddVarBool32("Render", "MatFX env map use matcolor", &rw::MatFX::envMapUseMatColor, nil);
#endif
#ifdef EXTENDED_PIPELINES
static const char *vehpipenames[] = { "MatFX", "Neo" };
e = DebugMenuAddVar("Render", "Vehicle Pipeline", &CustomPipes::VehiclePipeSwitch, nil,
@ -1011,14 +1091,14 @@ extern bool gbRenderWorld2;
#ifdef DRAW_GAME_VERSION_TEXT
extern bool gDrawVersionText;
DebugMenuAddVarBool8("Debug", "Version Text", &gDrawVersionText, nil);
DebugMenuAddVarBool8("Debug", "Version Text", &gbDrawVersionText, nil);
#endif
DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil);
#ifdef TIMEBARS
DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil);
#endif
#ifndef FINAL
DebugMenuAddVarBool8("Debug", "Use debug render groups", &bDebugRenderGroups, nil);
DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil);
#ifdef USE_CUSTOM_ALLOCATOR
DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap);
@ -1124,7 +1204,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
strcat_s(re3_buff, re3_buffsize, "(Press Retry to debug the application)");
nCode = ::MessageBoxA(nil, re3_buff, "RE3 Assertion Failed!",
nCode = ::MessageBoxA(nil, re3_buff, "REVC Assertion Failed!",
MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
if (nCode == IDABORT)
@ -1151,7 +1231,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
OSFatal(buf);
#else
// TODO
printf("\nRE3 ASSERT FAILED\n\tFile: %s\n\tLine: %d\n\tFunction: %s\n\tExpression: %s\n",filename,lineno,func,expr);
printf("\nREVC ASSERT FAILED\n\tFile: %s\n\tLine: %d\n\tFunction: %s\n\tExpression: %s\n",filename,lineno,func,expr);
assert(false);
#endif
}
@ -1207,7 +1287,7 @@ void re3_usererror(const char *format, ...)
vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va);
::MessageBoxA(nil, re3_buff, "RE3 Error!",
::MessageBoxA(nil, re3_buff, "REVC Error!",
MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
raise(SIGABRT);
@ -1215,9 +1295,9 @@ void re3_usererror(const char *format, ...)
#else
vsprintf(re3_buff, format, va);
#ifdef __WIIU__
WHBLogPrintf("\nRE3 Error!\n\t%s\n",re3_buff);
WHBLogPrintf("\nREVC Error!\n\t%s\n",re3_buff);
#else
printf("\nRE3 Error!\n\t%s\n",re3_buff);
printf("\nREVC Error!\n\t%s\n",re3_buff);
#endif
assert(false);
#endif

View File

@ -4,8 +4,8 @@
#include "World.h"
#include "Dummy.h"
void *CDummy::operator new(size_t sz) { return CPools::GetDummyPool()->New(); }
void CDummy::operator delete(void *p, size_t sz) { CPools::GetDummyPool()->Delete((CDummy*)p); }
void *CDummy::operator new(size_t sz) throw() { return CPools::GetDummyPool()->New(); }
void CDummy::operator delete(void *p, size_t sz) throw() { CPools::GetDummyPool()->Delete((CDummy*)p); }
void
CDummy::Add(void)

View File

@ -12,8 +12,8 @@ public:
void Add(void);
void Remove(void);
static void *operator new(size_t);
static void operator delete(void*, size_t);
static void *operator new(size_t) throw();
static void operator delete(void*, size_t) throw();
};
bool IsDummyPointerValid(CDummy* pDummy);

Some files were not shown because too many files have changed in this diff Show More