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/ sdk/
codewarrior/reVC.mcp
codewarrior/reVC_Data/ codewarrior/reVC_Data/
codewarrior/Release/ codewarrior/Release/
codewarrior/Debug/ 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 # 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) [![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 ## 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). 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) 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).\ 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. 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. 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/). - 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 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 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) - [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) - [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/ubuntu-18.04-gl3.zip)
- [MacOS 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/miami/macos-latest-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 gamefiles and in case of OpenAL the required dlls. - 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 ## Screenshots
@ -120,6 +120,12 @@ conan build .. -if build -bf build -pf package
``` ```
</details> </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> <details><summary>FreeBSD</summary>
For FreeBSD using premake, proceed: [Building on FreeBSD](https://github.com/GTAmodding/re3/wiki/Building-on-FreeBSD) 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). **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> </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. > :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 { newoption {
trigger = "lto", trigger = "with-lto",
description = "Use link time optimization" 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 if(_OPTIONS["with-librw"]) then
@ -58,7 +68,7 @@ end
workspace "reVC" workspace "reVC"
language "C++" language "C++"
configurations { "Debug", "Release", "Vanilla" } configurations { "Debug", "Release" }
startproject "reVC" startproject "reVC"
location "build" location "build"
symbols "Full" symbols "Full"
@ -70,6 +80,7 @@ workspace "reVC"
end end
filter { "system:windows" } filter { "system:windows" }
configurations { "Vanilla" }
platforms { platforms {
"win-x86-RW34_d3d8-mss", "win-x86-RW34_d3d8-mss",
"win-x86-librw_d3d9-mss", "win-x86-librw_d3d9-mss",
@ -109,13 +120,10 @@ workspace "reVC"
filter "configurations:not Debug" filter "configurations:not Debug"
defines { "NDEBUG" } defines { "NDEBUG" }
optimize "Speed" optimize "Speed"
if(_OPTIONS["lto"]) then if(_OPTIONS["with-lto"]) then
flags { "LinkTimeOptimization" } flags { "LinkTimeOptimization" }
end end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter { "platforms:win*" } filter { "platforms:win*" }
system "windows" system "windows"
@ -137,12 +145,18 @@ workspace "reVC"
filter { "platforms:*arm*" } filter { "platforms:*arm*" }
architecture "ARM" architecture "ARM"
filter { "platforms:macosx-arm64-*" } filter { "platforms:macosx-arm64-*", "files:**.cpp"}
buildoptions { "-target", "arm64-apple-macos11", "-std=gnu++14" } 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" } 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*" } filter { "platforms:*librw_d3d9*" }
defines { "RW_D3D9" } defines { "RW_D3D9" }
if(not _OPTIONS["with-librw"]) then if(not _OPTIONS["with-librw"]) then
@ -202,8 +216,14 @@ project "librw"
includedirs { "/usr/local/include" } includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" } 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 { "/opt/local/include" }
includedirs {"/usr/local/include" } includedirs {"/usr/local/include" }
libdirs { "/opt/local/lib" } libdirs { "/opt/local/lib" }
@ -253,7 +273,11 @@ project "reVC"
files { addSrcFiles("src/vehicles") } files { addSrcFiles("src/vehicles") }
files { addSrcFiles("src/weapons") } files { addSrcFiles("src/weapons") }
files { addSrcFiles("src/extras") } 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" }
includedirs { "src/animation" } includedirs { "src/animation" }
@ -279,12 +303,19 @@ project "reVC"
includedirs { "src/weapons" } includedirs { "src/weapons" }
includedirs { "src/extras" } includedirs { "src/extras" }
if(not _OPTIONS["no-git-hash"]) then
defines { "USE_OUR_VERSIONING" }
end
if _OPTIONS["with-opus"] then if _OPTIONS["with-opus"] then
includedirs { "vendor/ogg/include" } includedirs { "vendor/ogg/include" }
includedirs { "vendor/opus/include" } includedirs { "vendor/opus/include" }
includedirs { "vendor/opusfile/include" } includedirs { "vendor/opusfile/include" }
end end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter "platforms:*mss" filter "platforms:*mss"
defines { "AUDIO_MSS" } defines { "AUDIO_MSS" }
includedirs { "vendor/milessdk/include" } includedirs { "vendor/milessdk/include" }
@ -314,14 +345,22 @@ project "reVC"
linkoptions "/SAFESEH:NO" linkoptions "/SAFESEH:NO"
characterset ("MBCS") characterset ("MBCS")
targetextension ".exe" targetextension ".exe"
if(_OPTIONS["no-full-paths"]) then
usefullpaths "off"
linkoptions "/PDBALTPATH:%_PDB%"
end
if(_OPTIONS["with-librw"]) then if(_OPTIONS["with-librw"]) then
-- external librw is dynamic -- external librw is dynamic
staticruntime "on" staticruntime "on"
end 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*" 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*" filter "platforms:win*glfw*"
staticruntime "off" staticruntime "off"
@ -342,13 +381,19 @@ project "reVC"
libdirs { "vendor/openal-soft/libs/Win64" } libdirs { "vendor/openal-soft/libs/Win64" }
filter "platforms:linux*oal" filter "platforms:linux*oal"
links { "openal", "mpg123", "sndfile", "pthread" } links { "openal", "mpg123", "sndfile", "pthread", "X11" }
filter "platforms:bsd*oal" filter "platforms:bsd*oal"
links { "openal", "mpg123", "sndfile", "pthread" } links { "openal", "mpg123", "sndfile", "pthread", "X11" }
filter "platforms:macosx*oal" filter "platforms:macosx*oal"
links { "openal", "mpg123", "sndfile", "pthread" } 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" } includedirs { "/usr/local/opt/openal-soft/include" }
libdirs { "/usr/local/opt/openal-soft/lib" } libdirs { "/usr/local/opt/openal-soft/lib" }
@ -400,10 +445,18 @@ project "reVC"
includedirs { "/usr/local/include" } includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" } libdirs { "/usr/local/lib" }
filter "platforms:macosx*gl3_glfw*" filter "platforms:macosx-arm64-*gl3_glfw*"
links { "glfw" } links { "glfw" }
linkoptions { "-framework OpenGL" } linkoptions { "-framework OpenGL" }
includedirs { "/opt/local/include" } 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 { "/opt/local/lib" }
libdirs { "/usr/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 printf "%s\n" "\"" >> $1
printf "%s\n" "const char* g_GIT_SHA1 = GIT_SHA1;" >> $1
if (command -v "git" >/dev/null) then
git rev-parse --short HEAD | tr -d '\n' >> $1
fi fi
echo "\"" >> $1
echo "const char* g_GIT_SHA1 = GIT_SHA1;" >> $1

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ enum
}; };
struct ALDEVICEINFO { struct ALDEVICEINFO {
const char *strDeviceName; char *strDeviceName;
int iMajorVersion; int iMajorVersion;
int iMinorVersion; int iMinorVersion;
unsigned int uiSourceCount; unsigned int uiSourceCount;
@ -33,6 +33,19 @@ struct ALDEVICEINFO {
strDeviceName = NULL; strDeviceName = NULL;
Extensions = 0; 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; typedef ALDEVICEINFO *LPALDEVICEINFO;

View File

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

View File

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

View File

@ -1,9 +1,7 @@
#include "common.h" #include "common.h"
#ifdef AUDIO_OAL #ifdef AUDIO_OAL
#include "stream.h"
#include "sampman.h"
#include <stdio.h>
#include <malloc.h> #include <malloc.h>
#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK #if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK
@ -28,6 +26,29 @@
#include <opusfile.h> #include <opusfile.h>
#endif #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 #ifndef _WIN32
#include "crossplatform.h" #include "crossplatform.h"
#endif #endif
@ -45,6 +66,10 @@ class CSortStereoBuffer
{ {
uint16* PcmBuf; uint16* PcmBuf;
size_t BufSize; size_t BufSize;
//#ifdef MULTITHREADED_AUDIO
// std::mutex Mutex;
//#endif
public: public:
CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {} CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {}
~CSortStereoBuffer() ~CSortStereoBuffer()
@ -71,6 +96,9 @@ public:
void SortStereo(void* buf, size_t size) void SortStereo(void* buf, size_t size)
{ {
//#ifdef MULTITHREADED_AUDIO
// std::lock_guard<std::mutex> lock(Mutex);
//#endif
uint16* InBuf = (uint16*)buf; uint16* InBuf = (uint16*)buf;
uint16* OutBuf = GetBuffer(size); uint16* OutBuf = GetBuffer(size);
@ -140,7 +168,7 @@ public:
else else
StepIndex--; StepIndex--;
StepIndex = clamp(StepIndex, 0, 88); StepIndex = Clamp(StepIndex, 0, 88);
int delta = step >> 3; int delta = step >> 3;
if (adpcm & 1) delta += step >> 2; if (adpcm & 1) delta += step >> 2;
@ -149,7 +177,7 @@ public:
if (adpcm & 8) delta = -delta; if (adpcm & 8) delta = -delta;
int newSample = Sample + delta; int newSample = Sample + delta;
Sample = clamp(newSample, -32768, 32767); Sample = Clamp(newSample, -32768, 32767);
return Sample; return Sample;
} }
}; };
@ -285,6 +313,10 @@ public:
#undef CLOSE_ON_ERROR #undef CLOSE_ON_ERROR
} }
void FileOpen()
{
}
~CWavFile() ~CWavFile()
{ {
Close(); Close();
@ -295,6 +327,7 @@ public:
return m_bIsOpen; return m_bIsOpen;
} }
uint32 GetSampleSize() uint32 GetSampleSize()
{ {
return sizeof(uint16); return sizeof(uint16);
@ -464,6 +497,10 @@ public:
m_pfSound = sf_open_virtual(&vio, SFM_READ, &m_soundInfo, m_fileHandle); m_pfSound = sf_open_virtual(&vio, SFM_READ, &m_soundInfo, m_fileHandle);
} }
void FileOpen()
{
}
~CSndFile() ~CSndFile()
{ {
if ( m_pfSound ) if ( m_pfSound )
@ -642,18 +679,6 @@ public:
#endif #endif
#ifdef AUDIO_OAL_USE_MPG123 #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 class CMP3File : public IDecoder
{ {
@ -662,62 +687,58 @@ protected:
bool m_bOpened; bool m_bOpened;
uint32 m_nRate; uint32 m_nRate;
uint32 m_nChannels; uint32 m_nChannels;
FILE* m_fileHandle; const char* m_pPath;
char* m_buffer; bool m_bFileNotOpenedYet;
CMP3File() : CMP3File() :
m_pMH(nil), m_pMH(nil),
m_bOpened(false), m_bOpened(false),
m_nRate(0), m_nRate(0),
m_nChannels(0), m_bFileNotOpenedYet(false),
m_fileHandle(NULL), m_nChannels(0) {}
m_buffer(NULL) {}
public: public:
CMP3File(const char *path) : CMP3File(const char *path) :
m_pMH(nil), m_pMH(nil),
m_bOpened(false), m_bOpened(false),
m_nRate(0), m_nRate(0),
m_nChannels(0), m_nChannels(0),
m_fileHandle(NULL), m_pPath(path),
m_buffer(NULL) m_bFileNotOpenedYet(false)
{ {
m_pMH = mpg123_new(nil, nil); m_pMH = mpg123_new(nil, nil);
if ( m_pMH ) 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); 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 #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() ~CMP3File()
{ {
if ( m_pMH ) if ( m_pMH )
@ -725,13 +746,6 @@ public:
mpg123_close(m_pMH); mpg123_close(m_pMH);
mpg123_delete(m_pMH); mpg123_delete(m_pMH);
if (m_fileHandle) {
fclose(m_fileHandle);
}
free(m_buffer);
m_fileHandle = nil;
m_buffer = nil;
m_pMH = nil; m_pMH = nil;
} }
} }
@ -748,7 +762,7 @@ public:
uint32 GetSampleCount() uint32 GetSampleCount()
{ {
if ( !IsOpened() ) return 0; if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
return mpg123_length(m_pMH); return mpg123_length(m_pMH);
} }
@ -764,19 +778,19 @@ public:
void Seek(uint32 milliseconds) void Seek(uint32 milliseconds)
{ {
if ( !IsOpened() ) return; if ( !IsOpened() || m_bFileNotOpenedYet ) return;
mpg123_seek(m_pMH, ms2samples(milliseconds), SEEK_SET); mpg123_seek(m_pMH, ms2samples(milliseconds), SEEK_SET);
} }
uint32 Tell() uint32 Tell()
{ {
if ( !IsOpened() ) return 0; if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
return samples2ms(mpg123_tell(m_pMH)); return samples2ms(mpg123_tell(m_pMH));
} }
uint32 Decode(void *buffer) uint32 Decode(void *buffer)
{ {
if ( !IsOpened() ) return 0; if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
size_t size; size_t size;
int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &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); fseek((FILE*)fh, pos, seekType);
return ftell((FILE*)fh); return ftell((FILE*)fh);
} }
static void r_close(void* fh)
{
fclose((FILE*)fh);
}
public: public:
CADFFile(const char* path) CADFFile(const char* path)
{ {
m_pMH = mpg123_new(nil, nil); m_pMH = mpg123_new(nil, nil);
if (m_pMH) 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); 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 #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 #endif
@ -872,7 +895,7 @@ public:
static short quantize(double sample) static short quantize(double sample)
{ {
int a = int(sample + 0.5); 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) void Decode(void* _inbuf, int16* _outbuf, size_t size)
@ -966,6 +989,10 @@ public:
m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE]; m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE];
} }
void FileOpen()
{
}
~CVbFile() ~CVbFile()
{ {
if (m_pFile) if (m_pFile)
@ -1120,6 +1147,10 @@ public:
} }
} }
void FileOpen()
{
}
~COpusFile() ~COpusFile()
{ {
if (m_FileH) if (m_FileH)
@ -1184,11 +1215,173 @@ public:
}; };
#endif #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() void CStream::Initialise()
{ {
#ifdef AUDIO_OAL_USE_MPG123 #ifdef AUDIO_OAL_USE_MPG123
mpg123_init(); mpg123_init();
#endif #endif
#ifdef MULTITHREADED_AUDIO
gAudioThread = std::thread(audioFileOpsThread);
#endif
} }
void CStream::Terminate() void CStream::Terminate()
@ -1196,14 +1389,27 @@ void CStream::Terminate()
#ifdef AUDIO_OAL_USE_MPG123 #ifdef AUDIO_OAL_USE_MPG123
mpg123_exit(); mpg123_exit();
#endif #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_pAlSources(sources),
m_alBuffers(buffers), m_alBuffers(buffers),
m_pBuffer(nil), m_pBuffer(nil),
m_bPaused(false), m_bPaused(false),
m_bActive(false), m_bActive(false),
#ifdef MULTITHREADED_AUDIO
m_bIExist(false),
m_bDoSeek(false),
m_SeekPos(0),
#endif
m_pSoundFile(nil), m_pSoundFile(nil),
m_bReset(false), m_bReset(false),
m_nVolume(0), m_nVolume(0),
@ -1212,6 +1418,27 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
m_nLoopCount(1) 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/) // Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32) #if !defined(_WIN32)
char *real = casepath(filename); char *real = casepath(filename);
@ -1250,30 +1477,52 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
else else
m_pSoundFile = nil; m_pSoundFile = nil;
if ( IsOpened() ) if ( m_pSoundFile && m_pSoundFile->IsOpened() )
{ {
m_pBuffer = malloc(m_pSoundFile->GetBufferSize()); uint32 bufSize = m_pSoundFile->GetBufferSize();
ASSERT(m_pBuffer!=nil); if(bufSize != 0) { // Otherwise it's deferred
m_pBuffer = malloc(bufSize);
ASSERT(m_pBuffer != nil);
DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec()); DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount()); DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate()); DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
DEV("Channels: %d\n", m_pSoundFile->GetChannels()); DEV("Channels: %d\n", m_pSoundFile->GetChannels());
DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples()); 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("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); DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
}
return; #ifdef MULTITHREADED_AUDIO
m_bIExist = true;
#endif
return true;
} }
return false;
} }
CStream::~CStream() 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(); Stop();
ClearBuffers(); ClearBuffers();
@ -1288,6 +1537,7 @@ void CStream::Delete()
free(m_pBuffer); free(m_pBuffer);
m_pBuffer = nil; m_pBuffer = nil;
} }
#endif
} }
bool CStream::HasSource() bool CStream::HasSource()
@ -1295,9 +1545,14 @@ bool CStream::HasSource()
return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE); 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() bool CStream::IsOpened()
{ {
#ifdef MULTITHREADED_AUDIO
return m_bIExist;
#else
return m_pSoundFile && m_pSoundFile->IsOpened(); return m_pSoundFile && m_pSoundFile->IsOpened();
#endif
} }
bool CStream::IsPlaying() bool CStream::IsPlaying()
@ -1311,6 +1566,14 @@ bool CStream::IsPlaying()
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING) if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
return true; 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; return false;
@ -1372,10 +1635,10 @@ void CStream::SetVolume(uint32 nVol)
void CStream::SetPan(uint8 nPan) 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))); 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))); SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
m_nPan = nPan; m_nPan = nPan;
@ -1385,8 +1648,24 @@ void CStream::SetPan(uint8 nPan)
void CStream::SetPosMS(uint32 nPos) void CStream::SetPosMS(uint32 nPos)
{ {
if ( !IsOpened() ) return; 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(); ClearBuffers();
// adding to gStreamsToProcess not needed, someone always calls Start() / BuffersShouldBeFilled() after SetPosMS
} }
uint32 CStream::GetPosMS() uint32 CStream::GetPosMS()
@ -1394,10 +1673,16 @@ uint32 CStream::GetPosMS()
if ( !HasSource() ) return 0; if ( !HasSource() ) return 0;
if ( !IsOpened() ) return 0; if ( !IsOpened() ) return 0;
// Deferred init causes division by zero
if (m_pSoundFile->GetChannels() == 0)
return 0;
ALint offset; ALint offset;
//alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset); alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset);
//std::lock_guard<std::mutex> lock(m_mutex);
return m_pSoundFile->Tell() return m_pSoundFile->Tell()
- m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels() - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels()
+ m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / 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) bool CStream::FillBuffer(ALuint *alBuffer)
{ {
#ifndef MULTITHREADED_AUDIO
if ( !HasSource() ) if ( !HasSource() )
return false; return false;
if ( !IsOpened() ) if ( !IsOpened() )
@ -1419,6 +1705,7 @@ bool CStream::FillBuffer(ALuint *alBuffer)
return false; return false;
if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) ) if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) )
return false; return false;
#endif
uint32 size = m_pSoundFile->Decode(m_pBuffer); uint32 size = m_pSoundFile->Decode(m_pBuffer);
if( size == 0 ) if( size == 0 )
@ -1435,6 +1722,26 @@ bool CStream::FillBuffer(ALuint *alBuffer)
return true; 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 CStream::FillBuffers()
{ {
int32 i = 0; int32 i = 0;
@ -1464,17 +1771,33 @@ void CStream::ClearBuffers()
alSourceUnqueueBuffers(m_pAlSources[1], 1, &value); alSourceUnqueueBuffers(m_pAlSources[1], 1, &value);
} }
bool CStream::Setup(bool imSureQueueIsEmpty) bool CStream::Setup(bool imSureQueueIsEmpty, bool lock)
{ {
if ( IsOpened() ) if ( IsOpened() )
{ {
alSourcei(m_pAlSources[0], AL_LOOPING, AL_FALSE); #ifdef MULTITHREADED_AUDIO
alSourcei(m_pAlSources[1], AL_LOOPING, AL_FALSE); if (lock)
m_mutex.lock();
#endif
if (!imSureQueueIsEmpty) { if (!imSureQueueIsEmpty) {
SetPlay(false); Stop();
ClearBuffers(); 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); m_pSoundFile->Seek(0);
#endif
//SetPosition(0.0f, 0.0f, 0.0f); //SetPosition(0.0f, 0.0f, 0.0f);
SetPitch(1.0f); SetPitch(1.0f);
//SetPan(m_nPan); //SetPan(m_nPan);
@ -1512,7 +1835,7 @@ void CStream::SetPlay(bool state)
{ {
ALint sourceState = AL_STOPPED; ALint sourceState = AL_STOPPED;
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState);
if (sourceState != AL_STOPPED ) if (sourceState != AL_STOPPED)
alSourceStop(m_pAlSources[0]); alSourceStop(m_pAlSources[0]);
sourceState = AL_STOPPED; sourceState = AL_STOPPED;
@ -1527,8 +1850,12 @@ void CStream::SetPlay(bool state)
void CStream::Start() void CStream::Start()
{ {
if ( !HasSource() ) return; 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() void CStream::Stop()
@ -1550,8 +1877,22 @@ void CStream::Update()
if ( !m_bPaused ) 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 // 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. // 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 // 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. // 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) if (m_nLoopCount != 1 && m_bActive && totalBuffers[0] == 0)
{ {
Setup(true); #ifdef MULTITHREADED_AUDIO
buffersRefilled = FillBuffers() != 0; std::lock_guard<std::mutex> lock(m_mutex);
if (m_nLoopCount != 0)
m_nLoopCount--; 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 else
{ {
while( buffersProcessed[0]-- ) static std::queue<std::pair<ALuint, ALuint>> tempFillBuffer;
while ( buffersProcessed[0]-- )
{ {
ALuint buffer[2]; ALuint buffer[2];
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]); alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]); alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
if (m_bActive && FillBuffer(buffer)) if (m_bActive)
{ {
buffersRefilled = true; tempFillBuffer.push(std::pair<ALuint, ALuint>(buffer[0], buffer[1]));
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &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! // Source may be starved to audio and stopped itself
if (m_bActive && (buffersRefilled || (totalBuffers[1] - buffersProcessed[1] != 0))) if (m_bActive && !buffersQueuedAndStarted && (buffersQueuedButNotStarted || (totalBuffers[1] - buffersProcessed[1] != 0)))
SetPlay(true); SetPlay(true);
} }
} }
@ -1610,28 +1973,45 @@ void CStream::ProviderInit()
{ {
if ( m_bReset ) 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); SetPan(m_nPan);
SetVolume(m_nVolume); SetVolume(m_nVolume);
SetLoopCount(m_nLoopCount); SetLoopCount(m_nLoopCount);
SetPosMS(m_nPosBeforeReset); SetPosMS(m_nPosBeforeReset);
if (m_bActive) #ifdef MULTITHREADED_AUDIO
FillBuffers(); std::unique_lock<std::mutex> lock(m_mutex);
SetPlay(m_bActive); #endif
if ( m_bPaused ) if(m_bActive)
Pause(); 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() 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_bReset = true;
m_nPosBeforeReset = GetPosMS(); m_nPosBeforeReset = GetPosMS();
Stop();
ClearBuffers(); ClearBuffers();
} }

View File

@ -11,6 +11,7 @@ public:
virtual ~IDecoder() { } virtual ~IDecoder() { }
virtual bool IsOpened() = 0; virtual bool IsOpened() = 0;
virtual void FileOpen() = 0;
virtual uint32 GetSampleSize() = 0; virtual uint32 GetSampleSize() = 0;
virtual uint32 GetSampleCount() = 0; virtual uint32 GetSampleCount() = 0;
@ -48,12 +49,70 @@ public:
uint32 GetLength() uint32 GetLength()
{ {
FileOpen(); // abort deferred init, we need length now - game has to cache audio file sizes
return float(GetSampleCount()) * 1000.0f / float(GetSampleRate()); return float(GetSampleCount()) * 1000.0f / float(GetSampleRate());
} }
virtual uint32 Decode(void *buffer) = 0; 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 class CStream
{ {
char m_aFilename[128]; char m_aFilename[128];
@ -63,6 +122,17 @@ class CStream
bool m_bPaused; bool m_bPaused;
bool m_bActive; 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; void *m_pBuffer;
bool m_bReset; bool m_bReset;
@ -73,6 +143,13 @@ class CStream
IDecoder *m_pSoundFile; 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(); bool HasSource();
void SetPosition(int i, float x, float y, float z); void SetPosition(int i, float x, float y, float z);
void SetPitch(float pitch); void SetPitch(float pitch);
@ -81,15 +158,17 @@ class CStream
void SetPlay(bool state); void SetPlay(bool state);
bool FillBuffer(ALuint *alBuffer); bool FillBuffer(ALuint *alBuffer);
int32 FillBuffers(); int32 FillBuffers();
void ClearBuffers(); void ClearBuffers();
public: //public:
static void Initialise(); static void Initialise();
static void Terminate(); static void Terminate();
CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate = 32000); CStream(ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS]);
~CStream(); ~CStream();
void Delete(); void Delete();
bool Open(const char *filename, uint32 overrideSampleRate = 32000);
void Close();
bool IsOpened(); bool IsOpened();
bool IsPlaying(); bool IsPlaying();
@ -100,13 +179,12 @@ public:
uint32 GetPosMS(); uint32 GetPosMS();
uint32 GetLengthMS(); uint32 GetLengthMS();
bool Setup(bool imSureQueueIsEmpty = false); bool Setup(bool imSureQueueIsEmpty = false, bool lock = true);
void Start(); void Start();
void Stop(); void Stop();
void Update(void); void Update(void);
void SetLoopCount(int32); void SetLoopCount(int32);
void ProviderInit(); void ProviderInit();
void ProviderTerm(); 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" #include "AudioManager.h"
cSampleManager SampleManager; cSampleManager SampleManager;
bool _bSampmanInitialised = false; bool8 _bSampmanInitialised = FALSE;
uint32 BankStartOffset[MAX_SFX_BANKS]; uint32 BankStartOffset[MAX_SFX_BANKS];
uint32 nNumMP3s; uint32 nNumMP3s;
@ -60,7 +60,7 @@ int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
return 0; return 0;
} }
bool bool8
cSampleManager::IsMP3RadioChannelAvailable(void) cSampleManager::IsMP3RadioChannelAvailable(void)
{ {
return nNumMP3s != 0; return nNumMP3s != 0;
@ -75,10 +75,10 @@ void cSampleManager::ReacquireDigitalHandle(void)
{ {
} }
bool bool8
cSampleManager::Initialise(void) cSampleManager::Initialise(void)
{ {
return true; return TRUE;
} }
void void
@ -87,9 +87,9 @@ cSampleManager::Terminate(void)
} }
bool cSampleManager::CheckForAnAudioFileOnCD(void) bool8 cSampleManager::CheckForAnAudioFileOnCD(void)
{ {
return true; return TRUE;
} }
char cSampleManager::GetCDAudioDriveLetter(void) char cSampleManager::GetCDAudioDriveLetter(void)
@ -114,7 +114,7 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
} }
void void
cSampleManager::SetMusicMasterVolume(uint8 nVolume) cSampleManager::SetMP3BoostVolume(uint8 nVolume)
{ {
} }
@ -129,15 +129,15 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
} }
void void
cSampleManager::SetMonoMode(uint8 nMode) cSampleManager::SetMonoMode(bool8 nMode)
{ {
} }
bool bool8
cSampleManager::LoadSampleBank(uint8 nBank) cSampleManager::LoadSampleBank(uint8 nBank)
{ {
ASSERT( nBank < MAX_SFX_BANKS ); ASSERT( nBank < MAX_SFX_BANKS );
return false; return FALSE;
} }
void void
@ -146,20 +146,20 @@ cSampleManager::UnloadSampleBank(uint8 nBank)
ASSERT( nBank < MAX_SFX_BANKS ); ASSERT( nBank < MAX_SFX_BANKS );
} }
bool bool8
cSampleManager::IsSampleBankLoaded(uint8 nBank) cSampleManager::IsSampleBankLoaded(uint8 nBank)
{ {
ASSERT( nBank < MAX_SFX_BANKS ); ASSERT( nBank < MAX_SFX_BANKS );
return false; return FALSE;
} }
bool bool8
cSampleManager::IsPedCommentLoaded(uint32 nComment) cSampleManager::IsPedCommentLoaded(uint32 nComment)
{ {
ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
return false; return FALSE;
} }
@ -169,11 +169,11 @@ cSampleManager::_GetPedCommentSlot(uint32 nComment)
return -1; return -1;
} }
bool bool8
cSampleManager::LoadPedComment(uint32 nComment) cSampleManager::LoadPedComment(uint32 nComment)
{ {
ASSERT( nComment < TOTAL_AUDIO_SAMPLES ); ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
return false; return FALSE;
} }
int32 int32
@ -210,56 +210,56 @@ cSampleManager::GetSampleLength(uint32 nSample)
return 0; return 0;
} }
bool cSampleManager::UpdateReverb(void) bool8 cSampleManager::UpdateReverb(void)
{ {
return false; return FALSE;
} }
void void
cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag) cSampleManager::SetChannelReverbFlag(uint32 nChannel, bool8 nReverbFlag)
{ {
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
bool bool8
cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank) cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
{ {
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
return false; return FALSE;
} }
void void
cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
{ {
ASSERT( nChannel != CHANNEL2D ); ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
void void
cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ) cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
{ {
ASSERT( nChannel != CHANNEL2D ); ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
void void
cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin) cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
{ {
ASSERT( nChannel != CHANNEL2D ); ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
void void
cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume) cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
{ {
ASSERT( nChannel == CHANNEL2D ); ASSERT( nChannel >= MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
void void
cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan) cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
{ {
ASSERT(nChannel == CHANNEL2D); ASSERT( nChannel >= MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
@ -281,12 +281,12 @@ cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
} }
bool bool8
cSampleManager::GetChannelUsedFlag(uint32 nChannel) cSampleManager::GetChannelUsedFlag(uint32 nChannel)
{ {
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS ); ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
return false; return FALSE;
} }
void void
@ -308,7 +308,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
} }
void void
cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream) cSampleManager::PauseStream(bool8 nPauseFlag, uint8 nStream)
{ {
ASSERT( nStream < MAX_STREAMS ); ASSERT( nStream < MAX_STREAMS );
} }
@ -319,12 +319,12 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
ASSERT( nStream < MAX_STREAMS ); ASSERT( nStream < MAX_STREAMS );
} }
bool bool8
cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{ {
ASSERT( nStream < MAX_STREAMS ); ASSERT( nStream < MAX_STREAMS );
return false; return FALSE;
} }
void void
@ -342,7 +342,7 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
} }
void 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 ); ASSERT( nStream < MAX_STREAMS );
} }
@ -355,23 +355,23 @@ cSampleManager::GetStreamedFileLength(uint8 nStream)
return 1; return 1;
} }
bool bool8
cSampleManager::IsStreamPlaying(uint8 nStream) cSampleManager::IsStreamPlaying(uint8 nStream)
{ {
ASSERT( nStream < MAX_STREAMS ); ASSERT( nStream < MAX_STREAMS );
return false; return FALSE;
} }
bool bool8
cSampleManager::InitialiseSampleBanks(void) cSampleManager::InitialiseSampleBanks(void)
{ {
return true; return TRUE;
} }
void 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_49,
SOUND_WEAPON_BAT_ATTACK, SOUND_WEAPON_BAT_ATTACK,
SOUND_WEAPON_KNIFE_ATTACK, SOUND_WEAPON_KNIFE_ATTACK,
SOUND_WEAPON_CHAINSAW_ATTACK,
SOUND_WEAPON_CHAINSAW_IDLE, SOUND_WEAPON_CHAINSAW_IDLE,
SOUND_WEAPON_CHAINSAW_ATTACK,
SOUND_WEAPON_CHAINSAW_MADECONTACT, SOUND_WEAPON_CHAINSAW_MADECONTACT,
SOUND_WEAPON_SHOT_FIRED, SOUND_WEAPON_SHOT_FIRED,
SOUND_WEAPON_RELOAD, SOUND_WEAPON_RELOAD,
@ -116,8 +116,8 @@ enum eSound
SOUND_PED_MIAMIVICE_EXITING_CAR, SOUND_PED_MIAMIVICE_EXITING_CAR,
SOUND_PED_COP_HELIPILOTPHRASE, SOUND_PED_COP_HELIPILOTPHRASE,
SOUND_PED_PULLOUTWEAPON, SOUND_PED_PULLOUTWEAPON,
SOUND_PED_HELI_PLAYER_FOUND = 114, SOUND_PED_HELI_PLAYER_FOUND,
SOUND_PED_VCPA_PLAYER_FOUND = 115, SOUND_PED_VCPA_PLAYER_FOUND,
SOUND_PED_ON_FIRE, SOUND_PED_ON_FIRE,
SOUND_PED_AIMING, SOUND_PED_AIMING,
SOUND_PED_HANDS_UP, SOUND_PED_HANDS_UP,
@ -128,15 +128,15 @@ enum eSound
SOUND_PED_CAR_JACKED, SOUND_PED_CAR_JACKED,
SOUND_PED_ROBBED, SOUND_PED_ROBBED,
SOUND_PED_ACCIDENTREACTION1, SOUND_PED_ACCIDENTREACTION1,
SOUND_PED_UNK_126, SOUND_PED_INNOCENT,
SOUND_PED_PLAYER_AFTERSEX, SOUND_PED_PLAYER_AFTERSEX,
SOUND_PED_PLAYER_BEFORESEX, 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_COP_MANYCOPSAROUND, // also used for medics
SOUND_PED_GUNAIMEDAT2, SOUND_PED_GUNAIMEDAT2,
SOUND_PED_COP_ALONE, // also used for medics SOUND_PED_COP_ALONE, // also used for medics
SOUND_PED_GUNAIMEDAT3, SOUND_PED_GUNAIMEDAT3,
SOUND_PED_COP_REACTION, SOUND_PED_COP_ASK_FOR_ID,
SOUND_PED_COP_LITTLECOPSAROUND, // also used for medics SOUND_PED_COP_LITTLECOPSAROUND, // also used for medics
SOUND_PED_PLAYER_FARFROMCOPS, // also used for medics SOUND_PED_PLAYER_FARFROMCOPS, // also used for medics
SOUND_PED_TAXI_WAIT, SOUND_PED_TAXI_WAIT,
@ -151,12 +151,12 @@ enum eSound
SOUND_PED_ANNOYED_DRIVER, SOUND_PED_ANNOYED_DRIVER,
SOUND_PED_147, SOUND_PED_147,
SOUND_PED_SOLICIT, SOUND_PED_SOLICIT,
SOUND_PED_149, SOUND_PED_JEER,
SOUND_PED_150, SOUND_PED_150,
SOUND_PED_EXTINGUISHING_FIRE, SOUND_PED_EXTINGUISHING_FIRE,
SOUND_PED_WAIT_DOUBLEBACK, SOUND_PED_WAIT_DOUBLEBACK,
SOUND_153, SOUND_PED_CHAT_SEXY_FEMALE,
SOUND_PED_CHAT_SEXY, SOUND_PED_CHAT_SEXY_MALE,
SOUND_PED_CHAT_EVENT, SOUND_PED_CHAT_EVENT,
SOUND_PED_PED_COLLISION, SOUND_PED_PED_COLLISION,
SOUND_PED_CHAT, SOUND_PED_CHAT,

View File

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

View File

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

View File

@ -4,5 +4,5 @@
#include "Treadable.h" #include "Treadable.h"
#include "Pools.h" #include "Pools.h"
void *CTreadable::operator new(size_t sz) { return CPools::GetTreadablePool()->New(); } void *CTreadable::operator new(size_t sz) throw() { return CPools::GetTreadablePool()->New(); }
void CTreadable::operator delete(void *p, size_t sz) { CPools::GetTreadablePool()->Delete((CTreadable*)p); } 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 class CTreadable : public CBuilding
{ {
public: public:
static void *operator new(size_t); static void *operator new(size_t) throw();
static void operator delete(void*, size_t); static void operator delete(void*, size_t) throw();
bool GetIsATreadable(void) { return true; } bool GetIsATreadable(void) { return true; }
}; };

View File

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

View File

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

View File

@ -186,7 +186,7 @@ CColStore::LoadCollision(const CVector2D &pos)
}else{ }else{
for (int j = 0; j < MAX_CLEANUP; j++) { for (int j = 0; j < MAX_CLEANUP; j++) {
CPhysical* pEntity = nil; 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) { if (pCleanup->type == CLEANUP_CAR) {
pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id); pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id);
if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED) if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED)

View File

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

View File

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

View File

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

View File

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

View File

@ -24,13 +24,7 @@
#include "Wanted.h" #include "Wanted.h"
#include "World.h" #include "World.h"
#include "VarConsole.h" #include "VarConsole.h"
#include "SaveBuf.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)
#define ROTATED_DOOR_OPEN_SPEED (0.015f) #define ROTATED_DOOR_OPEN_SPEED (0.015f)
#define ROTATED_DOOR_CLOSE_SPEED (0.02f) #define ROTATED_DOOR_CLOSE_SPEED (0.02f)
@ -158,7 +152,7 @@ void CGarages::Init(void)
} }
hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (hGarages >= 0) if (hGarages >= 0)
DMAudio.SetEntityStatus(hGarages, true); DMAudio.SetEntityStatus(hGarages, TRUE);
} }
void CGarages::Shutdown(void) void CGarages::Shutdown(void)
@ -1843,11 +1837,12 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
m_nRadioStation = pVehicle->m_nRadioStation; m_nRadioStation = pVehicle->m_nRadioStation;
m_nVariationA = pVehicle->m_aExtras[0]; m_nVariationA = pVehicle->m_aExtras[0];
m_nVariationB = pVehicle->m_aExtras[1]; m_nVariationB = pVehicle->m_aExtras[1];
m_bBulletproof = pVehicle->bBulletProof; m_nFlags = 0;
m_bFireproof = pVehicle->bFireProof; if (pVehicle->bBulletProof) m_nFlags |= FLAG_BULLETPROOF;
m_bExplosionproof = pVehicle->bExplosionProof; if (pVehicle->bFireProof) m_nFlags |= FLAG_FIREPROOF;
m_bCollisionproof = pVehicle->bCollisionProof; if (pVehicle->bExplosionProof) m_nFlags |= FLAG_EXPLOSIONPROOF;
m_bMeleeproof = pVehicle->bMeleeProof; if (pVehicle->bCollisionProof) m_nFlags |= FLAG_COLLISIONPROOF;
if (pVehicle->bMeleeProof) m_nFlags |= FLAG_MELEEPROOF;
if (pVehicle->IsCar() || pVehicle->IsBike()) if (pVehicle->IsCar() || pVehicle->IsBike())
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour
} }
@ -1896,11 +1891,11 @@ CVehicle* CStoredCar::RestoreCar()
} }
pVehicle->bHasBeenOwnedByPlayer = true; pVehicle->bHasBeenOwnedByPlayer = true;
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED; pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
pVehicle->bBulletProof = m_bBulletproof; if (m_nFlags & FLAG_BULLETPROOF) pVehicle->bBulletProof = true;
pVehicle->bFireProof = m_bFireproof; if (m_nFlags & FLAG_FIREPROOF) pVehicle->bFireProof = true;
pVehicle->bExplosionProof = m_bExplosionproof; if (m_nFlags & FLAG_EXPLOSIONPROOF) pVehicle->bExplosionProof = true;
pVehicle->bCollisionProof = m_bCollisionproof; if (m_nFlags & FLAG_COLLISIONPROOF) pVehicle->bCollisionProof = true;
pVehicle->bMeleeProof = m_bMeleeproof; if (m_nFlags & FLAG_MELEEPROOF) pVehicle->bMeleeProof = true;
return pVehicle; return pVehicle;
} }
@ -2279,8 +2274,53 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aCarsInSafeHouses[j][i]); 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]); WriteSaveBuf(buf, aGarages[i]);
#endif
}
//VALIDATESAVEBUF(*size); //VALIDATESAVEBUF(*size);
} }
@ -2289,11 +2329,7 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
m_nModelIndex = other.m_nModelIndex; m_nModelIndex = other.m_nModelIndex;
m_vecPos = other.m_vecPos; m_vecPos = other.m_vecPos;
m_vecAngle = other.m_vecAngle; m_vecAngle = other.m_vecAngle;
m_bBulletproof = other.m_bBulletproof; m_nFlags = other.m_nFlags;
m_bFireproof = other.m_bFireproof;
m_bExplosionproof = other.m_bExplosionproof;
m_bCollisionproof = other.m_bCollisionproof;
m_bMeleeproof = other.m_bMeleeproof;
m_nPrimaryColor = other.m_nPrimaryColor; m_nPrimaryColor = other.m_nPrimaryColor;
m_nSecondaryColor = other.m_nSecondaryColor; m_nSecondaryColor = other.m_nSecondaryColor;
m_nRadioStation = other.m_nRadioStation; m_nRadioStation = other.m_nRadioStation;
@ -2306,25 +2342,72 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
void CGarages::Load(uint8* buf, uint32 size) void CGarages::Load(uint8* buf, uint32 size)
{ {
//INITSAVEBUF //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))); //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(); CloseHideOutGaragesBeforeSave();
NumGarages = ReadSaveBuf<uint32>(buf); ReadSaveBuf(&NumGarages, buf);
BombsAreFree = ReadSaveBuf<uint32>(buf); int32 tempInt;
RespraysAreFree = ReadSaveBuf<uint32>(buf); ReadSaveBuf(&tempInt, buf);
CarsCollected = ReadSaveBuf<int32>(buf); BombsAreFree = tempInt ? true : false;
BankVansCollected = ReadSaveBuf<int32>(buf); ReadSaveBuf(&tempInt, buf);
PoliceCarsCollected = ReadSaveBuf<int32>(buf); RespraysAreFree = tempInt ? true : false;
ReadSaveBuf(&CarsCollected, buf);
ReadSaveBuf(&BankVansCollected, buf);
ReadSaveBuf(&PoliceCarsCollected, buf);
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++) for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
CarTypesCollected[i] = ReadSaveBuf<uint32>(buf); ReadSaveBuf(&CarTypesCollected[i], buf);
LastTimeHelpMessage = ReadSaveBuf<uint32>(buf); ReadSaveBuf(&LastTimeHelpMessage, buf);
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) { for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) { 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++) { 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_pDoor1 = nil;
aGarages[i].m_pDoor2 = nil; aGarages[i].m_pDoor2 = nil;
aGarages[i].m_pTarget = nil; aGarages[i].m_pTarget = nil;

View File

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

View File

@ -9,14 +9,15 @@
#include "OnscreenTimer.h" #include "OnscreenTimer.h"
#include "Camera.h" #include "Camera.h"
void COnscreenTimer::Init() { void
COnscreenTimer::Init()
{
m_bDisabled = false; m_bDisabled = false;
for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) { for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
m_sCounters[i].m_nCounterOffset = 0; m_sCounters[i].m_nCounterOffset = 0;
for(uint32 j = 0; j < ARRAY_SIZE(m_sCounters[0].m_aCounterText); j++) { for(uint32 j = 0; j < ARRAY_SIZE(m_sCounters[0].m_aCounterText); j++)
m_sCounters[i].m_aCounterText[j] = 0; m_sCounters[i].m_aCounterText[j] = '\0';
}
m_sCounters[i].m_nType = COUNTER_DISPLAY_NUMBER; m_sCounters[i].m_nType = COUNTER_DISPLAY_NUMBER;
m_sCounters[i].m_bCounterProcessed = false; m_sCounters[i].m_bCounterProcessed = false;
@ -24,24 +25,25 @@ void COnscreenTimer::Init() {
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) { for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
m_sClocks[i].m_nClockOffset = 0; m_sClocks[i].m_nClockOffset = 0;
for(uint32 j = 0; j < ARRAY_SIZE(m_sClocks[0].m_aClockText); j++) { for(uint32 j = 0; j < ARRAY_SIZE(m_sClocks[0].m_aClockText); j++)
m_sClocks[i].m_aClockText[j] = 0; m_sClocks[i].m_aClockText[j] = '\0';
}
m_sClocks[i].m_bClockProcessed = false; m_sClocks[i].m_bClockProcessed = false;
m_sClocks[i].m_bClockGoingDown = true; m_sClocks[i].m_bClockGoingDown = true;
} }
} }
void COnscreenTimer::Process() { void
if(!CReplay::IsPlayingBack() && !m_bDisabled) { COnscreenTimer::Process()
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) { {
if(!CReplay::IsPlayingBack() && !m_bDisabled)
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++)
m_sClocks[i].Process(); m_sClocks[i].Process();
}
}
} }
void COnscreenTimer::ProcessForDisplay() { void
COnscreenTimer::ProcessForDisplay()
{
if(CHud::m_Wants_To_Draw_Hud) { if(CHud::m_Wants_To_Draw_Hud) {
m_bProcessed = false; m_bProcessed = false;
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) { 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++) { for(uint32 i = 0; i < NUMONSCREENCOUNTERS; i++) {
if(offset == m_sCounters[i].m_nCounterOffset) { if(offset == m_sCounters[i].m_nCounterOffset) {
m_sCounters[i].m_nCounterOffset = 0; 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_nType = COUNTER_DISPLAY_NUMBER;
m_sCounters[i].m_bCounterProcessed = 0; m_sCounters[i].m_bCounterProcessed = false;
} }
} }
} }
void COnscreenTimer::ClearClock(uint32 offset) { void
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) { COnscreenTimer::ClearClock(uint32 offset)
{
for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++)
if(offset == m_sClocks[i].m_nClockOffset) { if(offset == m_sClocks[i].m_nClockOffset) {
m_sClocks[i].m_nClockOffset = 0; m_sClocks[i].m_nClockOffset = 0;
m_sClocks[i].m_aClockText[0] = 0; m_sClocks[i].m_aClockText[0] = '\0';
m_sClocks[i].m_bClockProcessed = 0; m_sClocks[i].m_bClockProcessed = false;
m_sClocks[i].m_bClockGoingDown = true; 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') if (m_sCounters[pos].m_aCounterText[0] != '\0')
return; return;
m_sCounters[pos].m_nCounterOffset = offset; m_sCounters[pos].m_nCounterOffset = offset;
if(text) { if(text)
strncpy(m_sCounters[pos].m_aCounterText, text, ARRAY_SIZE(m_sCounters[0].m_aCounterText)); strncpy(m_sCounters[pos].m_aCounterText, text, ARRAY_SIZE(m_sCounters[0].m_aCounterText));
} else { else
m_sCounters[pos].m_aCounterText[0] = 0; m_sCounters[pos].m_aCounterText[0] = '\0';
}
m_sCounters[pos].m_nType = type; m_sCounters[pos].m_nType = type;
} }
void COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown) { void
COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown)
// dead code in here {
uint32 i; for(uint32 i = 0; i < NUMONSCREENCLOCKS; i++) {
for(i = 0; i < NUMONSCREENCLOCKS; i++) {
if(m_sClocks[i].m_nClockOffset == 0) { 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; 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() { void
if(m_nClockOffset == 0) { COnscreenTimerEntry::Process()
{
if(m_nClockOffset == 0)
return; return;
}
int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nClockOffset); int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nClockOffset);
int32 oldTime = BSWAP32(*timerPtr); int32 oldTime = BSWAP32(*timerPtr);
@ -147,13 +149,17 @@ void COnscreenTimerEntry::Process() {
*timerPtr = oldTime + int32(CTimer::GetTimeStepInMilliseconds()); *timerPtr = oldTime + int32(CTimer::GetTimeStepInMilliseconds());
} }
void COnscreenTimerEntry::ProcessForDisplayClock() { void
COnscreenTimerEntry::ProcessForDisplayClock()
{
uint32 time = BSWAP32(*CTheScripts::GetPointerToScriptVariable(m_nClockOffset)); uint32 time = BSWAP32(*CTheScripts::GetPointerToScriptVariable(m_nClockOffset));
sprintf(m_aClockBuffer, "%02d:%02d", time / 1000 / 60 % 100, sprintf(m_aClockBuffer, "%02d:%02d", time / 1000 / 60 % 100,
time / 1000 % 60); time / 1000 % 60);
} }
void COnscreenCounterEntry::ProcessForDisplayCounter() { void
COnscreenCounterEntry::ProcessForDisplayCounter()
{
uint32 counter = BSWAP32(*CTheScripts::GetPointerToScriptVariable(m_nCounterOffset)); uint32 counter = BSWAP32(*CTheScripts::GetPointerToScriptVariable(m_nCounterOffset));
sprintf(m_aCounterBuffer, "%d", counter); 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 fBoundMaxY = boundingBox.max.y + 0.3f;
const float fBoundMinY = boundingBox.min.y - 0.3f; const float fBoundMinY = boundingBox.min.y - 0.3f;
const float fBoundMaxX = boundingBox.max.x + 0.3f; const float fBoundMaxX = boundingBox.max.x + 0.3f;
const float fDistanceX = pPosition->x - pEntity->m_matrix.GetPosition().x; const float fDistanceX = pPosition->x - pEntity->GetMatrix().GetPosition().x;
const float fDistanceY = pPosition->y - pEntity->m_matrix.GetPosition().y; const float fDistanceY = pPosition->y - pEntity->GetMatrix().GetPosition().y;
const float fBoundRadius = pEntity->GetBoundRadius(); const float fBoundRadius = pEntity->GetBoundRadius();
CVector vecBoundCentre; CVector vecBoundCentre;
pEntity->GetBoundCentre(vecBoundCentre); pEntity->GetBoundCentre(vecBoundCentre);
@ -215,8 +215,8 @@ CPedPath::AddBlockade(CEntity *pEntity, CPedPathNode(*pathNodes)[40], CVector *p
if (!pathNodes[x][y].bBlockade) { if (!pathNodes[x][y].bBlockade) {
const float pointY = y * 0.7f + fDistanceY; const float pointY = y * 0.7f + fDistanceY;
CVector2D point(pointX, pointY); CVector2D point(pointX, pointY);
if (fBoundMaxX > Abs(DotProduct2D(point, pEntity->m_matrix.GetRight()))) { if (fBoundMaxX > Abs(DotProduct2D(point, pEntity->GetMatrix().GetRight()))) {
float fDotProduct = DotProduct2D(point, pEntity->m_matrix.GetForward()); float fDotProduct = DotProduct2D(point, pEntity->GetMatrix().GetForward());
if (fBoundMaxY > fDotProduct && fBoundMinY < fDotProduct) if (fBoundMaxY > fDotProduct && fBoundMinY < fDotProduct)
pathNodes[x][y].bBlockade = true; pathNodes[x][y].bBlockade = true;
} }

View File

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

View File

@ -33,6 +33,13 @@
#include "Hud.h" #include "Hud.h"
#include "Messages.h" #include "Messages.h"
#include "Streaming.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]; CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages; int16 CPickups::NumMessages;
@ -1008,8 +1015,7 @@ CPickups::DoPickUpEffects(CEntity *entity)
entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame; entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame;
if (!entity->bDoNotRender) { if (!entity->bDoNotRender) {
float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)); float modifiedSin = 0.3f * (Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)) + 1.0f);
float modifiedSin = 0.3f * (s + 1.0f);
#ifdef FIX_BUGS #ifdef FIX_BUGS
int16 colorId = 0; int16 colorId = 0;
@ -1149,7 +1155,20 @@ CPickups::DoPickUpEffects(CEntity *entity)
if (model == MI_MINIGUN || model == MI_MINIGUN2) if (model == MI_MINIGUN || model == MI_MINIGUN2)
scale = 1.2f; 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) { if (entity->GetModelIndex() == MI_MINIGUN2) {
CMatrix matrix1; CMatrix matrix1;
@ -1429,7 +1448,32 @@ CPickups::Load(uint8 *buf, uint32 size)
INITSAVEBUF INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) { 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_eType != PICKUP_NONE) {
if (aPickUps[i].m_pObject != nil) if (aPickUps[i].m_pObject != nil)
@ -1437,15 +1481,15 @@ INITSAVEBUF
if (aPickUps[i].m_pExtraObject != nil) if (aPickUps[i].m_pExtraObject != nil)
aPickUps[i].m_pExtraObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pExtraObject - 1); aPickUps[i].m_pExtraObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pExtraObject - 1);
} }
#endif
} }
CollectedPickUpIndex = ReadSaveBuf<uint16>(buf); ReadSaveBuf(&CollectedPickUpIndex, buf);
ReadSaveBuf<uint16>(buf); SkipSaveBuf(buf, 2);
NumMessages = 0; NumMessages = 0;
for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
aPickUpsCollected[i] = ReadSaveBuf<int32>(buf); ReadSaveBuf(&aPickUpsCollected[i], buf);
VALIDATESAVEBUF(size) VALIDATESAVEBUF(size)
} }
@ -1453,12 +1497,34 @@ VALIDATESAVEBUF(size)
void void
CPickups::Save(uint8 *buf, uint32 *size) CPickups::Save(uint8 *buf, uint32 *size)
{ {
*size = sizeof(aPickUps); *size = PICKUPS_SAVE_SIZE;
*size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected); *size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) { 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]); CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE) { if (buf_pickup->m_eType != PICKUP_NONE) {
if (buf_pickup->m_pObject != nil) if (buf_pickup->m_pObject != nil)
@ -1466,6 +1532,7 @@ INITSAVEBUF
if (buf_pickup->m_pExtraObject != nil) if (buf_pickup->m_pExtraObject != nil)
buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1); buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1);
} }
#endif
} }
WriteSaveBuf(buf, CollectedPickUpIndex); 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_x = 4.0f * vecPos.x;
pp->pos_y = 4.0f * vecPos.y; pp->pos_y = 4.0f * vecPos.y;
pp->pos_z = 4.0f * vecPos.z; pp->pos_z = 4.0f * vecPos.z;
pp->dir_x = 120.0f * clamp(vecDir.x, -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_y = 120.0f * Clamp(vecDir.y, -1.0f, 1.0f);
pp->dir_z = 120.0f * clamp(vecDir.z, -1.0f, 1.0f); pp->dir_z = 120.0f * Clamp(vecDir.z, -1.0f, 1.0f);
pp->size = fSize; pp->size = fSize;
pp->r = color.red; pp->r = color.red;
pp->g = color.green; 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); CAnimBlendAssociation* main = RpAnimBlendClumpGetMainAssociation((RpClump*)ped->m_rwObject, &second, &blend_amount);
if (main){ if (main){
state->animId = main->animId; state->animId = main->animId;
state->time = 255.0f / 4.0f * clamp(main->currentTime, 0.0f, 4.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->speed = 255.0f / 3.0f * Clamp(main->speed, 0.0f, 3.0f);
state->groupId = main->groupId; state->groupId = main->groupId;
}else{ }else{
state->animId = 3; state->animId = 3;
@ -474,9 +474,9 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
} }
if (second) { if (second) {
state->secAnimId = second->animId; state->secAnimId = second->animId;
state->secTime = 255.0f / 4.0f * clamp(second->currentTime, 0.0f, 4.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->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->blendAmount = 255.0f / 2.0f * Clamp(blend_amount, 0.0f, 2.0f);
state->secGroupId = second->groupId; state->secGroupId = second->groupId;
}else{ }else{
state->secAnimId = 0; state->secAnimId = 0;
@ -488,9 +488,9 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
CAnimBlendAssociation* partial = RpAnimBlendClumpGetMainPartialAssociation((RpClump*)ped->m_rwObject); CAnimBlendAssociation* partial = RpAnimBlendClumpGetMainPartialAssociation((RpClump*)ped->m_rwObject);
if (partial) { if (partial) {
state->partAnimId = partial->animId; state->partAnimId = partial->animId;
state->partAnimTime = 255.0f / 4.0f * clamp(partial->currentTime, 0.0f, 4.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->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->partBlendAmount = 255.0f / 2.0f * Clamp(partial->blendAmount, 0.0f, 2.0f);
state->partGroupId = partial->groupId; state->partGroupId = partial->groupId;
}else{ }else{
state->partAnimId = 0; state->partAnimId = 0;
@ -507,10 +507,10 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainAssociation_N((RpClump*)ped->m_rwObject, i); CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainAssociation_N((RpClump*)ped->m_rwObject, i);
if (assoc){ if (assoc){
state->aAnimId[i] = assoc->animId; state->aAnimId[i] = assoc->animId;
state->aCurTime[i] = 255.0f / 4.0f * clamp(assoc->currentTime, 0.0f, 4.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->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->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->aBlendDelta[i] = 127.0f / 32.0f * Clamp(assoc->blendDelta, -16.0f, 16.0f);
state->aFlags[i] = assoc->flags; state->aFlags[i] = assoc->flags;
state->aGroupId[i] = assoc->groupId; state->aGroupId[i] = assoc->groupId;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) { 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); CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainPartialAssociation_N((RpClump*)ped->m_rwObject, i);
if (assoc) { if (assoc) {
state->aAnimId2[i] = assoc->animId; state->aAnimId2[i] = assoc->animId;
state->aCurTime2[i] = 255.0f / 4.0f * clamp(assoc->currentTime, 0.0f, 4.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->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->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->aBlendDelta2[i] = 127.0f / 16.0f * Clamp(assoc->blendDelta, -16.0f, 16.0f);
state->aFlags2[i] = assoc->flags; state->aFlags2[i] = assoc->flags;
state->aGroupId2[i] = assoc->groupId; state->aGroupId2[i] = assoc->groupId;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) { if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
@ -1463,7 +1463,7 @@ void CReplay::RestoreStuffFromMem(void)
ped->SetModelIndex(mi); ped->SetModelIndex(mi);
ped->m_pVehicleAnim = nil; ped->m_pVehicleAnim = nil;
ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped); 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); CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false);
for (int j = 0; j < TOTAL_WEAPON_SLOTS; j++) { for (int j = 0; j < TOTAL_WEAPON_SLOTS; j++) {
int mi1 = CWeaponInfo::GetWeaponInfo(ped->m_weapons[j].m_eWeaponType)->m_nModelId; 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); car->SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT, true);
} }
vehicle->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, vehicle); vehicle->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, vehicle);
DMAudio.SetEntityStatus(vehicle->m_audioEntityId, true); DMAudio.SetEntityStatus(vehicle->m_audioEntityId, TRUE);
CCarCtrl::UpdateCarCount(vehicle, false); CCarCtrl::UpdateCarCount(vehicle, false);
if ((mi == MI_AIRTRAIN || mi == MI_DEADDODO) && vehicle->m_rwObject){ if ((mi == MI_AIRTRAIN || mi == MI_DEADDODO) && vehicle->m_rwObject){
CVehicleModelInfo* info = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi); CVehicleModelInfo* info = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi);

View File

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

View File

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

View File

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

View File

@ -749,7 +749,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed; CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed;
script_assert(pPlayerPed); 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; return 0;
} }
case COMMAND_ADD_ARMOUR_TO_CHAR: case COMMAND_ADD_ARMOUR_TO_CHAR:
@ -757,7 +757,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed); 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; return 0;
} }
case COMMAND_OPEN_GARAGE: case COMMAND_OPEN_GARAGE:
@ -1398,7 +1398,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND); 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; return 0;
} }
case COMMAND_CLEAR_AREA: case COMMAND_CLEAR_AREA:

View File

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

View File

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

View File

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

View File

@ -1183,7 +1183,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl
float ReqSpeed = DeltaBeta * SpeedMultiplier; float ReqSpeed = DeltaBeta * SpeedMultiplier;
// this is also added // this is also added
ReqSpeed = clamp(ReqSpeed, -SpeedLimit, SpeedLimit); ReqSpeed = Clamp(ReqSpeed, -SpeedLimit, SpeedLimit);
// Add or subtract absolute depending on sign, genius! // Add or subtract absolute depending on sign, genius!
if(ReqSpeed - BetaSpeed > 0.0f) 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; 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)){ 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; 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) if(CarAlpha < 0.0f)
AlphaOffset += CarAlpha; AlphaOffset += CarAlpha;
} }
@ -1828,7 +1828,7 @@ CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientati
if(DeltaBeta > PI) DeltaBeta -= TWOPI; if(DeltaBeta > PI) DeltaBeta -= TWOPI;
else if(DeltaBeta < -PI) DeltaBeta += TWOPI; else if(DeltaBeta < -PI) DeltaBeta += TWOPI;
float dist = (TargetCoors - Source).Magnitude(); 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)); 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; if(BetaOffset > PI) BetaOffset -= TWOPI;
else 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; Beta = NewBeta + BetaOffset;
} }
@ -3271,7 +3271,7 @@ CCam::Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, f
// useless call // useless call
//CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &Water); //CWaterLevel::GetWaterLevelNoWaves(TargetCoors.x, TargetCoors.y, TargetCoors.z, &Water);
Water = (WaterLevel + WATER_Z_ADDITION_MIN - WaterLevelBuffered - WATER_Z_ADDITION)/(BoatDimensions.z/2.0f + MaxHeightUp); 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){ 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]); 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; float b = 1.0f - a;
*out = b*b*b * spline[marker-3] + *out = b*b*b * spline[marker-3] +
3.0f*a*b*b * spline[marker-1] + 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]); 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; float b = 1.0f - a;
out->x = out->x =
b*b*b * spline[marker-9] + 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 // 0.98f: CAR_FOV_FADE_MULT
FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV; 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) // 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; AlphaSpeed = 0.0;
Distance = 1000.0; Distance = 1000.0;
Front.x = -(cos(Beta) * cos(Alpha)); Front.x = -(Cos(Beta) * Cos(Alpha));
Front.y = -(sin(Beta) * cos(Alpha)); Front.y = -(Sin(Beta) * Cos(Alpha));
Front.z = sin(Alpha); Front.z = Sin(Alpha);
m_aTargetHistoryPosOne = TargetCoors - nextDistance * Front; 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 <= maxAlphaAllowed) {
if (targetAlpha < -CARCAM_SET[camSetArrPos][14]) if (targetAlpha < -CARCAM_SET[camSetArrPos][14])
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; lastBeta = Beta;
Front.x = -(cos(Beta) * cos(Alpha)); Front.x = -(Cos(Beta) * Cos(Alpha));
Front.y = -(sin(Beta) * cos(Alpha)); Front.y = -(Sin(Beta) * Cos(Alpha));
Front.z = sin(Alpha); Front.z = Sin(Alpha);
GetVectorsReadyForRW(); GetVectorsReadyForRW();
TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyBehind = false;
TheCamera.m_bCamDirectlyInFront = false; TheCamera.m_bCamDirectlyInFront = false;
@ -5240,9 +5240,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
m_cvecTargetCoorsForFudgeInter = TargetCoors; m_cvecTargetCoorsForFudgeInter = TargetCoors;
m_aTargetHistoryPosThree = m_aTargetHistoryPosOne; m_aTargetHistoryPosThree = m_aTargetHistoryPosOne;
float nextAlpha = alphaWithSpeedAccounted + zoomModeAlphaOffset; float nextAlpha = alphaWithSpeedAccounted + zoomModeAlphaOffset;
float nextFrontX = -(cos(Beta) * cos(nextAlpha)); float nextFrontX = -(Cos(Beta) * Cos(nextAlpha));
float nextFrontY = -(sin(Beta) * cos(nextAlpha)); float nextFrontY = -(Sin(Beta) * Cos(nextAlpha));
float nextFrontZ = sin(nextAlpha); float nextFrontZ = Sin(nextAlpha);
m_aTargetHistoryPosOne.x = TargetCoors.x - nextFrontX * nextDistance; m_aTargetHistoryPosOne.x = TargetCoors.x - nextFrontX * nextDistance;
m_aTargetHistoryPosOne.y = TargetCoors.y - nextFrontY * 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 alphaToFace = Atan2(hi.z, hi.Magnitude2D()) + DEGTORAD(15.0f);
float neededAlphaTurn = alphaToFace - carGunUD; float neededAlphaTurn = alphaToFace - carGunUD;
float alphaTurnPerFrame = CTimer::GetTimeStep() * 0.02f; float alphaTurnPerFrame = CTimer::GetTimeStepInSeconds();
if (neededAlphaTurn > alphaTurnPerFrame) { if (neededAlphaTurn > alphaTurnPerFrame) {
neededTurn = alphaTurnPerFrame; neededTurn = alphaTurnPerFrame;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -779,7 +779,7 @@ TriggerAudio_RadioStation(CMenuMultiChoicePicturedTriggered *widget)
if ( CMenuManager::m_PrefsRadioStation != widget->GetMenuSelection() ) if ( CMenuManager::m_PrefsRadioStation != widget->GetMenuSelection() )
{ {
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); DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
} }
} }

View File

@ -1375,7 +1375,7 @@ CMenuManager::DrawFrontEndNormal(void)
if ((m_nStartPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) <= 1600) if ((m_nStartPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) <= 1600)
alpha = float(m_nStartPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) / 400.0f; 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 ) switch ( m_nSlidingDir )
{ {
@ -1392,7 +1392,7 @@ CMenuManager::DrawFrontEndNormal(void)
float slide = float(m_nEndPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) / 800.0f; float slide = float(m_nEndPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) / 800.0f;
float alpha = float((int32)(m_nEndPauseTimer - CTimer::GetTimeInMillisecondsPauseMode()) + -266) / 533.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 ) switch ( m_nSlidingDir )
{ {
@ -2858,7 +2858,7 @@ CMenuManager::ProcessDPadCrossJustDown(void)
{ {
if ( !gMusicPlaying ) if ( !gMusicPlaying )
{ {
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
gMusicPlaying = true; gMusicPlaying = true;
} }
} }

View File

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

View File

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

View File

@ -26,6 +26,7 @@
#include "ModelInfo.h" #include "ModelInfo.h"
#include "Pad.h" #include "Pad.h"
#include "ControllerConfig.h" #include "ControllerConfig.h"
#include "DMAudio.h"
// Menu screens array is at the bottom of the file. // Menu screens array is at the bottom of the file.
@ -181,38 +182,6 @@ void IslandLoadingAfterChange(int8 before, int8 after) {
} }
#endif #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 #ifndef MULTISAMPLING
void GraphicsGoBack() { void GraphicsGoBack() {
} }
@ -226,6 +195,8 @@ void MultiSamplingButtonPress(int8 action) {
if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel; FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.Service();
FrontEndMenuManager.SetHelperText(0); FrontEndMenuManager.SetHelperText(0);
FrontEndMenuManager.SaveSettings(); FrontEndMenuManager.SaveSettings();
} }
@ -287,6 +258,8 @@ const char* screenModes[] = { "FED_FLS", "FED_WND" };
void ScreenModeAfterChange(int8 before, int8 after) void ScreenModeAfterChange(int8 before, int8 after)
{ {
_psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.Service();
FrontEndMenuManager.SetHelperText(0); 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_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_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, 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, MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
}, },

View File

@ -2,12 +2,13 @@
class CPlaceable class CPlaceable
{ {
protected:
CMatrix m_matrix;
public: public:
// disable allocation // disable allocation
static void *operator new(size_t); static void *operator new(size_t);
CMatrix m_matrix;
CPlaceable(void); CPlaceable(void);
const CVector &GetPosition(void) { return m_matrix.GetPosition(); } const CVector &GetPosition(void) { return m_matrix.GetPosition(); }
void SetPosition(float x, float y, float z) { void SetPosition(float x, float y, float z) {
@ -20,6 +21,7 @@ public:
CVector &GetForward(void) { return m_matrix.GetForward(); } CVector &GetForward(void) { return m_matrix.GetForward(); }
CVector &GetUp(void) { return m_matrix.GetUp(); } CVector &GetUp(void) { return m_matrix.GetUp(); }
CMatrix &GetMatrix(void) { return m_matrix; } CMatrix &GetMatrix(void) { return m_matrix; }
void SetMatrix(CMatrix &newMatrix) { m_matrix = newMatrix; }
void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); } void SetTransform(RwMatrix *m) { m_matrix = CMatrix(m, false); }
void SetHeading(float angle); void SetHeading(float angle);
void SetOrientation(float x, float y, float z){ 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); 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 = 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. // Because vehicle enter/exit use same key binding.
bool enterOrExitVeh; bool enterOrExitVeh;

View File

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

View File

@ -19,6 +19,7 @@
#include "Streaming.h" #include "Streaming.h"
#include "SpecialFX.h" #include "SpecialFX.h"
#include "Font.h" #include "Font.h"
#include "SaveBuf.h"
float CRadar::m_radarRange; float CRadar::m_radarRange;
sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS]; sRadarTrace CRadar::ms_RadarTrace[NUMRADARBLIPS];
@ -184,6 +185,75 @@ void GetTextureCorners(int32 x, int32 y, CVector2D *out)
out[3].y = RADAR_TILE_SIZE * (y); 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) bool IsPointInsideRadar(const CVector2D &point)
{ {
@ -264,74 +334,6 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &
return edge; 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) int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
{ {
CVector2D corners[4] = { CVector2D corners[4] = {
@ -410,6 +412,50 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
return n; 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) 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) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition(); CVector pos = entity->GetPosition();
pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f; 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; 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) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition(); CVector pos = entity->GetPosition();
pos.z += 3.0f; 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; 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) { if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition(); CVector pos = entity->GetPosition();
pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f; 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; break;
} }
@ -466,7 +512,7 @@ void CRadar::Draw3dMarkers()
case BLIP_CONTACT_POINT: case BLIP_CONTACT_POINT:
if (!CTheScripts::IsPlayerOnAMission()) { if (!CTheScripts::IsPlayerOnAMission()) {
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) 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; break;
} }
@ -928,21 +974,21 @@ INITSAVEBUF
CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE); CheckSaveHeader(buf, 'R', 'D', 'R', '\0', size - SAVE_HEADER_SIZE);
for (int i = 0; i < NUMRADARBLIPS; i++) { for (int i = 0; i < NUMRADARBLIPS; i++) {
ms_RadarTrace[i].m_nColor = ReadSaveBuf<uint32>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_nColor, buf);
ms_RadarTrace[i].m_Radius = ReadSaveBuf<float>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_Radius, buf);
ms_RadarTrace[i].m_eBlipType = ReadSaveBuf<uint32>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_eBlipType, buf);
ms_RadarTrace[i].m_nEntityHandle = ReadSaveBuf<int32>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_nEntityHandle, buf);
ms_RadarTrace[i].m_vec2DPos.x = ReadSaveBuf<float>(buf); // CVector2D ReadSaveBuf(&ms_RadarTrace[i].m_vec2DPos.x, buf);
ms_RadarTrace[i].m_vec2DPos.y = ReadSaveBuf<float>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_vec2DPos.y, buf);
ms_RadarTrace[i].m_vecPos = ReadSaveBuf<CVector>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_vecPos, buf);
ms_RadarTrace[i].m_BlipIndex = ReadSaveBuf<uint16>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_BlipIndex, buf);
ms_RadarTrace[i].m_bDim = ReadSaveBuf<bool>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_bDim, buf);
ms_RadarTrace[i].m_bInUse = ReadSaveBuf<bool>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_bInUse, buf);
ms_RadarTrace[i].m_bShortRange = ReadSaveBuf<bool>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_bShortRange, buf);
ms_RadarTrace[i].m_unused = ReadSaveBuf<bool>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_unused, buf);
ms_RadarTrace[i].m_wScale = ReadSaveBuf<int16>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_wScale, buf);
ms_RadarTrace[i].m_eBlipDisplay = ReadSaveBuf<uint16>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_eBlipDisplay, buf);
ms_RadarTrace[i].m_eRadarSprite = ReadSaveBuf<uint16>(buf); ReadSaveBuf(&ms_RadarTrace[i].m_eRadarSprite, buf);
} }
VALIDATESAVEBUF(size); VALIDATESAVEBUF(size);
@ -1337,7 +1383,7 @@ CRadar::InitFrontEndMap()
void void
CRadar::DrawYouAreHereSprite(float x, float y) CRadar::DrawYouAreHereSprite(float x, float y)
{ {
static PauseModeTime lastChange = 0; static uint32 lastChange = 0;
static bool show = true; static bool show = true;
if (show) { if (show) {
@ -1537,7 +1583,7 @@ void
CRadar::DrawLegend(int32 x, int32 y, int32 sprite) CRadar::DrawLegend(int32 x, int32 y, int32 sprite)
{ {
if (sprite < 0) { if (sprite < 0) {
static PauseModeTime lastChange = 0; static uint32 lastChange = 0;
static int8 blipMode = 0; static int8 blipMode = 0;
CRGBA color; CRGBA color;

View File

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

View File

@ -1,5 +1,6 @@
#include "common.h" #include "common.h"
#include "main.h"
#include "Timer.h" #include "Timer.h"
#include "ModelIndices.h" #include "ModelIndices.h"
#include "Streaming.h" #include "Streaming.h"
@ -91,9 +92,11 @@ void
CRopes::Render(void) CRopes::Render(void)
{ {
int i; int i;
PUSH_RENDERGROUP("CRopes::Render");
for(i = 0; i < ARRAY_SIZE(aRopes); i++) for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive) if(aRopes[i].m_bActive)
aRopes[i].Render(); aRopes[i].Render();
POP_RENDERGROUP();
} }
bool bool
@ -147,7 +150,7 @@ CRopes::FindCoorsAlongRope(uintptr id, float t, CVector *coors)
float f; float f;
for(i = 0; i < ARRAY_SIZE(aRopes); i++) for(i = 0; i < ARRAY_SIZE(aRopes); i++)
if(aRopes[i].m_bActive && aRopes[i].m_id == id){ 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; j = t;
f = t - j; f = t - j;
*coors = (1.0f-f)*aRopes[i].m_pos[j] + f*aRopes[i].m_pos[j+1]; *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"); FASTEST_TIME(20, "STFT_21");
if (FastestTimes[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); STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1);
#endif
if (TopShootingRangeScore > 0.0f) if (TopShootingRangeScore > 0.0f)
STAT_LINE_1(int, "TOP_SHO", TopShootingRangeScore, 0); 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++){ for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){
if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq && if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq &&
((i == 0 && zone.carThreshold[0] != 0) || ((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]))) { (i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) {
#endif
maxReq = CCarCtrl::NumRequestsOfCarRating[i]; maxReq = CCarCtrl::NumRequestsOfCarRating[i];
mostRequestedRating = i; mostRequestedRating = i;
} }
@ -1875,8 +1881,7 @@ CStreaming::RemoveCurrentZonesModels(void)
if (ms_currentPedGrp != -1) if (ms_currentPedGrp != -1)
for (i = 0; i < NUMMODELSPERPEDGROUP; i++) { for (i = 0; i < NUMMODELSPERPEDGROUP; i++) {
ms_bIsPedFromPedGroupLoaded[i] = false; ms_bIsPedFromPedGroupLoaded[i] = false;
if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1 && if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1) {
CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) {
SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]); SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]); SetModelTxdIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);
} }

View File

@ -8,7 +8,7 @@
#include "SpecialFX.h" #include "SpecialFX.h"
uint32 CTimer::m_snTimeInMilliseconds; uint32 CTimer::m_snTimeInMilliseconds;
PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1; uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
uint32 CTimer::m_snTimeInMillisecondsNonClipped; uint32 CTimer::m_snTimeInMillisecondsNonClipped;
uint32 CTimer::m_snPreviousTimeInMilliseconds; uint32 CTimer::m_snPreviousTimeInMilliseconds;
@ -18,6 +18,10 @@ float CTimer::ms_fTimeStep;
float CTimer::ms_fTimeStepNonClipped; float CTimer::ms_fTimeStepNonClipped;
bool CTimer::m_UserPause; bool CTimer::m_UserPause;
bool CTimer::m_CodePause; bool CTimer::m_CodePause;
#ifdef FIX_BUGS
uint32 CTimer::m_LogicalFrameCounter;
uint32 CTimer::m_LogicalFramesPassed;
#endif
uint32 _nCyclesPerMS = 1; uint32 _nCyclesPerMS = 1;
@ -35,10 +39,6 @@ RsTimerType suspendPcTimer;
uint32 suspendDepth; uint32 suspendDepth;
#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double frameTime;
#endif
void CTimer::Initialise(void) void CTimer::Initialise(void)
{ {
debug("Initialising CTimer...\n"); debug("Initialising CTimer...\n");
@ -51,6 +51,10 @@ void CTimer::Initialise(void)
m_snTimeInMillisecondsNonClipped = 0; m_snTimeInMillisecondsNonClipped = 0;
m_snPreviousTimeInMilliseconds = 0; m_snPreviousTimeInMilliseconds = 0;
m_snTimeInMilliseconds = 1; m_snTimeInMilliseconds = 1;
#ifdef FIX_BUGS
m_LogicalFrameCounter = 0;
m_LogicalFramesPassed = 0;
#endif
#ifdef _WIN32 #ifdef _WIN32
LARGE_INTEGER perfFreq; 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) void CTimer::Update(void)
{ {
m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds; m_snPreviousTimeInMilliseconds = m_snTimeInMilliseconds;
@ -98,11 +190,7 @@ void CTimer::Update(void)
float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale; float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
// We need that real frame time to fix transparent menu bug. double frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double
#endif
frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime; m_snTimeInMillisecondsPauseMode = m_snTimeInMillisecondsPauseMode + frameTime;
@ -122,11 +210,7 @@ void CTimer::Update(void)
RsTimerType updInMs = timer - oldPcTimer; RsTimerType updInMs = timer - oldPcTimer;
// We need that real frame time to fix transparent menu bug. double frameTime = (double)updInMs * ms_fTimeScale;
#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double
#endif
frameTime = (double)updInMs * ms_fTimeScale;
oldPcTimer = timer; oldPcTimer = timer;
@ -163,6 +247,7 @@ void CTimer::Update(void)
m_FrameCounter++; m_FrameCounter++;
} }
#endif
void CTimer::Suspend(void) void CTimer::Suspend(void)
{ {

View File

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

View File

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

View File

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

View File

@ -103,8 +103,8 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity); static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup); static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos); static int16 FindAudioZone(CVector *pos);
static CZone *GetPointerForZoneIndex(ssize_t i) { return i == -1 ? nil : &NavigationZoneArray[i]; } static CZone *GetPointerForNavigationZoneIndex(ssize_t i) { return i == -1 ? nil : &NavigationZoneArray[i]; }
static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; } static ssize_t GetIndexForNavigationZonePointer(CZone *zone) { return zone == nil ? -1 : zone - NavigationZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone); static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void); static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length); 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 "maths.h"
#include "Vector.h" #include "Vector.h"
#ifdef GTA_PS2
#include "VuVector.h"
#define CVUVECTOR CVuVector
#else
#define CVUVECTOR CVector
#endif
#include "Vector2D.h" #include "Vector2D.h"
#include "Matrix.h" #include "Matrix.h"
#include "Rect.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); 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; } inline float sq(float x) { return x*x; }
#define SQR(x) ((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) x##y
#define CONCAT(x,y) CONCAT_(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 #pragma once
// disables (most) stuff that wasn't in original gta-vc.exe - check section at the bottom of this file // disables (most) stuff that wasn't in original gta-vc.exe
//#define VANILLA_DEFINES #ifdef __MWERKS__
#define VANILLA_DEFINES
#endif
enum Config { enum Config {
NUMPLAYERS = 1, NUMPLAYERS = 1,
@ -131,7 +133,6 @@ enum Config {
NUM_PED_COMMENTS_SLOTS = 20, NUM_PED_COMMENTS_SLOTS = 20,
NUM_SOUNDS_SAMPLES_BANKS = 2, NUM_SOUNDS_SAMPLES_BANKS = 2,
NUM_SOUNDS_SAMPLES_SLOTS = 27,
NUM_AUDIOENTITIES = 250, NUM_AUDIOENTITIES = 250,
NUM_AUDIO_REFLECTIONS = 8, NUM_AUDIO_REFLECTIONS = 8,
@ -155,8 +156,33 @@ enum Config {
//#define GTA_PS2 //#define GTA_PS2
//#define GTA_XBOX //#define GTA_XBOX
// This enables things from the PS2 version on PC // Version defines
#define GTA_PS2_STUFF #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. // This is enabled for all released games.
// any debug stuff that isn't left in any game is not in FINAL // any debug stuff that isn't left in any game is not in FINAL
@ -175,28 +201,35 @@ enum Config {
#define FINAL #define FINAL
#endif #endif
// Version defines // these are placed here to work with VANILLA_DEFINES for compatibility
#define GTAVC_PS2 400 #define NO_CDCHECK // skip audio CD check
#define GTAVC_PC_10 410 #define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define GTAVC_PC_11 411
#define GTAVC_PC_JAP 412
// TODO? maybe something for xbox or android?
#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 FINAL
//#define GTA3_STEAM_PATCH #define MASTER
//#define GTAVC_JP_PATCH //#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 // quality of life fixes that should also be in FINAL
#define NASTY_GAME // nasty game for all languages #define NASTY_GAME // nasty game for all languages
#define NO_CDCHECK
// those infamous texts // those infamous texts
#define DRAW_GAME_VERSION_TEXT #define DRAW_GAME_VERSION_TEXT
#ifdef 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. // 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 #endif
// Memory allocation and compression // Memory allocation and compression
@ -204,21 +237,10 @@ enum Config {
//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices //#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed //#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
#if defined GTA_PS2 #if defined GTA_PC && defined GTA_PS2_STUFF
# define GTA_PS2_STUFF # define USE_PS2_RAND
# define RANDOMSPLASH # define RANDOMSPLASH // use random splash as on PS2
//# define USE_CUSTOM_ALLOCATOR # define PS2_MATFX
# 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
#endif #endif
#ifdef VU_COLLISION #ifdef VU_COLLISION
@ -232,7 +254,6 @@ enum Config {
// not in master builds // not in master builds
#define VALIDATE_SAVE_SIZE #define VALIDATE_SAVE_SIZE
#define NO_MOVIES // disable intro videos
#define DEBUGMENU #define DEBUGMENU
#endif #endif
@ -246,10 +267,12 @@ enum Config {
#endif #endif
#define FIX_BUGS // fixes bugs that we've came across during reversing. You can undefine this only on release builds. #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 MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible #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 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) #if defined(__LP64__) || defined(_WIN64)
#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build #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 #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 #undef ASCII_STRCMP
#endif #endif
@ -294,11 +317,11 @@ enum Config {
#endif #endif
// Water & Particle // Water & Particle
// #define PC_WATER #undef PC_WATER
#define WATER_CHEATS #define WATER_CHEATS
//#define USE_CUTSCENE_SHADOW_FOR_PED //#define USE_CUTSCENE_SHADOW_FOR_PED // requires COMPATIBLE_SAVES
#define DISABLE_CUTSCENE_SHADOWS //#define DISABLE_CUTSCENE_SHADOWS
// Pad // Pad
#if !defined(RW_GL3) && defined(_WIN32) #if !defined(RW_GL3) && defined(_WIN32)
@ -399,9 +422,12 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
// Audio // Audio
#define RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS #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 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_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files #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 #ifdef AUDIO_OPUS
#define AUDIO_OAL_USE_OPUS // enable support of opus files #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 #ifdef SQUEEZE_PERFORMANCE
#undef PS2_ALPHA_TEST #undef PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING #undef NO_ISLAND_LOADING
#undef PS2_AUDIO_CHANNELS
#endif #endif
#ifdef __WIIU__ #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 #define INI_BUFFER_SIZE (8*1024) // 8k should be enough for the ini file
#endif #endif
// ------- // if these defines are enabled saves are not vanilla compatible without COMPATIBLE_SAVES
#ifndef COMPATIBLE_SAVES
#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
#undef USE_CUTSCENE_SHADOW_FOR_PED #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
#endif // VANILLA_DEFINES

View File

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

View File

@ -1,5 +1,16 @@
#pragma once #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 struct GlobalScene
{ {
RpWorld *world; RpWorld *world;
@ -55,3 +66,11 @@ void SaveINIControllerSettings();
extern bool gbNewRenderer; extern bool gbNewRenderer;
bool FredIsInFirstPersonCam(void); bool FredIsInFirstPersonCam(void);
#endif #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 #ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h" #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 void
CustomFrontendOptionsPopulate(void) CustomFrontendOptionsPopulate(void)
{ {
// Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h // 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 // These work only if we have neo folder, so they're dynamically added
#ifdef EXTENDED_PIPELINES #ifdef EXTENDED_PIPELINES
const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" }; const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" };
const char *off_on[] = { "FEM_OFF", "FEM_ON" }; 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) { if (fd) {
#ifdef GRAPHICS_MENU_OPTIONS #ifdef GRAPHICS_MENU_OPTIONS
FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false); FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
@ -121,22 +156,72 @@ CustomFrontendOptionsPopulate(void)
#endif #endif
CFileMgr::CloseFile(fd); 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
} }
#endif #endif
#ifdef LOAD_INI_SETTINGS #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) bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
{ {
std::string strval = cfg.get(cat, key, "\xBA"); mINI::INIMap<std::string> section = cfg.get(cat);
const char *value = strval.c_str(); if (section.has(key)) {
char *endPtr; char *endPtr;
if (value && value[0] != '\xBA') { *out = strtoul(section.get(key).c_str(), &endPtr, 0);
*out = strtoul(value, &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 true;
} }
return false; 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) bool ReadIniIfExists(const char *cat, const char *key, bool *out)
{ {
std::string strval = cfg.get(cat, key, "\xBA"); mINI::INIMap<std::string> section = cfg.get(cat);
const char *value = strval.c_str(); if (section.has(key)) {
char *endPtr; char *endPtr;
if (value && value[0] != '\xBA') { *out = strtoul(section.get(key).c_str(), &endPtr, 0);
*out = strtoul(value, &endPtr, 0);
return true; return true;
} }
return false; 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) bool ReadIniIfExists(const char *cat, const char *key, int32 *out)
{ {
std::string strval = cfg.get(cat, key, "\xBA"); mINI::INIMap<std::string> section = cfg.get(cat);
const char *value = strval.c_str(); if (section.has(key)) {
char *endPtr; char *endPtr;
if (value && value[0] != '\xBA') { *out = strtol(section.get(key).c_str(), &endPtr, 0);
*out = strtol(value, &endPtr, 0);
return true; return true;
} }
return false; 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) bool ReadIniIfExists(const char *cat, const char *key, int8 *out)
{ {
std::string strval = cfg.get(cat, key, "\xBA"); mINI::INIMap<std::string> section = cfg.get(cat);
const char *value = strval.c_str(); if (section.has(key)) {
char *endPtr; char *endPtr;
if (value && value[0] != '\xBA') { *out = strtol(section.get(key).c_str(), &endPtr, 0);
*out = strtol(value, &endPtr, 0);
return true; return true;
} }
return false; 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) bool ReadIniIfExists(const char *cat, const char *key, float *out)
{ {
std::string strval = cfg.get(cat, key, "\xBA"); mINI::INIMap<std::string> section = cfg.get(cat);
const char *value = strval.c_str(); if (section.has(key)) {
if (value && value[0] != '\xBA') { char *endPtr;
*out = atof(value); *out = strtof(section.get(key).c_str(), &endPtr);
return true; return true;
} }
return false; 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) bool ReadIniIfExists(const char *cat, const char *key, char *out, int size)
{ {
std::string strval = cfg.get(cat, key, "\xBA"); mINI::INIMap<std::string> section = cfg.get(cat);
const char *value = strval.c_str(); if (section.has(key)) {
if (value && value[0] != '\xBA') { strncpy(out, section.get(key).c_str(), size - 1);
strncpy(out, value, size); out[size - 1] = '\0';
return true; return true;
} }
return false; 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) void StoreIni(const char *cat, const char *key, uint32 val)
{ {
char temp[10]; char temp[11];
sprintf(temp, "%u", val); sprintf(temp, "%u", val);
cfg.set(cat, key, temp); cfg[cat][key] = temp;
} }
void StoreIni(const char *cat, const char *key, uint8 val) void StoreIni(const char *cat, const char *key, uint8 val)
{ {
char temp[10]; char temp[11];
sprintf(temp, "%u", (uint32)val); sprintf(temp, "%u", val);
cfg.set(cat, key, temp); cfg[cat][key] = temp;
} }
void StoreIni(const char *cat, const char *key, int32 val) void StoreIni(const char *cat, const char *key, int32 val)
{ {
char temp[10]; char temp[11];
sprintf(temp, "%d", val); sprintf(temp, "%d", val);
cfg.set(cat, key, temp); cfg[cat][key] = temp;
} }
void StoreIni(const char *cat, const char *key, int8 val) void StoreIni(const char *cat, const char *key, int8 val)
{ {
char temp[10]; char temp[11];
sprintf(temp, "%d", (int32)val); sprintf(temp, "%d", val);
cfg.set(cat, key, temp); cfg[cat][key] = temp;
} }
void StoreIni(const char *cat, const char *key, float val) void StoreIni(const char *cat, const char *key, float val)
{ {
char temp[10]; char temp[50];
sprintf(temp, "%f", val); 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) 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", 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 #endif
// force to default GTA behaviour (never overwrite bindings on joy change/initialization) if user init'ed/set bindings before we introduced that // 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)) { 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++) { for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) {
@ -401,20 +483,13 @@ void SaveINIControllerSettings()
#endif #endif
#endif #endif
StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited); StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited);
#ifdef WIIU_CHANNEL
cfg.write_file("/vol/external01/wiiu/apps/reVC/reVC.ini"); ini.write(cfg);
#else
cfg.write_file("reVC.ini");
#endif
} }
bool LoadINISettings() bool LoadINISettings()
{ {
#ifdef WIIU_CHANNEL if (!ini.read(cfg))
if (!cfg.load_file("/vol/external01/wiiu/apps/reVC/reVC.ini"))
#else
if (!cfg.load_file("reVC.ini"))
#endif
return false; return false;
#ifdef IMPROVED_VIDEOMODE #ifdef IMPROVED_VIDEOMODE
@ -479,12 +554,14 @@ bool LoadINISettings()
ReadIniIfExists("Draw", "FixSprites", &CDraw::ms_bFixSprites); ReadIniIfExists("Draw", "FixSprites", &CDraw::ms_bFixSprites);
#endif #endif
#ifdef DRAW_GAME_VERSION_TEXT #ifdef DRAW_GAME_VERSION_TEXT
extern bool gDrawVersionText; ReadIniIfExists("General", "DrawVersionText", &gbDrawVersionText);
ReadIniIfExists("General", "DrawVersionText", &gDrawVersionText); #endif
#ifdef NO_MOVIES
ReadIniIfExists("General", "NoMovies", &gbNoMovies);
#endif #endif
#ifdef CUSTOM_FRONTEND_OPTIONS #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 i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) { for (int j = 0; j < NUM_MENUROWS; j++) {
CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
@ -497,7 +574,7 @@ bool LoadINISettings()
// Migrate from old .ini to new .ini // Migrate from old .ini to new .ini
if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value)) 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 else
ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value); 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); StoreIni("Draw", "FixSprites", CDraw::ms_bFixSprites);
#endif #endif
#ifdef DRAW_GAME_VERSION_TEXT #ifdef DRAW_GAME_VERSION_TEXT
extern bool gDrawVersionText; StoreIni("General", "DrawVersionText", gbDrawVersionText);
StoreIni("General", "DrawVersionText", gDrawVersionText); #endif
#ifdef NO_MOVIES
StoreIni("General", "NoMovies", gbNoMovies);
#endif #endif
#ifdef CUSTOM_FRONTEND_OPTIONS #ifdef CUSTOM_FRONTEND_OPTIONS
for (int i = 0; i < MENUPAGES; i++) { for (int i = 0; i < MENUPAGES; i++) {
@ -594,11 +673,7 @@ void SaveINISettings()
} }
#endif #endif
#ifdef WIIU_CHANNEL ini.write(cfg);
cfg.write_file("/vol/external01/wiiu/apps/reVC/reVC.ini");
#else
cfg.write_file("reVC.ini");
#endif
} }
#endif #endif
@ -983,6 +1058,11 @@ extern bool gbRenderWorld2;
#ifndef MASTER #ifndef MASTER
DebugMenuAddVarBool8("Render", "Occlusion debug", &bDispayOccDebugStuff, nil); DebugMenuAddVarBool8("Render", "Occlusion debug", &bDispayOccDebugStuff, nil);
#endif #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 #ifdef EXTENDED_PIPELINES
static const char *vehpipenames[] = { "MatFX", "Neo" }; static const char *vehpipenames[] = { "MatFX", "Neo" };
e = DebugMenuAddVar("Render", "Vehicle Pipeline", &CustomPipes::VehiclePipeSwitch, nil, e = DebugMenuAddVar("Render", "Vehicle Pipeline", &CustomPipes::VehiclePipeSwitch, nil,
@ -1011,14 +1091,14 @@ extern bool gbRenderWorld2;
#ifdef DRAW_GAME_VERSION_TEXT #ifdef DRAW_GAME_VERSION_TEXT
extern bool gDrawVersionText; DebugMenuAddVarBool8("Debug", "Version Text", &gbDrawVersionText, nil);
DebugMenuAddVarBool8("Debug", "Version Text", &gDrawVersionText, nil);
#endif #endif
DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil); DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil);
#ifdef TIMEBARS #ifdef TIMEBARS
DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil); DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil);
#endif #endif
#ifndef FINAL #ifndef FINAL
DebugMenuAddVarBool8("Debug", "Use debug render groups", &bDebugRenderGroups, nil);
DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil); DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil);
#ifdef USE_CUSTOM_ALLOCATOR #ifdef USE_CUSTOM_ALLOCATOR
DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap); 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)"); 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); MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
if (nCode == IDABORT) if (nCode == IDABORT)
@ -1151,7 +1231,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
OSFatal(buf); OSFatal(buf);
#else #else
// TODO // 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); assert(false);
#endif #endif
} }
@ -1207,7 +1287,7 @@ void re3_usererror(const char *format, ...)
vsprintf_s(re3_buff, re3_buffsize, format, va); vsprintf_s(re3_buff, re3_buffsize, format, va);
va_end(va); va_end(va);
::MessageBoxA(nil, re3_buff, "RE3 Error!", ::MessageBoxA(nil, re3_buff, "REVC Error!",
MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL); MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
raise(SIGABRT); raise(SIGABRT);
@ -1215,9 +1295,9 @@ void re3_usererror(const char *format, ...)
#else #else
vsprintf(re3_buff, format, va); vsprintf(re3_buff, format, va);
#ifdef __WIIU__ #ifdef __WIIU__
WHBLogPrintf("\nRE3 Error!\n\t%s\n",re3_buff); WHBLogPrintf("\nREVC Error!\n\t%s\n",re3_buff);
#else #else
printf("\nRE3 Error!\n\t%s\n",re3_buff); printf("\nREVC Error!\n\t%s\n",re3_buff);
#endif #endif
assert(false); assert(false);
#endif #endif

View File

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

View File

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

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