Compare commits

...

256 Commits

Author SHA1 Message Date
withmorten 3233ffe1c4
Merge pull request #1233 from madebr/cmake-fixes
Fix cmake installation with conan
2021-09-03 00:38:46 +02:00
Sergeanur 3569b7edfe Fix ped comments on oal 2021-09-02 19:22:29 +03:00
Sergeanur a15d5589b3 Fix reflection counter 2021-09-02 18:49:49 +03:00
Sergeanur d23c045d11 Audio: small refactoring 2021-09-02 18:30:15 +03:00
Sergeanur 3bc6aa85da Audio: a bit more PS2 changes 2021-09-02 17:52:11 +03:00
Sergeanur 5aa149f0bc PS2 ProcessReverb 2021-09-02 12:58:42 +03:00
Sergeanur 8c1f1cc7b8 PS2 mission audio length 2021-09-02 12:43:15 +03:00
Sergeanur 9b511d28ec Audio: PS2 cAudioManager::ServicePoliceRadioChannel 2021-09-02 08:31:22 +03:00
Sergeanur c41239ed5e Ped comments fixes 2021-09-02 08:00:04 +03:00
Sergeanur 787f1922f4 Audio: fix types for IsSampleBankLoaded/IsPedCommentLoaded, reverse ProcessSpecial from PS2 2021-09-02 07:13:35 +03:00
withmorten 6d44cee7c2 fix librw to be most recent 2021-09-01 15:57:05 +02:00
Sergeanur 6c3cb330c1 Audio: PS2 mission audio 2021-09-01 13:25:47 +03:00
Sergeanur 57757e6c6f Audio: PS2 pager code 2021-09-01 10:44:38 +03:00
Sergeanur 1c426fdff1 Audio: some PS2 code 2021-09-01 08:09:33 +03:00
Sergeanur bcdeb71070 Audio: ps2 code ifdef 2021-08-30 11:25:14 +03:00
Nikolay Korolev 9bb34fab25 ps2 fix 2021-08-29 19:45:52 +03:00
Nikolay Korolev 8593fff48b fix PS2 script 2021-08-29 19:36:44 +03:00
Sergeanur 55e950fe84 Audio: fixing bugs, fixing types, making code more accurate to original 2021-08-29 09:42:24 +03:00
Nikolay af543350db
Merge pull request #1322 from x87/master
Mention CLEO Redux
2021-08-28 14:16:45 +03:00
x87 9c71524583
Mention CLEO Redux 2021-08-27 13:29:32 -04:00
Nikolay Korolev 399fb28f77 fix debug teleport 2021-08-26 21:50:19 +03:00
Sergeanur 2e02aed5d5 Fix acceleration sound on exiting the vehicle 2021-08-26 08:15:03 +03:00
Nikolay Korolev 885467bcd0 keep noinline only for broken vs versions 2021-08-26 01:24:31 +03:00
Sergeanur 5017e09dd0 Refactor cPedComments 2021-08-25 13:41:29 +03:00
Sergeanur ee93e4bc7d Audio: refactoring, type fixes, renaming cAudioManager fields 2021-08-25 08:49:42 +03:00
Sergeanur 9ecca45bf3 Audio: fix PS2 ifdefs 2021-08-24 15:24:28 +03:00
Sergeanur 38f4ea7aa3 Audio enhancements:
* redo high fps fix
* make releasing vehicle sounds attach to entities
* fix bug with reusing audio entity that is still being used
* use time scale to modify sound speed
2021-08-24 13:11:36 +03:00
erorcun e9a61ca38c Adjust plane free cam values for sparks to be visible in Dodo 2021-08-23 21:56:22 +03:00
Sergeanur ceb65eafa5 Make ped comments update position and volume 2021-08-23 11:15:03 +03:00
erorcun 6110f74ad6 Add forgotten bit from X11 detection 2021-08-22 13:00:33 +03:00
erorcun c52aebe8e7 Fix an original bug about entering boat sometimes takes 2 key press 2021-08-21 19:07:26 +03:00
erorcun f86bdb2cdb Fix map teleport Z coordinate 2021-08-21 17:15:30 +03:00
erorcun e33b56b49a VC bits 2021-08-21 15:13:23 +03:00
Sergeanur b683c047dc Remove cMissionAudio, move cAMCrime array outside of cPoliceRadioQueue (R* vision) 2021-08-21 12:18:45 +03:00
Nikolay Korolev 7d5b1e6c2e fix 2021-08-20 20:38:24 +03:00
Nikolay Korolev aa104bb0aa small refactoring 2021-08-20 17:49:51 +03:00
Sergeanur ef0b5f857d A few small audio changes 2021-08-20 14:28:18 +03:00
Sergeanur c168786b42 Audio refactoring:
* renamed tSound fields, added descriptions for each field
* getting rid of term 'intensity' in favour of 'max distance'
* renamed two cAudioManager fields
* fix volume not being reduced for stopping sounds that are looped
* reverse a few PS2 bits
2021-08-20 13:02:58 +03:00
aap 0e5ffb8c34 CAutomobile fixes 2021-08-20 10:29:33 +02:00
withmorten d3e7ab933d update librw 2021-08-19 17:02:26 +02:00
Sergeanur eda2c05448 Audio: ifdef more things that aren't on ps2 2021-08-18 21:07:33 +03:00
Sergeanur 01c70dfb76 Fix acceleration sound playing when exiting the vehicle 2021-08-18 18:37:10 +03:00
Sergeanur 597802ff2e One more type fix 2021-08-18 15:37:31 +03:00
Sergeanur 5c562c3adc More type fixes in audio 2021-08-18 15:31:58 +03:00
aap d4175c5315 update librw 2021-08-17 23:21:27 +02:00
aap 6b4b11d80e fix opengl; update librw 2021-08-17 12:59:30 +02:00
Sergeanur 16ff379ebe Add AUDIO_REFLECTIONS define, fix a bunch of types, fix heli chatter intensity 2021-08-17 13:58:48 +03:00
Sergeanur 2526503743 Remove FIX_BUGS that wasn't needed 2021-08-17 10:50:53 +03:00
erorcun e0ecbeee39 Auto-detect X11 dependency 2021-08-16 21:06:52 +03:00
erorcun 79856dac25 Fix impossible bullets & turn speed on heavy guns 2021-08-16 21:06:06 +03:00
erorcun 8641e9d0bb Switch PR & remove X11 part from CMakeLists 2021-08-16 20:02:40 +03:00
Sergeanur 076b324539 Fix ped comments playing at full volume behind the wall 2021-08-16 14:21:51 +03:00
Sergeanur bcb5b4f94d Remove not needed entry from config 2021-08-16 10:29:44 +03:00
Sergeanur ab03fbb6c8 Make UpdateReflections a bit more binary exact + small code changes to sync with miami 2021-08-16 09:59:08 +03:00
aap 97aeb85d84 some CAutomobile fixes 2021-08-16 00:25:47 +02:00
Nikolay Korolev 4b4aefe339 bruh 2021-08-15 18:40:38 +03:00
Nikolay Korolev c48f6e9bda actual fix 2021-08-15 18:35:47 +03:00
Nikolay Korolev 5fe04940be lil fix 2021-08-15 18:27:30 +03:00
Sergeanur 854ee12d9d Fix ifdef for audio reflection members 2021-08-15 14:11:20 +03:00
Sergeanur 5ddd0649e3 Fix cAudioManager::ProcessVehicleEngine return type, document PS2 changes, rename Sound Intensity 2021-08-15 13:14:16 +03:00
Sergeanur 886650a887 Fix CW build 2021-08-15 13:12:10 +03:00
erorcun 747ae04279 Fix premature .ini saving leading to missing bindings 2021-08-15 04:07:48 +03:00
erorcun df89e5091e Revert "map memory usage high default"
This reverts commit b7c7c883d7.
2021-08-13 00:16:16 +03:00
withmorten b7c7c883d7 map memory usage high default 2021-08-12 23:07:54 +02:00
Sergeanur 8759c2edf0 Sync fixes from miami 2021-08-12 15:01:58 +03:00
Sergeanur 033d89a9ab Refactor cAudioManager::ProcessActiveQueues, fix doppler effect 2021-08-12 13:01:07 +03:00
Sergeanur f1545daeae Rename unused audio member 2021-08-12 11:46:10 +03:00
Sergeanur 4f8993e19b Replace static_assert with #error 2021-08-12 11:39:34 +03:00
Sergeanur 2ef43e8d1a Fix sampman_null 2021-08-12 11:39:34 +03:00
Sergeanur ce78081a7f Put more things under ifdef 2021-08-12 11:39:34 +03:00
Sergeanur 6c2d179aad Add define to enable/disable external 3d audio simulation 2021-08-12 11:39:34 +03:00
Sergeanur 2eb0390dc9 Fix unset emitting volume for sawmill 2021-08-11 13:35:50 +03:00
Sergeanur f131f70761 Fix unset emitting volume for moan sound 2021-08-11 12:10:48 +03:00
Sergeanur 1f98f01dcb Fix a bunch of CModelInfo::GetModelInfo->GetColModel calls 2021-08-09 18:14:19 +03:00
Sergeanur 8ea411e4c5 Add sprite to the waypoint marker 2021-08-09 18:07:42 +03:00
withmorten 858f913fac small fix 2021-08-09 16:34:05 +02:00
Nikolay Korolev 35dd465c19 Revert "small fix"
This reverts commit bd96584433.
2021-08-08 17:41:35 +03:00
Nikolay Korolev bd96584433 small fix 2021-08-08 17:34:03 +03:00
Nikolay Korolev 947f67dfb7 small fix 2021-08-08 17:17:20 +03:00
Nikolay Korolev 63046894b0 small refactoring 2021-08-08 16:57:37 +03:00
Nikolay Korolev 15f770531c fixed tab 2021-08-08 15:42:44 +03:00
aap 4f461bd7be CVehicle fixes and cleanup 2021-08-04 13:54:04 +02:00
aap 09748d094a CPhysical fixes and cleanup 2021-08-02 20:02:35 +02:00
Sergeanur cb5586e658
Merge pull request #1268 from Nick007J/master
move debug stuff to a separate file
2021-08-02 15:06:40 +03:00
Sergeanur 865ce46fdb Fix waypoint disappearing after each save 2021-08-02 14:26:00 +03:00
Nikolay Korolev 2b99f2634b sync 2021-08-01 14:00:16 +03:00
Nikolay Korolev 6d7dec96af move debug script stuff to a separate file 2021-08-01 13:58:15 +03:00
erorcun 0542b1bd4d Fix radio scroll when player controls disabled 2021-07-31 23:03:59 +03:00
Sergeanur 232b5a04ba
Merge pull request #1251 from Sergeanur/HigherDrawDist
Make cars and peds to not despawn when you look away
2021-07-31 20:07:29 +03:00
Sergeanur 9d25e7f315
Merge pull request #1248 from davicr/radar-cutscene-bugfix
Fix blip rendering during scripted sequences
2021-07-31 20:06:20 +03:00
aap 3c5bae164f CVisibilityPlugins and CRenderer fixes 2021-07-29 19:43:47 +02:00
Sergeanur 6cea1de9e6 Reverse unused audio functions from mobile 2021-07-29 00:40:32 +03:00
Sergeanur 81673ab304 Fix comments 2021-07-28 10:36:18 +03:00
Sergeanur d0666a8702 One more type fix 2021-07-27 22:38:35 +03:00
Sergeanur 16e2e3d091 Type fix 2021-07-27 22:32:47 +03:00
Sergeanur 5240dce018 cAudioManager::GetCollisionOneShotRatio cleanup 2021-07-27 22:01:17 +03:00
erorcun 1eedf7f0ae
Merge pull request #1257 from Nopey/fixbugs_pedgaplist
Fix bug triggering gnNumTempPedList assertion
2021-07-27 21:51:28 +03:00
Magnus Larsen 55e83982c3 Remove static_assert from previous commit 2021-07-27 00:23:40 -07:00
Magnus Larsen 388dd5cb00 Allow sector ped count to exceed gap-list size
This solves the gnNumTempPedList assertion.
To prove this works, change gapTempPedList's length to 12, and visit the
Triad's basketball court.
2021-07-26 19:50:10 -07:00
withmorten d77ed4608f fix 2021-07-26 20:25:36 +02:00
Sergeanur f19a1aebd4 Remove deceiving comment 2021-07-26 09:16:20 +03:00
Sergeanur bc3734cae3 Fix smooth spray when shooting with colt or usi while using PC controls 2021-07-26 09:13:16 +03:00
Sergeanur cafc0f3c10 Fix ridiculously accurate bullets when you shoot behind with enabled free camera 2021-07-26 08:28:01 +03:00
Sergeanur f73dfa12e6 Make cars and peds to not despawn when you look away 2021-07-26 04:43:26 +03:00
Sergeanur 6a94299eac Fix 2021-07-26 04:42:15 +03:00
Sergeanur a064b3a687 Audio changes:
- Reorder AudioCollision.cpp functions into original order
- Add missing cAudioCollision::Reset()
- Move cAudioCollision ctor into .h (like original)
- Fix argument types for ped comment functions and more
- Fix wrong names of ped comment functions
- Fix incorrect ped comments
- Remove getters
- Reorder declarations of cAudioManager
- Wrap PC only functions around ifdef
- Add cAudioManager methods from PS2 and mobile
2021-07-26 04:34:55 +03:00
Nikolay Korolev a7e673c2ec sync 2021-07-24 00:47:04 +03:00
Sergeanur 3adf37a3a9 Fix aiming with flamethrower with PC controls 2021-07-22 22:54:30 +03:00
Davi bd3c3849fe Properly fix blip rendering during scripted sequences
Changes conditionals from "DrawBlips" and "ShowRadarTrace", "ShowRadarTraceWithHeight" to allow blips to be rendered during scripted sequences when "MENU_MAP" is enabled.
2021-07-22 16:10:15 -03:00
Sergeanur 1d1f10d68c Fixes from miami 2021-07-22 20:56:15 +03:00
withmorten a437d2bc26 fix garbage data written in garage save block 2021-07-19 23:43:51 +02:00
Sergeanur d0404cbdb7 render -> renderer (original name) 2021-07-18 00:04:26 +03:00
withmorten 8018e40ebf
Merge pull request #1217 from Nopey/master
Fix debug script loader crashing missions
2021-07-15 23:09:28 +02:00
Sergeanur 2ce36a48b9 Make PS2 VB files work together with PC audio files 2021-07-15 18:06:02 +03:00
Sergeanur 4f78733836 Remove stupid cast 2021-07-15 00:47:11 +03:00
erorcun d2e594db2b
Merge pull request #1236 from Nopey/fix_nearPeds
Fix NearPed count going negative
2021-07-13 18:10:59 +03:00
Magnus Larsen 894495689f Fix NearPed count going negative 2021-07-12 23:51:28 -07:00
Adrian Graber 207378c947 Use svcGetInfo definitions from libnx
Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
2021-07-13 00:50:49 +02:00
Adrian Graber a7b38e1b34 Save current usable memory for Switch application 2021-07-13 00:50:49 +02:00
Adrian Graber 5cab196718 Finish cmake stuff for Switch build
* SDL2 for OpenAL not needed anymore
* Add re3_platform_target function and use that instead of manually building NRO
2021-07-13 00:50:49 +02:00
Adrian Graber 3bde84f6c8 Move assets to dedicated folder and redefine GLFW mappings for Switch 2021-07-13 00:50:49 +02:00
Adrian Graber a99a04ed49 Add Switch controller asset and configuration
* Add GXT string for the Nintendo Switch Controller
* Add frontend and button textures for Nintendo Switch controllers
* Fix wrong #ifndef when hiding screen resolution option on GTA_HANDHELD
2021-07-13 00:50:49 +02:00
Adrian Graber b09b489ae7 Fix WINDOWS -> WIN32 on cmake 2021-07-13 00:50:49 +02:00
Anonymous Maarten a247d53367 cmake: fix OpenAL on Switch + using X11 on Linux 2021-07-13 00:50:49 +02:00
Adrian Graber ca5d3c8811 Replace GTA_SWITCH macro and use GAMEPAD_MENU
* Replace GTA_SWITCH macro with __SWITCH__ for platform specific stuff and GTA_HANDHELD for the rest (which could be used by other ports)
* Use GAMEPAD_MENU on GTA_HANDHELD, which will replace the usual controller setup (which contains some useless features for handhelds)
* Fix some identation inconsistencies
* Disable PC_PLAYER_CONTROLS on GTA_HANDHELD builds
2021-07-13 00:50:49 +02:00
Adrian Graber 02ec56e8f7 Add platform specific functions for glfw vibration
With implementation for Switch vibration through libnx hid/pad API
2021-07-13 00:50:45 +02:00
Adrian Graber 6da20aa723 Enable Gamepad Menu on Switch 2021-07-13 00:49:21 +02:00
Adrian Graber 28f266302f Add Nintendo Switch initial support 2021-07-13 00:49:13 +02:00
withmorten a4b92fe9be fix premake 2021-07-12 23:26:49 +02:00
Anonymous Maarten 152148d71f conan: copy gamefiles to source folder so cmake install succeeds 2021-07-12 18:00:04 +02:00
Anonymous Maarten 3d922c90e9 cmake: add _INSTALL cmake option 2021-07-12 18:00:02 +02:00
withmorten f50026828a Vanilla config for Windows and win-x86 only 2021-07-12 04:24:10 +02:00
withmorten ac3905123e fix 2021-07-12 03:10:02 +02:00
Sergeanur b4364c3672 Reorganize config.h 2021-07-12 03:34:37 +03:00
erorcun 3515363df5
Merge pull request #1218 from withmorten/ini
switch out current ini_parser.hpp with pulzed/mINI
2021-07-12 02:40:15 +03:00
withmorten c0cbf8045f switch out current ini_parser.hpp with pulzed/mINI 2021-07-12 01:19:22 +02:00
erorcun a8fd3f828a
Merge pull request #1149 from withmorten/saves
finish COMPATIBLE_SAVES and FIX_INCOMPATIBLE_SAVES
2021-07-12 01:06:59 +03:00
erorcun 291213ed40 Unite all sliders 2021-07-12 00:51:45 +03:00
erorcun 2a6f9c2757 Add ped and car density slider to menu, remove dumb collision "optimization" 2021-07-12 00:12:25 +03:00
Sergeanur 11434f96cc Add PED DENSITY and CAR DENSITY lines to GXT 2021-07-11 23:52:55 +03:00
withmorten 3194fdb2c1 fix the fix (and another fix) 2021-07-11 03:34:43 +02:00
withmorten d7ceb4870c tiny diff fixes 2021-07-11 03:26:21 +02:00
erorcun e9baf31ad8 Physical: division by zero fix 2021-07-10 23:24:27 +03:00
erorcun d82dbf91ef Merge/sync fixes after threaded audio 2021-07-10 23:14:13 +03:00
erorcun db4ae18e5d Remove waiting for stream closure in multi-thread audio 2021-07-10 23:14:08 +03:00
erorcun 5458632c40 Multi-threaded audio fixes 2021-07-10 23:13:51 +03:00
erorcun ab73c2f539 Multi-threaded audio streams
Under MULTITHREADED_AUDIO define.
2021-07-10 23:13:42 +03:00
Magnus Larsen 12efd1209b Fix Cheat menu debug script loader 2021-07-10 10:18:32 -07:00
Magnus Larsen 33c45e4ae0 Fix debug script loader crashing missions
* open_script is now exposed in Script.h, perhaps it should be namespaced
as a static method on CTheScripts? I'm unsure what is preferred.
* I've moved the joypad code out of open_script to prevent buttons held
  down at mission load time from changing the scriptToLoad.
2021-07-10 09:34:17 -07:00
withmorten 011aafa043 finish COMPATIBLE_SAVES and FIX_INCOMPATIBLE_SAVES 2021-07-10 17:30:27 +02:00
withmorten 71f28c8cf5
readme: fix lto option 2021-07-10 01:17:03 +02:00
withmorten 4eb9a149e4 recompile german.gxt 2021-07-10 01:06:34 +02:00
withmorten f09da45823
Merge pull request #1134 from RuesanG/master
German is 100%
2021-07-10 01:06:01 +02:00
Sergeanur d824a321b9 Update GXT compiler with fix of German 2021-07-10 02:02:42 +03:00
withmorten 9a68f94c54
Update german.txt 2021-07-10 00:43:22 +02:00
withmorten a7ab4cc23a
Update german.txt 2021-07-10 00:20:26 +02:00
withmorten 5b390ade40
Update german.txt 2021-07-10 00:19:02 +02:00
IgorPolyakov f184c43b9b Update russian.txt 2021-07-10 01:10:25 +03:00
withmorten 37b6d491e7 fix jittery cars at 15fps 2021-07-09 18:50:33 +02:00
withmorten e2ae17d994 add librw defines to vanilla defines undefs 2021-07-09 18:02:36 +02:00
Sergeanur 47f153fe76 Use CPad functions to check key states in script loader 2021-07-08 03:24:47 +03:00
withmorten f9a2f1daf7 fix macro redefinition warnings on win-glfw build 2021-07-08 01:40:58 +02:00
withmorten dadc56ccf9 fix sampman_null build 2021-07-07 01:54:16 +02:00
erorcun 164623d58e
Merge pull request #1188 from mssx86/echo_to_printf
fix: printHash.sh; replace echo -n, check if $1 is set.
2021-07-05 21:04:05 +03:00
erorcun 386b113603
Merge pull request #1187 from mssx86/musl_fix
fix: add missing limits.h includes to enable bulding on musl.
2021-07-05 20:50:18 +03:00
withmorten 8916fe1820 fix cmake workflow 2021-07-05 19:07:47 +02:00
erorcun ab7513cc85
Merge pull request #1202 from AGraber/librw_update
Update librw
2021-07-04 19:34:28 +03:00
Adrian Graber 6edb8d9610 Update librw 2021-07-04 18:14:24 +02:00
withmorten 52e4cd19ce
Update README.md 2021-07-03 23:10:50 +02:00
erorcun ec45ba68cd
Add MacOS to Readme 2021-07-03 16:34:55 +03:00
Sergeanur 77f31105de Fix overflow in audio code 2021-07-03 15:57:48 +03:00
erorcun 3136ce6451 Fix Mac M1 premake 2021-07-03 15:33:40 +03:00
withmorten 060c1181bc fix previous PED_SKIN commit, add comments 2021-07-03 02:52:54 +02:00
withmorten be6e273930 premake: add no-full-paths option for CI builds, rename lto to with-lto 2021-07-03 02:40:25 +02:00
withmorten 63d9d9c148 disable PED_SKIN and PEDS_REPORT_CRIMES_ON_PHONE when COMPATIBLE_SAVES is disabled 2021-07-03 01:32:04 +02:00
erorcun 51042e15aa Remove redundant part of 'Sanitizer fixes 2' 2021-07-03 01:53:43 +03:00
erorcun a8549e86a7 Sanitizer fixes 2 2021-07-03 01:42:24 +03:00
erorcun 424a6d90bd Peds: Efforts to find the reason of crashes on GCC 7.5.0
* Prevent deleted peds to be in nearPeds list (was always needed, might be unrelated to crashes)
* Add asserts to nearPeds and PedIK ctor (crash reasons)
* Shouldn't fix reported crashes since they were caused by null peds.
2021-07-03 01:30:54 +03:00
erorcun 70fa7fc239 Sanitizer fixes 2021-07-03 01:28:32 +03:00
Sergeanur 7df71c9673 Refactor OnscreenTimer 2021-07-02 10:18:22 +03:00
withmorten f7816c577f fix compilation when ctype.h is included 2021-07-01 21:49:01 +02:00
mssx86 de64bbe875
fix: printHash.sh; replace echo -n, check if $1 is set. 2021-07-01 20:14:46 +03:00
mssx86 b8e80a67ea
fix: add missing limits.h includes to enable bulding on musl. 2021-07-01 20:12:28 +03:00
withmorten 2071abd295 zero out work_buff before writing padding in save 2021-07-01 18:08:48 +02:00
Sergeanur a3964dfd4a Pause radio when game is paused 2021-06-30 21:36:11 +03:00
withmorten 3383d8c6e7 fix some string sizes to be MAX_PATH 2021-06-30 16:23:44 +02:00
erorcun 22e8e0eff8 Fix MP3 finding stack crash 2021-06-28 17:35:25 +03:00
withmorten cb3b3855b8 rename clamp macro to Clamp to fix compilation with g++11 2021-06-28 13:31:35 +02:00
erorcun cc235be3aa Less invasive red tint on Delete Game page 2021-06-27 18:14:34 +03:00
erorcun 53a4b6936b Revert "Use PS2-y global names on SampMan"
We know that they changed all those names on PC.

This reverts commit 091a65996e.
2021-06-27 17:59:50 +03:00
erorcun 091a65996e Use PS2-y global names on SampMan 2021-06-27 17:53:14 +03:00
erorcun a923728877 Fix map texture leak 2021-06-27 00:34:46 +03:00
withmorten 4819d195d8 fix WriteSaveHeader 2021-06-26 19:19:45 +02:00
withmorten f3a931e1c9 Revert "Revert "Redo ReadSaveBuf + common.h cleanup""
This reverts commit af7573ddbe.
2021-06-26 19:14:46 +02:00
Sergeanur 090fa619b4
Merge pull request #1155 from leanndroguedes/master
re3: Update Linux 64bit build download link
2021-06-26 18:22:31 +03:00
Leandro Guedes 2c92accb8e
re3: Update Linux 64bit build download link 2021-06-26 12:11:29 -03:00
withmorten 171d9fd036 fix screenshot name space 2021-06-26 13:13:07 +02:00
withmorten 036eff2c48 swap out codewarrior re3.mcp with xml export 2021-06-26 03:32:08 +02:00
withmorten fff899ec16 fix tabs in premake 2021-06-26 03:19:52 +02:00
Sergeanur 6cb8c11285 Fix premature CTimer calls 2021-06-26 04:09:45 +03:00
Sergeanur 3092b9a46e Small timer fix 2021-06-26 01:56:29 +03:00
erorcun 9b5caa190e Pool fixes
Mostly for Linux
2021-06-26 00:27:20 +03:00
erorcun af7573ddbe Revert "Redo ReadSaveBuf + common.h cleanup"
This reverts commit 2b67aba94c.
2021-06-26 00:25:59 +03:00
withmorten 4bab6d5356
Merge pull request #1147 from withmorten/githash
add no-git-hash option to premake
2021-06-25 19:51:45 +02:00
Sergeanur 2b67aba94c Redo ReadSaveBuf + common.h cleanup 2021-06-25 19:03:51 +03:00
erorcun 6152f02333
Update invite link 2021-06-25 16:22:20 +03:00
withmorten 84fb48825d add no-git-hash option to premake 2021-06-25 02:40:42 +02:00
withmorten a83ecc123d fix cmake build? 2021-06-25 02:32:41 +02:00
Sergeanur 1f082a85cb Refactor CTimer::Update 2021-06-25 02:33:40 +03:00
Sergeanur 5c1af537af Don't restart OAL device when switching EAX 2021-06-24 21:32:44 +03:00
Sergeanur a446dbefaa Fix police scanner on high fps 2021-06-24 21:32:44 +03:00
Sergeanur 2592da2273 Remove frameTime, fix pause mode timer 2021-06-24 21:32:44 +03:00
Sergeanur b90784da90 Make times more accurate 2021-06-24 21:32:44 +03:00
Sergeanur f741101e44 Fix redone + add hud fix 2021-06-24 21:32:44 +03:00
Sergeanur cacec36dd1 Fix cut off sfx on high framerates 2021-06-24 21:32:44 +03:00
Sergeanur f2390deaa9 Make sampman stream functions default to stream 0 2021-06-24 21:32:44 +03:00
Sergeanur 8fc99387f5 Fix use of enum in ped comment banks switch 2021-06-24 21:32:44 +03:00
Sergeanur 939d0c59a3 Add macros to set sample loop offsets 2021-06-24 21:32:44 +03:00
Sergeanur edc25a689f Fix typo 2021-06-24 21:32:44 +03:00
Sergeanur 68b5270fe4 Fix some timer calls 2021-06-24 21:32:43 +03:00
Sergeanur a11bf19b93 Fix sin & cos calls 2021-06-24 21:32:43 +03:00
Sergeanur 2ad3a75be5 Fix IsSphereVisible calls 2021-06-24 21:32:43 +03:00
aap 50058371ef CEntity and C(Vu)Vector fixes and cleanup 2021-06-24 21:32:43 +03:00
Sergeanur ce0a097392 Undef PS2_AUDIO_CHANNELS for SQUEEZE_PERFORMANCE and VANILLA_DEFINES 2021-06-24 21:32:43 +03:00
Sergeanur 1e084dfab7 Set number of stereo sources 2021-06-24 21:32:43 +03:00
Sergeanur 5a55d3a949 Patch PolRadio 2021-06-24 21:32:43 +03:00
Sergeanur 7a2dbd9112 Increase the number of audio channels to PS2 count and some small audio fixes 2021-06-24 21:32:43 +03:00
Sergeanur c9804510d1 This means sound should be panned right, not volume 2021-06-24 21:32:43 +03:00
Sergeanur c37f4c3c1a Fix cAudioManager::SetupJumboFlySound 2021-06-24 21:32:43 +03:00
Sergeanur 319bf9d8d2 Fix return type 2021-06-24 21:32:43 +03:00
Sergeanur 786e101acf Use bool8 in audio code 2021-06-24 21:32:43 +03:00
Sergeanur 596e12b897 Fix C3dMarkers::PlaceMarker calls in Radar 2021-06-24 21:32:43 +03:00
Sergeanur 4a9d890ae9 Fix quiet police scanner on OpenAL 2021-06-24 21:32:43 +03:00
Sergeanur 873c4fc81e Make gang members react to sexy females 2021-06-24 21:32:43 +03:00
Sergeanur f518676b76 fabs -> fabsf 2021-06-24 21:32:43 +03:00
Sergeanur 0f6583560d small RoadBlock fix 2021-06-24 21:32:43 +03:00
Sergeanur 6537dfe7f1 Use some GetMatrix/SetMatrix logic based on SA + CutsceneHead fix 2021-06-24 21:32:43 +03:00
aap f2b59f5097 update librw 2021-06-24 21:32:43 +03:00
erorcun 8ae4859398 Fix FPE 2021-06-24 21:32:43 +03:00
aap c4f231deb4 experiment: sorted building list for new renderer 2021-06-24 21:32:43 +03:00
aap c58d98a39e fix new renderer 2021-06-24 21:32:43 +03:00
aap 77ca9c593f fix postfx fix 2021-06-24 21:32:43 +03:00
erorcun 8488dc791a Pointless fixes 2021-06-24 21:32:39 +03:00
aap df1ad8e122 fix postfx 2021-02-28 15:29:58 +01:00
aap 931bc690cd proper radar clipping 2021-02-28 14:55:01 +01:00
aap 087174c6a6 update librw; little fix 2021-02-28 14:15:22 +01:00
Sergeanur 9fce8636b0 Fix muzzleflash rotation 2021-02-26 20:37:22 +02:00
Sergeanur 5bdbb5f802 Uhh, right 2021-02-26 11:05:37 +02:00
Sergeanur 59c9ae29cf PoliceRadio -> PolRadio (original name) 2021-02-26 10:56:26 +02:00
Sergeanur 82ebd8aae1 Fix controls 2021-02-22 17:47:58 +02:00
withmorten a3f1601fd1 Merge pull request 'Fix potential stack corruption in HandleGraphEvent in 64bit arch' (#2) from HaydnTrigg/re3:master into master 2021-02-21 16:13:56 +00:00
Haydn Trigg 620155ac8d Fix stack corruption in HandleGraphEvent 2021-02-21 11:38:32 +00:00
aap 9a7fa47857 make debug render groups optional 2021-02-19 18:41:31 +01:00
withmorten 0b1d3669bc
remove nightly 2021-02-19 18:21:04 +01:00
RuesanG 53631f97db
Add files via upload 2021-02-19 03:41:59 +01:00
RuesanG 006254fc9c
Add files via upload
Fixed strings
2021-02-19 03:37:59 +01:00
256 changed files with 31329 additions and 10898 deletions

View File

@ -23,11 +23,11 @@ jobs:
# - os: 'windows-latest'
# platform: 'd3d9'
# audio: 'miles'
- os: 'ubuntu-latest'
- os: 'ubuntu-18.04'
platform: 'gl3'
gl3_gfxlib: 'glfw'
audio: 'openal'
# - os: 'ubuntu-latest'
# - os: 'ubuntu-18.04'
# platform: 'gl3'
# gl3_gfxlib: 'sdl2'
# audio: 'openal'
@ -63,8 +63,9 @@ jobs:
python -m pip install conan
conan config init
conan config set log.print_run_commands=True
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
conan remote add madebr_ps2dev https://api.bintray.com/conan/madebr/ps2dev
conan config set general.revisions_enabled=1
conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan
# conan remote add madebr_ps2dev https://api.bintray.com/conan/madebr/ps2dev
- name: "Add os=playstation2 + gcc.version=3.2 to .conan/settings.yml"
shell: python
run: |
@ -85,7 +86,7 @@ jobs:
fi
- name: "Export Playstation 2 CMake toolchain conan recipe"
run: |
conan export vendor/librw/cmake/ps2toolchain ps2dev-cmaketoolchain/master@
conan export vendor/librw/cmake/ps2/cmaketoolchain ps2dev-cmaketoolchain/master@
- name: "Export librw conan recipe"
run: |
conan export vendor/librw librw/master@

28
.github/workflows/build-switch.yml vendored Normal file
View File

@ -0,0 +1,28 @@
name: re3 cmake devkitA64 (Nintendo Switch)
on:
pull_request:
push:
release:
types: published
jobs:
build-nintendo-switch:
runs-on: ubuntu-latest
container: devkitpro/devkita64:latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'true'
- name: "Build files"
run: |
/opt/devkitpro/portlibs/switch/bin/aarch64-none-elf-cmake -S. -Bbuild -DRE3_AUDIO=OAL -DLIBRW_PLATFORM=GL3 -DLIBRW_GL3_GFXLIB=GLFW -DRE3_WITH_OPUS=False -DRE3_VENDORED_LIBRW=True -DRE3_INSTALL=True
cmake --build build --parallel
- name: "Create binary package (cpack)"
working-directory: ./build
run: |
cpack
- name: "Archive binary package (github artifacts)"
uses: actions/upload-artifact@v2
with:
name: "switch-gl3"
path: build/*.zip
if-no-files-found: error

View File

@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
platform: [win-amd64-librw_d3d9-oal, win-amd64-librw_gl3_glfw-oal]
buildtype: [Debug, Release, Vanilla]
buildtype: [Debug, Release]
steps:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2
@ -34,7 +34,7 @@ jobs:
7z x ${{env.GLFW_FILE}}
- name: Configure build
run: |
./premake5 vs2019 --with-librw --glfwdir64=${{env.GLFW_BASE}}
./premake5 vs2019 --with-librw --no-full-paths --glfwdir64=${{env.GLFW_BASE}}
- name: Build
run: |
msbuild -m build/re3.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}

View File

@ -34,7 +34,7 @@ jobs:
7z x ${{env.GLFW_FILE}}
- name: Configure build
run: |
./premake5 vs2019 --with-librw --glfwdir32=${{env.GLFW_BASE}}
./premake5 vs2019 --with-librw --no-full-paths --glfwdir32=${{env.GLFW_BASE}}
- name: Build
run: |
msbuild -m build/re3.sln /property:Configuration=${{matrix.buildtype}} /property:Platform=${{matrix.platform}}

1
.gitignore vendored
View File

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

View File

@ -26,6 +26,24 @@
"compilerArgs": ["-ggdb"],
"cStandard": "gnu11",
"cppStandard": "gnu++14"
},
{
"name": "devkitPro aarch64 (Nintendo Switch)",
"compilerPath": "${env:DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++",
"includePath": [
"${default}",
"${env:DEVKITPRO}/portlibs/switch/include",
"${env:DEVKITPRO}/libnx/include"
],
"intelliSenseMode": "gcc-arm64",
"cStandard": "gnu11",
"cppStandard": "gnu++11",
"defines": [
"__SWITCH__",
"LIBRW",
"RW_GL3",
"AUDIO_OAL"
]
}
],
"version": 4

12
.vscode/settings.json vendored
View File

@ -2,8 +2,13 @@
"C_Cpp.default.cStandard": "gnu11",
"C_Cpp.default.cppStandard": "gnu++14",
"C_Cpp.default.includePath": [
"src",
"src/animation",
"src/audio",
"src/audio/eax",
"src/audio/oal",
"src/buildings",
"src/collision",
"src/control",
"src/core",
"src/entities",
@ -13,10 +18,11 @@
"src/modelinfo",
"src/objects",
"src/peds",
"src/render",
"src/renderer",
"src/rw",
"src/save",
"src/skel",
"src/save/",
"src/skel/",
"src/skel/glfw",
"src/text",
"src/vehicles",
"src/weapons",

View File

@ -1,15 +1,26 @@
cmake_minimum_required(VERSION 3.8)
cmake_minimum_required(VERSION 3.14)
set(EXECUTABLE re3)
set(PROJECT RE3)
project(${EXECUTABLE} C CXX)
set(${PROJECT}_AUTHOR "${PROJECT} Team")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1 "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR")
message(STATUS "Building ${CMAKE_PROJECT_NAME} GIT SHA1: ${GIT_SHA1}")
if(NINTENDO_SWITCH)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/nx")
include(NXFunctions)
endif()
if(NOT COMMAND re3_platform_target)
function(re3_platform_target)
endfunction()
endif()
if(WIN32)
set(${PROJECT}_AUDIOS "OAL" "MSS")
else()
@ -18,6 +29,7 @@ endif()
set(${PROJECT}_AUDIO "OAL" CACHE STRING "Audio")
option(${PROJECT}_INSTALL "Enable installation of ${EXECUTABLE} + gamefiles" OFF)
option(${PROJECT}_WITH_OPUS "Build ${EXECUTABLE} with opus support" OFF)
option(${PROJECT}_WITH_LIBSNDFILE "Build ${EXECUTABLE} with libsndfile (instead of internal decoder)" OFF)
@ -66,6 +78,8 @@ if(${PROJECT}_INSTALL)
set(os "-apple")
elseif(UNIX)
set(os "-linux")
elseif(NINTENDO_SWITCH)
set(os "-switch")
else()
set(compiler "-UNK")
message(WARNING "Unknown os. Created cpack package will be wrong. (override using cpack -P)")

View File

@ -1,13 +1,13 @@
<img src="https://github.com/GTAmodding/re3/blob/master/logo.png?raw=true" alt="re3 logo" width="200">
<img src="https://github.com/GTAmodding/re3/blob/master/res/images/logo_1024.png?raw=true" alt="re3 logo" width="200">
[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGTAmodding%2Fre3%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/GTAmodding/re3/goto?ref=master)
<a href="https://discord.gg/ERYg58ttcE"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
<a href="https://discord.gg/RFNbjsUMGg"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
## Intro
In this repository you'll find the fully reversed source code for GTA III ([master](https://github.com/GTAmodding/re3/tree/master/) branch) and GTA VC ([miami](https://github.com/GTAmodding/re3/tree/miami/) branch).
It has been tested and works on Windows, Linux and FreeBSD, on x86, amd64, arm and arm64.\
It has been tested and works on Windows, Linux, MacOS and FreeBSD, on x86, amd64, arm and arm64.\
Rendering is handled either by original RenderWare (D3D8)
or the reimplementation [librw](https://github.com/aap/librw) (D3D9, OpenGL 2.1 or above, OpenGL ES 2.0 or above).\
Audio is done with MSS (using dlls from original GTA) or OpenAL.
@ -21,13 +21,13 @@ We cannot build for PS2 or Xbox yet. If you're interested in doing so, get in to
## Installation
- re3 requires PC game assets to work, so you **must** own [a copy of GTA III](https://store.steampowered.com/app/12100/Grand_Theft_Auto_III/).
- Build re3 or download the latest nightly build:
- Build re3 or download the latest build:
- [Windows D3D9 MSS 32bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_x86/master/re3_Release_win-x86-librw_d3d9-mss.zip)
- [Windows D3D9 64bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_amd64/master/re3_Release_win-amd64-librw_d3d9-oal.zip)
- [Windows OpenGL 64bit](https://nightly.link/GTAmodding/re3/workflows/re3_msvc_amd64/master/re3_Release_win-amd64-librw_gl3_glfw-oal.zip)
- [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/ubuntu-latest-gl3.zip)
- [MacOS 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/macos-latest-gl3.zip)
- Extract the downloaded zip over your GTA 3 directory and run re3. The zip includes the gamefiles and in case of OpenAL the required dlls.
- [Linux 64bit](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/ubuntu-18.04-gl3.zip)
- [MacOS 64bit x86-64](https://nightly.link/GTAmodding/re3/workflows/build-cmake-conan/master/macos-latest-gl3.zip)
- Extract the downloaded zip over your GTA 3 directory and run re3. The zip includes the binary, updated and additional gamefiles and in case of OpenAL the required dlls.
## Screenshots
@ -85,7 +85,9 @@ The following things would be nice to have/do:
Asset modifications (models, texture, handling, script, ...) should work the same way as with original GTA for the most part.
Mods that make changes to the code (dll/asi, CLEO, limit adjusters) will *not* work.
CLEO scripts work with [CLEO Redux](https://github.com/cleolibrary/CLEO-Redux).
Mods that make changes to the code (dll/asi, limit adjusters) will *not* work.
Some things these mods do are already implemented in re3 (much of SkyGFX, GInput, SilentPatch, Widescreen fix),
others can easily be achieved (increasing limis, see `config.h`),
others will simply have to be rewritten and integrated into the code directly.
@ -115,6 +117,12 @@ conan build .. -if build -bf build -pf package
```
</details>
<details><summary>MacOS Premake</summary>
For MacOS using premake, proceed: [Building on MacOS](https://github.com/GTAmodding/re3/wiki/Building-on-MacOS)
</details>
<details><summary>FreeBSD</summary>
For FreeBSD using premake, proceed: [Building on FreeBSD](https://github.com/GTAmodding/re3/wiki/Building-on-FreeBSD)
@ -132,7 +140,7 @@ Microsoft recently discontinued its downloads of the DX9 SDK. You can download a
**If you choose OpenAL on Windows** You must read [Running OpenAL build on Windows](https://github.com/GTAmodding/re3/wiki/Running-OpenAL-build-on-Windows).
</details>
> :information_source: premake has an `--lto` option if you want the project to be compiled with Link Time Optimization.
> :information_source: premake has an `--with-lto` option if you want the project to be compiled with Link Time Optimization.
> :information_source: There are various settings in [config.h](https://github.com/GTAmodding/re3/tree/master/src/core/config.h), you may want to take a look there.

27
autoconf/LICENSE.txt Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2016 Blizzard Entertainment and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of Premake nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

305
autoconf/api.lua Normal file
View File

@ -0,0 +1,305 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
-- Enhanced by re3
---
local p = premake
local autoconf = p.modules.autoconf
autoconf.cache = {}
autoconf.parameters = ""
---
-- register autoconfigure api.
---
p.api.register {
name = "autoconfigure",
scope = "config",
kind = "table"
}
---
-- Check for a particular include file.
--
-- @cfg : Current config.
-- @variable : The variable to store the result, such as 'HAVE_STDINT_H'.
-- @filename : The header file to check for.
---
function check_include(cfg, variable, filename)
local res = autoconf.cache_compile(cfg, variable, function ()
p.outln('#include <' .. filename .. '>')
p.outln('int main(void) { return 0; }')
end)
if res.value then
autoconf.set_value(cfg, variable, 1)
end
end
---
-- Check for size of a particular type.
--
-- @cfg : Current config.
-- @variable : The variable to use, such as 'SIZEOF_SIZE_T', this method will also add "'HAVE_' .. variable".
-- @type : The type to check.
-- @headers : An optional array of header files to include.
-- @defines : An optional array of defines to define.
---
function check_type_size(cfg, variable, type, headers, defines)
check_include(cfg, 'HAVE_SYS_TYPES_H', 'sys/types.h')
check_include(cfg, 'HAVE_STDINT_H', 'stdint.h')
check_include(cfg, 'HAVE_STDDEF_H', 'stddef.h')
local res = autoconf.cache_compile(cfg, variable .. cfg.platform,
function ()
if cfg.autoconf['HAVE_SYS_TYPES_H'] then
p.outln('#include <sys/types.h>')
end
if cfg.autoconf['HAVE_STDINT_H'] then
p.outln('#include <stdint.h>')
end
if cfg.autoconf['HAVE_STDDEF_H'] then
p.outln('#include <stddef.h>')
end
autoconf.include_defines(defines)
autoconf.include_headers(headers)
p.outln("")
p.outln("#define SIZE (sizeof(" .. type .. "))")
p.outln("char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',")
p.outln(" ('0' + ((SIZE / 10000)%10)),")
p.outln(" ('0' + ((SIZE / 1000)%10)),")
p.outln(" ('0' + ((SIZE / 100)%10)),")
p.outln(" ('0' + ((SIZE / 10)%10)),")
p.outln(" ('0' + (SIZE %10)),")
p.outln(" ']', '\\0'};")
p.outln("")
p.outln("int main(int argc, char *argv[]) {")
p.outln(" int require = 0;")
p.outln(" require += info_size[argc];")
p.outln(" (void)argv;")
p.outln(" return require;")
p.outln("}")
end,
function (e)
-- if the compile step succeeded, we should have a binary with 'INFO:size[*****]'
-- somewhere in there.
local content = io.readfile(e.binary)
if content then
local size = string.find(content, 'INFO:size')
if size then
e.size = tonumber(string.sub(content, size+10, size+14))
end
end
end
)
if res.size then
autoconf.set_value(cfg, 'HAVE_' .. variable, 1)
autoconf.set_value(cfg, variable, res.size)
end
end
---
-- Check if the given struct or class has the specified member variable
--
-- @cfg : current config.
-- @variable : variable to store the result.
-- @type : the name of the struct or class you are interested in
-- @member : the member which existence you want to check
-- @headers : an optional array of header files to include.
-- @defines : An optional array of defines to define.
---
function check_struct_has_member(cfg, variable, type, member, headers, defines)
local res = autoconf.cache_compile(cfg, variable, function ()
autoconf.include_defines(defines)
autoconf.include_headers(headers)
p.outln('int main(void) {')
p.outln(' (void)sizeof(((' .. type .. '*)0)->' .. member ..');')
p.outln(' return 0;')
p.outln('}')
end)
if res.value then
autoconf.set_value(cfg, variable, 1)
end
end
---
-- Check if a symbol exists as a function, variable, or macro
--
-- @cfg : current config.
-- @variable : variable to store the result.
-- @symbol : The symbol to check for.
-- @headers : an optional array of header files to include.
-- @defines : An optional array of defines to define.
---
function check_symbol_exists(cfg, variable, symbol, headers, defines)
local h = headers
local res = autoconf.cache_compile(cfg, variable, function ()
autoconf.include_defines(defines)
autoconf.include_headers(headers)
p.outln('int main(int argc, char** argv) {')
p.outln(' (void)argv;')
p.outln('#ifndef ' .. symbol)
p.outln(' return ((int*)(&' .. symbol .. '))[argc];')
p.outln('#else')
p.outln(' (void)argc;')
p.outln(' return 0;')
p.outln('#endif')
p.outln('}')
end)
if res.value then
autoconf.set_value(cfg, variable, 1)
end
end
---
-- try compiling a piece of c/c++
---
function autoconf.try_compile(cfg, cpp)
local ts = autoconf.toolset(cfg)
if ts then
return ts.try_compile(cfg, cpp, autoconf.parameters)
else
p.warnOnce('autoconf', 'no toolset found, autoconf always failing.')
end
end
function autoconf.cache_compile(cfg, entry, func, post)
if not autoconf.cache[entry] then
local cpp = p.capture(func)
local res = autoconf.try_compile(cfg, cpp)
if res then
local e = { binary = res, value = true }
if post then
post(e)
end
autoconf.cache[entry] = e
else
autoconf.cache[entry] = { }
end
end
return autoconf.cache[entry]
end
---
-- get the current configured toolset, or the default.
---
function autoconf.toolset(cfg)
local ts = p.config.toolset(cfg)
if not ts then
local tools = {
-- Actually we always return nil on msc. see msc.lua
['vs2010'] = p.tools.msc,
['vs2012'] = p.tools.msc,
['vs2013'] = p.tools.msc,
['vs2015'] = p.tools.msc,
['vs2017'] = p.tools.msc,
['vs2019'] = p.tools.msc,
['gmake'] = premake.tools.gcc,
['gmake2'] = premake.tools.gcc,
['codelite'] = premake.tools.gcc,
['xcode4'] = premake.tools.clang,
}
ts = tools[_ACTION]
end
return ts
end
---
-- store the value of the variable in the configuration
---
function autoconf.set_value(cfg, variable, value)
cfg.autoconf[variable] = value
end
---
-- write the cfg.autoconf table to the file
---
function autoconf.writefile(cfg, filename)
if cfg.autoconf then
local file = io.open(filename, "w+")
for variable, value in pairs(cfg.autoconf) do
file:write('#define ' .. variable .. ' ' .. tostring(value) .. (_eol or '\n'))
end
file:close()
end
end
---
-- Utility method to add a table of headers.
---
function autoconf.include_headers(headers)
if headers ~= nil then
if type(headers) == "table" then
for _, v in ipairs(headers) do
p.outln('#include <' .. v .. '>')
end
else
p.outln('#include <' .. headers .. '>')
end
end
end
function autoconf.include_defines(defines)
if defines ~= nil then
if type(defines) == "table" then
for _, v in ipairs(defines) do
p.outln('#define ' .. v)
end
else
p.outln('#define ' .. defines)
end
end
end
---
-- attach ourselfs to the running action.
---
p.override(p.action, 'call', function (base, name)
local a = p.action.get(name)
-- store the old callback.
local onBaseProject = a.onProject or a.onproject
-- override it with our own.
a.onProject = function(prj)
-- go through each configuration, and call the setup configuration methods.
for cfg in p.project.eachconfig(prj) do
cfg.autoconf = {}
if cfg.autoconfigure then
verbosef('Running auto config steps for "%s/%s".', prj.name, cfg.name)
for file, func in pairs(cfg.autoconfigure) do
func(cfg)
if not (file ~= "dontWrite") then
os.mkdir(cfg.objdir)
local filename = path.join(cfg.objdir, file)
autoconf.writefile(cfg, filename)
end
end
end
end
-- then call the old onProject.
if onBaseProject then
onBaseProject(prj)
end
end
-- now call the original action.call methods
base(name)
end)

18
autoconf/autoconf.lua Normal file
View File

@ -0,0 +1,18 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
if not premake.modules.autoconf then
p.modules.autoconf = {}
p.modules.autoconf._VERSION = p._VERSION
verbosef('Loading autoconf module...')
include('api.lua')
include('msc.lua')
include('clang.lua')
include('gcc.lua')
end
return p.modules.autoconf

27
autoconf/clang.lua Normal file
View File

@ -0,0 +1,27 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
local clang = p.tools.clang
function clang.try_compile(cfg, text, parameters)
-- write the text to a temporary file.
local cppFile = path.join(cfg.objdir, "temp.cpp")
if not io.writefile(cppFile, text) then
return nil
end
if parameters == nil then
parameters = ""
end
local outFile = path.join(cfg.objdir, "temp.out")
-- compile that text file.
if os.execute('clang "' .. cppFile .. '" ' .. parameters .. ' -o "' .. outFile ..'" &> /dev/null') then
return outFile
else
return nil
end
end

27
autoconf/gcc.lua Normal file
View File

@ -0,0 +1,27 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
local gcc = p.tools.gcc
function gcc.try_compile(cfg, text, parameters)
-- write the text to a temporary file.
local cppFile = path.join(cfg.objdir, "temp.cpp")
if not io.writefile(cppFile, text) then
return nil
end
if parameters == nil then
parameters = ""
end
local outFile = path.join(cfg.objdir, "temp.out")
-- compile that text file.
if os.execute('gcc "' .. cppFile .. '" ' .. parameters .. ' -o "' .. outFile ..'" &> /dev/null') then
return outFile
else
return nil
end
end

62
autoconf/msc.lua Normal file
View File

@ -0,0 +1,62 @@
---
-- Autoconfiguration.
-- Copyright (c) 2016 Blizzard Entertainment
---
local p = premake
local msc = p.tools.msc
-- "parameters" is unused, matter of fact this file is unused - re3
function msc.try_compile(cfg, text, parameters)
return nil
--[[
-- write the text to a temporary file.
local cppFile = path.join(cfg.objdir, "temp.cpp")
if not io.writefile(cppFile, text) then
return nil
end
-- write out a batch file.
local batch = p.capture(function ()
p.outln('@echo off')
p.outln('SET mypath=%~dp0')
p.outln('pushd %mypath%')
local map = {
vs2010 = 'VS100COMNTOOLS',
vs2012 = 'VS110COMNTOOLS',
vs2013 = 'VS120COMNTOOLS',
vs2015 = 'VS140COMNTOOLS',
vs2017 = 'VS141COMNTOOLS',
vs2019 = 'VS142COMNTOOLS',
}
local a = map[_ACTION]
if a then
a = path.translate(os.getenv(a), '/')
a = path.join(a, '../../VC/vcvarsall.bat')
if cfg.platform == 'x86' then
p.outln('call "' .. a .. '" > NUL')
else
p.outln('call "' .. a .. '" amd64 > NUL')
end
p.outln('cl.exe /nologo temp.cpp > NUL')
else
error('Unsupported Visual Studio version: ' .. _ACTION)
end
end)
local batchFile = path.join(cfg.objdir, "compile.bat")
if not io.writefile(batchFile, batch) then
return nil
end
if os.execute(batchFile) then
return path.join(cfg.objdir, "temp.exe")
else
return nil
end
--]]
end

View File

@ -0,0 +1,38 @@
if(NOT COMMAND nx_generate_nacp)
message(FATAL_ERROR "The `nx_generate_nacp` cmake command is not available. Please use an appropriate Nintendo Switch toolchain.")
endif()
if(NOT COMMAND nx_create_nro)
message(FATAL_ERROR "The `nx_create_nro` cmake command is not available. Please use an appropriate Nintendo Switch toolchain.")
endif()
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
function(re3_platform_target TARGET)
cmake_parse_arguments(RPT "INSTALL" "" "" ${ARGN})
get_target_property(TARGET_TYPE "${TARGET}" TYPE)
if(TARGET_TYPE STREQUAL "EXECUTABLE")
nx_generate_nacp(${TARGET}.nacp
NAME "${TARGET}"
AUTHOR "${${PROJECT}_AUTHOR}"
VERSION "1.0.0-${GIT_SHA1}"
)
nx_create_nro(${TARGET}
NACP ${TARGET}.nacp
ICON "${PROJECT_SOURCE_DIR}/res/images/logo_256.jpg"
)
if(${PROJECT}_INSTALL AND RPT_INSTALL)
get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME)
if(NOT TARGET_OUTPUT_NAME)
set(TARGET_OUTPUT_NAME "${TARGET}")
endif()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_OUTPUT_NAME}.nro"
DESTINATION "."
)
endif()
endif()
endfunction()

Binary file not shown.

15378
codewarrior/re3.mcp.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,7 @@ class Re3Conan(ConanFile):
self.requires("opusfile/0.12")
def export_sources(self):
for d in ("cmake", "src"):
for d in ("cmake", "gamefiles", "src"):
shutil.copytree(src=d, dst=os.path.join(self.export_sources_folder, d))
self.copy("CMakeLists.txt")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -28,10 +28,22 @@ newoption {
}
newoption {
trigger = "lto",
description = "Use link time optimization"
trigger = "with-lto",
description = "Build with link time optimization"
}
newoption {
trigger = "no-git-hash",
description = "Don't print git commit hash into binary"
}
newoption {
trigger = "no-full-paths",
description = "Don't print full paths into binary"
}
require("autoconf")
if(_OPTIONS["with-librw"]) then
Librw = "vendor/librw"
else
@ -58,7 +70,7 @@ end
workspace "re3"
language "C++"
configurations { "Debug", "Release", "Vanilla" }
configurations { "Debug", "Release" }
startproject "re3"
location "build"
symbols "Full"
@ -70,6 +82,7 @@ workspace "re3"
end
filter { "system:windows" }
configurations { "Vanilla" }
platforms {
"win-x86-RW33_d3d8-mss",
"win-x86-librw_d3d9-mss",
@ -105,64 +118,67 @@ workspace "re3"
filter "configurations:Debug"
defines { "DEBUG" }
filter "configurations:not Debug"
defines { "NDEBUG" }
optimize "Speed"
if(_OPTIONS["lto"]) then
if(_OPTIONS["with-lto"]) then
flags { "LinkTimeOptimization" }
end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter { "platforms:win*" }
system "windows"
filter { "platforms:linux*" }
system "linux"
filter { "platforms:bsd*" }
system "bsd"
filter { "platforms:macosx*" }
system "macosx"
filter { "platforms:*x86*" }
architecture "x86"
filter { "platforms:*amd64*" }
architecture "amd64"
filter { "platforms:*arm*" }
architecture "ARM"
filter { "platforms:macosx-arm64-*" }
filter { "platforms:macosx-arm64-*", "files:**.cpp"}
buildoptions { "-target", "arm64-apple-macos11", "-std=gnu++14" }
filter { "platforms:macosx-amd64-*" }
filter { "platforms:macosx-arm64-*", "files:**.c"}
buildoptions { "-target", "arm64-apple-macos11" }
filter { "platforms:macosx-amd64-*", "files:**.cpp"}
buildoptions { "-target", "x86_64-apple-macos10.12", "-std=gnu++14" }
filter { "platforms:macosx-amd64-*", "files:**.c"}
buildoptions { "-target", "x86_64-apple-macos10.12" }
filter { "platforms:*librw_d3d9*" }
defines { "RW_D3D9" }
if(not _OPTIONS["with-librw"]) then
libdirs { path.join(Librw, "lib/win-%{getarch(cfg.architecture)}-d3d9/%{cfg.buildcfg}") }
end
filter "platforms:*librw_gl3_glfw*"
defines { "RW_GL3" }
if(not _OPTIONS["with-librw"]) then
libdirs { path.join(Librw, "lib/%{getsys(cfg.system)}-%{getarch(cfg.architecture)}-gl3/%{cfg.buildcfg}") }
end
filter "platforms:*x86-librw_gl3_glfw*"
includedirs { path.join(_OPTIONS["glfwdir32"], "include") }
filter "platforms:*amd64-librw_gl3_glfw*"
includedirs { path.join(_OPTIONS["glfwdir64"], "include") }
filter {}
function setpaths (gamepath, exepath)
if (gamepath) then
postbuildcommands {
@ -186,7 +202,7 @@ project "librw"
files { path.join(Librw, "src/*.*") }
files { path.join(Librw, "src/*/*.*") }
files { path.join(Librw, "src/gl/*/*.*") }
filter { "platforms:*x86*" }
architecture "x86"
@ -202,16 +218,22 @@ project "librw"
includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" }
filter "platforms:macosx*"
-- Support MacPorts and Homebrew
-- Support MacPorts and Homebrew
filter "platforms:macosx-arm64-*"
includedirs { "/opt/local/include" }
includedirs {"/opt/homebrew/include" }
libdirs { "/opt/local/lib" }
libdirs { "/opt/homebrew/lib" }
filter "platforms:macosx-amd64-*"
includedirs { "/opt/local/include" }
includedirs {"/usr/local/include" }
libdirs { "/opt/local/lib" }
libdirs { "/usr/local/lib" }
filter "platforms:*gl3_glfw*"
staticruntime "off"
filter "platforms:*RW33*"
flags { "ExcludeFromBuild" }
filter {}
@ -244,7 +266,7 @@ project "re3"
files { addSrcFiles("src/modelinfo") }
files { addSrcFiles("src/objects") }
files { addSrcFiles("src/peds") }
files { addSrcFiles("src/render") }
files { addSrcFiles("src/renderer") }
files { addSrcFiles("src/rw") }
files { addSrcFiles("src/save") }
files { addSrcFiles("src/skel") }
@ -253,7 +275,11 @@ project "re3"
files { addSrcFiles("src/vehicles") }
files { addSrcFiles("src/weapons") }
files { addSrcFiles("src/extras") }
files { "src/extras/GitSHA1.cpp" } -- this won't be in repo in first build
if(not _OPTIONS["no-git-hash"]) then
files { "src/extras/GitSHA1.cpp" } -- this won't be in repo in first build
else
removefiles { "src/extras/GitSHA1.cpp" } -- but it will be everytime after
end
includedirs { "src" }
includedirs { "src/animation" }
@ -269,7 +295,7 @@ project "re3"
includedirs { "src/modelinfo" }
includedirs { "src/objects" }
includedirs { "src/peds" }
includedirs { "src/render" }
includedirs { "src/renderer" }
includedirs { "src/rw" }
includedirs { "src/save/" }
includedirs { "src/skel/" }
@ -278,18 +304,25 @@ project "re3"
includedirs { "src/vehicles" }
includedirs { "src/weapons" }
includedirs { "src/extras" }
if(not _OPTIONS["no-git-hash"]) then
defines { "USE_OUR_VERSIONING" }
end
if _OPTIONS["with-opus"] then
includedirs { "vendor/ogg/include" }
includedirs { "vendor/opus/include" }
includedirs { "vendor/opusfile/include" }
end
filter "configurations:Vanilla"
defines { "VANILLA_DEFINES" }
filter "platforms:*mss"
defines { "AUDIO_MSS" }
includedirs { "vendor/milessdk/include" }
libdirs { "vendor/milessdk/lib" }
if _OPTIONS["with-opus"] then
filter "platforms:win*"
libdirs { "vendor/ogg/win32/VS2015/Win32/%{cfg.buildcfg}" }
@ -298,15 +331,15 @@ project "re3"
filter {}
defines { "AUDIO_OPUS" }
end
filter "platforms:*oal"
defines { "AUDIO_OAL" }
filter {}
if(os.getenv("GTA_III_RE_DIR")) then
setpaths(os.getenv("GTA_III_RE_DIR") .. "/", "%(cfg.buildtarget.name)")
end
filter "platforms:win*"
files { addSrcFiles("src/skel/win") }
includedirs { "src/skel/win" }
@ -314,44 +347,71 @@ project "re3"
linkoptions "/SAFESEH:NO"
characterset ("MBCS")
targetextension ".exe"
if(_OPTIONS["no-full-paths"]) then
usefullpaths "off"
linkoptions "/PDBALTPATH:%_PDB%"
end
if(_OPTIONS["with-librw"]) then
-- external librw is dynamic
staticruntime "on"
end
prebuildcommands { '"%{prj.location}..\\printHash.bat" "%{prj.location}..\\src\\extras\\GitSHA1.cpp"' }
if(not _OPTIONS["no-git-hash"]) then
prebuildcommands { '"%{prj.location}..\\printHash.bat" "%{prj.location}..\\src\\extras\\GitSHA1.cpp"' }
end
filter "platforms:not win*"
prebuildcommands { '"%{prj.location}/../printHash.sh" "%{prj.location}/../src/extras/GitSHA1.cpp"' }
if(not _OPTIONS["no-git-hash"]) then
prebuildcommands { '"%{prj.location}/../printHash.sh" "%{prj.location}/../src/extras/GitSHA1.cpp"' }
end
filter "platforms:win*glfw*"
staticruntime "off"
filter "platforms:*glfw*"
premake.modules.autoconf.parameters = "-lglfw -lX11"
autoconfigure {
-- iterates all configs and runs on them
["dontWrite"] = function (cfg)
check_symbol_exists(cfg, "haveX11", "glfwGetX11Display", { "X11/Xlib.h", "X11/XKBlib.h", "GLFW/glfw3.h", "GLFW/glfw3native.h" }, "GLFW_EXPOSE_NATIVE_X11")
if cfg.autoconf["haveX11"] ~= nil and cfg.autoconf["haveX11"] == 1 then
table.insert(cfg.links, "X11")
table.insert(cfg.defines, "GET_KEYBOARD_INPUT_FROM_X11")
end
end
}
filter "platforms:win*oal"
includedirs { "vendor/openal-soft/include" }
includedirs { "vendor/libsndfile/include" }
includedirs { "vendor/mpg123/include" }
filter "platforms:win-x86*oal"
libdirs { "vendor/mpg123/lib/Win32" }
libdirs { "vendor/libsndfile/lib/Win32" }
libdirs { "vendor/openal-soft/libs/Win32" }
filter "platforms:win-amd64*oal"
libdirs { "vendor/mpg123/lib/Win64" }
libdirs { "vendor/libsndfile/lib/Win64" }
libdirs { "vendor/openal-soft/libs/Win64" }
filter "platforms:linux*oal"
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:bsd*oal"
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:macosx*oal"
links { "openal", "mpg123", "sndfile", "pthread" }
filter "platforms:macosx-arm64-*oal"
includedirs { "/opt/homebrew/opt/openal-soft/include" }
libdirs { "/opt/homebrew/opt/openal-soft/lib" }
filter "platforms:macosx-amd64-*oal"
includedirs { "/usr/local/opt/openal-soft/include" }
libdirs { "/usr/local/opt/openal-soft/lib" }
if _OPTIONS["with-opus"] then
filter {}
links { "libogg" }
@ -365,7 +425,7 @@ project "re3"
links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtcharse", "rpanisot" }
defines { "RWLIBS" }
linkoptions "/SECTION:_rwcseg,ER!W /MERGE:_rwcseg=.text"
filter "platforms:*librw*"
defines { "LIBRW" }
files { addSrcFiles("src/fakerw") }
@ -379,31 +439,39 @@ project "re3"
filter "platforms:*d3d9*"
defines { "USE_D3D9" }
links { "d3d9" }
filter "platforms:*x86*d3d*"
includedirs { "sdk/dx8sdk/include" }
libdirs { "sdk/dx8sdk/lib" }
filter "platforms:win-x86*gl3_glfw*"
libdirs { path.join(_OPTIONS["glfwdir32"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
links { "opengl32", "glfw3" }
filter "platforms:win-amd64*gl3_glfw*"
libdirs { path.join(_OPTIONS["glfwdir64"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
links { "opengl32", "glfw3" }
filter "platforms:linux*gl3_glfw*"
links { "GL", "glfw" }
filter "platforms:bsd*gl3_glfw*"
links { "GL", "glfw", "sysinfo" }
includedirs { "/usr/local/include" }
libdirs { "/usr/local/lib" }
filter "platforms:macosx*gl3_glfw*"
filter "platforms:macosx-arm64-*gl3_glfw*"
links { "glfw" }
linkoptions { "-framework OpenGL" }
includedirs { "/opt/local/include" }
includedirs { "/usr/local/include" }
includedirs {"/opt/homebrew/include" }
libdirs { "/opt/local/lib" }
libdirs { "/opt/homebrew/lib" }
filter "platforms:macosx-amd64-*gl3_glfw*"
links { "glfw" }
linkoptions { "-framework OpenGL" }
includedirs { "/opt/local/include" }
includedirs {"/usr/local/include" }
libdirs { "/opt/local/lib" }
libdirs { "/usr/local/lib" }

View File

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

View File

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

BIN
res/images/logo_256.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -39,7 +39,7 @@ target_compile_definitions(${EXECUTABLE}
PRIVATE
$<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG>
LIBRW
${PROJECT}_NO_AUTOLINK
CMAKE_NO_AUTOLINK
)
if(LIBRW_PLATFORM_D3D9)
@ -50,12 +50,17 @@ if(LIBRW_PLATFORM_D3D9)
endif()
target_compile_definitions(${EXECUTABLE} PRIVATE CMAKE_BUILD)
target_compile_definitions(${EXECUTABLE} PRIVATE USE_OUR_VERSIONING)
if(${PROJECT}_AUDIO STREQUAL "OAL")
find_package(OpenAL REQUIRED)
target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
if(TARGET OpenAL::OpenAL)
target_link_libraries(${EXECUTABLE} PRIVATE OpenAL::OpenAL)
else()
target_include_directories(${EXECUTABLE} PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE} PRIVATE ${OPENAL_LIBRARY})
target_compile_definitions(${EXECUTABLE} PRIVATE ${OPENAL_DEFINITIONS})
endif()
target_compile_definitions(${EXECUTABLE} PRIVATE AUDIO_OAL)
elseif(${PROJECT}_AUDIO STREQUAL "MSS")
find_package(MilesSDK REQUIRED)
@ -119,13 +124,35 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
)
endif()
if(NINTENDO_SWITCH)
set(${PROJECT}_C_CXX_EXTENSIONS ON)
else()
set(${PROJECT}_C_CXX_EXTENSIONS OFF)
endif()
if(LIBRW_PLATFORM_GL3 AND LIBRW_GL3_GFXLIB STREQUAL "GLFW")
include(CheckSymbolExists)
set(CMAKE_REQUIRED_LIBRARIES glfw)
set(CMAKE_REQUIRED_DEFINITIONS -DGLFW_EXPOSE_NATIVE_X11)
check_symbol_exists(glfwGetX11Display "GLFW/glfw3.h;GLFW/glfw3native.h" GLFW_HAS_X11)
unset(CMAKE_REQUIRED_DEFINITIONS)
unset(CMAKE_REQUIRED_LIBRARIES)
if (GLFW_HAS_X11)
find_package(X11 REQUIRED)
target_link_libraries(${EXECUTABLE} PRIVATE X11::X11)
target_compile_definitions(${EXECUTABLE} PRIVATE GET_KEYBOARD_INPUT_FROM_X11)
endif (GLFW_HAS_X11)
endif()
set_target_properties(${EXECUTABLE}
PROPERTIES
C_STANDARD 11
C_EXTENSIONS OFF
C_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
C_STANDARD_REQUIRED ON
CXX_STANDARD 11
CXX_EXTENSIONS OFF
CXX_EXTENSIONS ${${PROJECT}_C_CXX_EXTENSIONS}
CXX_STANDARD_REQUIRED ON
)
@ -139,3 +166,5 @@ if(${PROJECT}_INSTALL)
install(FILES $<TARGET_PDB_FILE:${EXECUTABLE}> DESTINATION "." OPTIONAL)
endif()
endif()
re3_platform_target(${EXECUTABLE} INSTALL)

View File

@ -35,7 +35,7 @@ public:
CAnimBlendLink link;
int numNodes; // taken from CAnimBlendClumpData::numFrames
int32 numNodes; // taken from CAnimBlendClumpData::numFrames
// NB: Order of these depends on order of nodes in Clump this was built from
CAnimBlendNode *nodes;
CAnimBlendHierarchy *hierarchy;

View File

@ -3,7 +3,6 @@
#include "AnimBlendClumpData.h"
#include "MemoryMgr.h"
CAnimBlendClumpData::CAnimBlendClumpData(void)
{
numFrames = 0;

View File

@ -8,29 +8,46 @@
#include "SurfaceTable.h"
#include "sampman.h"
const int CollisionSoundIntensity = 60;
cAudioCollisionManager::cAudioCollisionManager()
void
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
float velocity)
{
m_sQueue.m_pEntity1 = nil;
m_sQueue.m_pEntity2 = nil;
m_sQueue.m_bSurface1 = SURFACE_DEFAULT;
m_sQueue.m_bSurface2 = SURFACE_DEFAULT;
m_sQueue.m_fIntensity2 = 0.0f;
m_sQueue.m_fIntensity1 = 0.0f;
m_sQueue.m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
float distSquared;
CVector v1;
CVector v2;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_bIsPaused ||
(velocity < 0.0016f && collisionPower < 0.01f))
return;
m_bCollisionsInQueue = 0;
if(entity1->IsBuilding()) {
v1 = v2 = entity2->GetPosition();
} else if(entity2->IsBuilding()) {
v1 = v2 = entity1->GetPosition();
} else {
v1 = entity1->GetPosition();
v2 = entity2->GetPosition();
}
CVector pos = (v1 + v2) * 0.5f;
distSquared = GetDistanceSquared(pos);
if(distSquared < SQR(COLLISION_MAX_DIST)) {
m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
m_sCollisionManager.m_sQueue.m_vecPosition = pos;
m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
m_sCollisionManager.AddCollisionToRequestedQueue();
}
}
void
cAudioCollisionManager::AddCollisionToRequestedQueue()
{
int32 collisionsIndex;
int32 i;
uint32 collisionsIndex;
uint32 i;
if (m_bCollisionsInQueue < NUMAUDIOCOLLISIONS)
@ -55,137 +72,72 @@ cAudioCollisionManager::AddCollisionToRequestedQueue()
m_bIndicesTable[i] = collisionsIndex;
}
float
cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const
{
return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
}
float
cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const
{
float result;
switch(a) {
case SURFACE_DEFAULT:
case SURFACE_TARMAC:
case SURFACE_PAVEMENT:
case SURFACE_STEEP_CLIFF:
case SURFACE_TRANSPARENT_STONE: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
case SURFACE_GRASS:
case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
case SURFACE_GRAVEL: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
case SURFACE_MUD_DRY: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break;
case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
case SURFACE_SCAFFOLD_POLE:
case SURFACE_METAL_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break;
case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
case SURFACE_WATER: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
case SURFACE_RUBBER:
case SURFACE_WHEELBASE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break;
case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break;
case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
case SURFACE_NEWS_VENDOR: result = GetCollisionRatio(b, 0.f, 5.f, 5.f); break;
default: result = 0.f; break;
}
return result;
}
float
cAudioManager::GetCollisionRatio(float a, float b, float c, float d) const
{
float e;
e = a;
if(a <= b) return 0.0f;
if(c <= a) e = c;
return (e - b) / d;
}
uint32
cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
{
uint8 surface1 = audioCollision.m_bSurface1;
uint8 surface2 = audioCollision.m_bSurface2;
int32 vol;
float ratio;
if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
surface2 == SURFACE_HEDGE) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
vol = 30.f * ratio;
} else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY ||
surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) {
return 0;
} else {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
vol = 40.f * ratio;
}
if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2;
return vol;
}
void
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
cAudioManager::ServiceCollisions()
{
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
m_sQueueSample.m_nVolume =
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) {
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nReleasingVolumeModificator = 7;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart =
SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd =
SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_nReleasingVolumeDivider = 5;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
int i, j;
bool8 abRepeatedCollision1[NUMAUDIOCOLLISIONS];
bool8 abRepeatedCollision2[NUMAUDIOCOLLISIONS];
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
abRepeatedCollision1[i] = abRepeatedCollision2[i] = FALSE;
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
) {
abRepeatedCollision1[index] = TRUE;
abRepeatedCollision2[j] = TRUE;
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
break;
}
}
}
for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
if (!abRepeatedCollision2[i]) {
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
}
}
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if (!abRepeatedCollision1[index]) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
if (!abRepeatedCollision2[j]) {
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
break;
}
}
SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]);
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
}
}
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_sCollisionManager.m_bCollisionsInQueue = 0;
}
static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
static const uint32 gOneShotCol[] = {SFX_COL_TARMAC_1,
SFX_COL_TARMAC_1,
SFX_COL_GRASS_1,
SFX_COL_GRAVEL_1,
@ -222,11 +174,10 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
void
cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
{
uint16 s1;
uint16 s2;
int16 s1;
int16 s2;
int32 emittingVol;
uint32 emittingVol;
float ratio;
static uint16 counter = 28;
@ -245,12 +196,12 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
s1 = SURFACE_CAR_PANEL;
ratio = Min(1.f, 2.f * ratio);
}
emittingVol = 40.f * ratio;
emittingVol = 40 * ratio;
if(emittingVol) {
m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
m_sQueueSample.m_nVolume =
ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) {
ComputeVolume(emittingVol, COLLISION_MAX_DIST, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume > 0) {
m_sQueueSample.m_nSampleIndex = gOneShotCol[s1];
switch(m_sQueueSample.m_nSampleIndex) {
case SFX_COL_TARMAC_1:
@ -307,17 +258,16 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
if(counter >= 255) counter = 28;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nReleasingVolumeModificator = 11;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nPriority = 11;
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
SET_EMITTING_VOLUME(emittingVol);
RESET_LOOP_OFFSETS
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = CollisionSoundIntensity;
m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
m_sQueueSample.m_MaxDistance = COLLISION_MAX_DIST;
m_sQueueSample.m_bStatic = TRUE;
m_sQueueSample.m_bReverb = TRUE;
SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue();
}
}
@ -325,101 +275,127 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
}
void
cAudioManager::ServiceCollisions()
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{
int i, j;
bool abRepeatedCollision1[NUMAUDIOCOLLISIONS];
bool abRepeatedCollision2[NUMAUDIOCOLLISIONS];
m_sQueueSample.m_nEntityIndex = m_nCollisionEntity;
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
abRepeatedCollision1[i] = abRepeatedCollision2[i] = false;
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if ((m_sCollisionManager.m_asCollisions1[index].m_pEntity1 == m_sCollisionManager.m_asCollisions2[j].m_pEntity1)
&& (m_sCollisionManager.m_asCollisions1[index].m_pEntity2 == m_sCollisionManager.m_asCollisions2[j].m_pEntity2)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface1 == m_sCollisionManager.m_asCollisions2[j].m_bSurface1)
&& (m_sCollisionManager.m_asCollisions1[index].m_bSurface2 == m_sCollisionManager.m_asCollisions2[j].m_bSurface2)
) {
abRepeatedCollision1[index] = true;
abRepeatedCollision2[j] = true;
m_sCollisionManager.m_asCollisions1[index].m_nBaseVolume = ++m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume;
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
break;
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
m_sQueueSample.m_nVolume =
ComputeVolume(emittingVol, COLLISION_MAX_DIST, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume > 0) {
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = FALSE;
m_sQueueSample.m_nPriority = 7;
m_sQueueSample.m_nLoopCount = 0;
SET_EMITTING_VOLUME(emittingVol);
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_MaxDistance = COLLISION_MAX_DIST;
m_sQueueSample.m_bStatic = FALSE;
m_sQueueSample.m_nFramesToPlay = 5;
m_sQueueSample.m_bReverb = TRUE;
SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue();
}
}
}
for (i = 0; i < NUMAUDIOCOLLISIONS; i++) {
if (!abRepeatedCollision2[i]) {
m_sCollisionManager.m_asCollisions2[i].m_pEntity1 = nil;
m_sCollisionManager.m_asCollisions2[i].m_pEntity2 = nil;
m_sCollisionManager.m_asCollisions2[i].m_bSurface1 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_bSurface2 = SURFACE_DEFAULT;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity2 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_fIntensity1 = 0.0f;
m_sCollisionManager.m_asCollisions2[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
m_sCollisionManager.m_asCollisions2[i].m_fDistance = 0.0f;
}
}
for (i = 0; i < m_sCollisionManager.m_bCollisionsInQueue; i++) {
int index = m_sCollisionManager.m_bIndicesTable[i];
if (!abRepeatedCollision1[index]) {
for (j = 0; j < NUMAUDIOCOLLISIONS; j++) {
if (!abRepeatedCollision2[j]) {
m_sCollisionManager.m_asCollisions2[j].m_nBaseVolume = 1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity1 = m_sCollisionManager.m_asCollisions1[index].m_pEntity1;
m_sCollisionManager.m_asCollisions2[j].m_pEntity2 = m_sCollisionManager.m_asCollisions1[index].m_pEntity2;
m_sCollisionManager.m_asCollisions2[j].m_bSurface1 = m_sCollisionManager.m_asCollisions1[index].m_bSurface1;
m_sCollisionManager.m_asCollisions2[j].m_bSurface2 = m_sCollisionManager.m_asCollisions1[index].m_bSurface2;
break;
}
}
SetUpOneShotCollisionSound(m_sCollisionManager.m_asCollisions1[index]);
SetUpLoopingCollisionSound(m_sCollisionManager.m_asCollisions1[index], j);
}
}
for (int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_sCollisionManager.m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_sCollisionManager.m_bCollisionsInQueue = 0;
}
void
cAudioManager::ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower,
float velocity)
uint32
cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision)
{
float distSquared;
CVector v1;
CVector v2;
uint8 surface1 = audioCollision.m_bSurface1;
uint8 surface2 = audioCollision.m_bSurface2;
int32 vol;
float ratio;
if(!m_bIsInitialised || m_nCollisionEntity < 0 || m_nUserPause ||
(velocity < 0.0016f && collisionPower < 0.01f))
return;
if(entity1->IsBuilding()) {
v1 = v2 = entity2->GetPosition();
} else if(entity2->IsBuilding()) {
v1 = v2 = entity1->GetPosition();
if(surface1 == SURFACE_GRASS || surface2 == SURFACE_GRASS || surface1 == SURFACE_HEDGE ||
surface2 == SURFACE_HEDGE) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_RAIN;
m_sQueueSample.m_nFrequency = 13000.f * ratio + 35000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_WATER || surface2 == SURFACE_WATER) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
vol = 30.f * ratio;
} else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY ||
surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
vol = 50.f * ratio;
} else if(surface1 == SURFACE_PED || surface2 == SURFACE_PED) {
return 0;
} else {
v1 = entity1->GetPosition();
v2 = entity2->GetPosition();
}
CVector pos = (v1 + v2) * 0.5f;
distSquared = GetDistanceSquared(pos);
if(distSquared < SQR(CollisionSoundIntensity)) {
m_sCollisionManager.m_sQueue.m_pEntity1 = entity1;
m_sCollisionManager.m_sQueue.m_pEntity2 = entity2;
m_sCollisionManager.m_sQueue.m_bSurface1 = surface1;
m_sCollisionManager.m_sQueue.m_bSurface2 = surface2;
m_sCollisionManager.m_sQueue.m_fIntensity1 = collisionPower;
m_sCollisionManager.m_sQueue.m_fIntensity2 = velocity;
m_sCollisionManager.m_sQueue.m_vecPosition = pos;
m_sCollisionManager.m_sQueue.m_fDistance = distSquared;
m_sCollisionManager.AddCollisionToRequestedQueue();
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_SCRAPE_CAR_1;
m_sQueueSample.m_nFrequency = 10000.f * ratio + 10000;
vol = 40.f * ratio;
}
if(audioCollision.m_nBaseVolume < 2) vol = audioCollision.m_nBaseVolume * vol / 2;
return vol;
}
float
cAudioManager::GetCollisionOneShotRatio(uint32 a, float b)
{
switch(a) {
case SURFACE_DEFAULT:
case SURFACE_TARMAC:
case SURFACE_PAVEMENT:
case SURFACE_STEEP_CLIFF:
case SURFACE_TRANSPARENT_STONE: return GetCollisionRatio(b, 10.f, 60.f, 50.f);
case SURFACE_GRASS:
case SURFACE_CARDBOARDBOX:
case SURFACE_GRAVEL:
case SURFACE_MUD_DRY: return GetCollisionRatio(b, 0.f, 2.f, 2.f);
case SURFACE_CAR: return GetCollisionRatio(b, 6.f, 50.f, 44.f);
case SURFACE_GLASS:
case SURFACE_METAL_CHAIN_FENCE: return GetCollisionRatio(b, 0.1f, 10.f, 9.9f);
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_THICK_METAL_PLATE: return GetCollisionRatio(b, 30.f, 130.f, 100.f);
case SURFACE_GARAGE_DOOR: return GetCollisionRatio(b, 20.f, 100.f, 80.f);
case SURFACE_CAR_PANEL: return GetCollisionRatio(b, 0.f, 4.f, 4.f);
case SURFACE_SCAFFOLD_POLE:
case SURFACE_METAL_GATE:
case SURFACE_LAMP_POST: return GetCollisionRatio(b, 1.f, 10.f, 9.f);
case SURFACE_FIRE_HYDRANT: return GetCollisionRatio(b, 1.f, 15.f, 14.f);
case SURFACE_GIRDER: return GetCollisionRatio(b, 8.f, 50.f, 42.f);
case SURFACE_PED: return GetCollisionRatio(b, 0.f, 20.f, 20.f);
case SURFACE_SAND:
case SURFACE_WATER:
case SURFACE_RUBBER:
case SURFACE_WHEELBASE: return GetCollisionRatio(b, 0.f, 10.f, 10.f);
case SURFACE_WOOD_CRATES: return GetCollisionRatio(b, 1.f, 4.f, 3.f);
case SURFACE_WOOD_BENCH: return GetCollisionRatio(b, 0.1f, 5.f, 4.9f);
case SURFACE_WOOD_SOLID: return GetCollisionRatio(b, 0.1f, 40.f, 39.9f);
case SURFACE_PLASTIC: return GetCollisionRatio(b, 0.1f, 4.f, 3.9f);
case SURFACE_HEDGE: return GetCollisionRatio(b, 0.f, 0.5f, 0.5f);
case SURFACE_CONTAINER: return GetCollisionRatio(b, 4.f, 40.f, 36.f);
case SURFACE_NEWS_VENDOR: return GetCollisionRatio(b, 0.f, 5.f, 5.f);
default: break;
}
return 0.f;
}
float
cAudioManager::GetCollisionLoopingRatio(uint32 a, uint32 b, float c)
{
return GetCollisionRatio(c, 0.0f, 0.02f, 0.02f);
}
float
cAudioManager::GetCollisionRatio(float a, float b, float c, float d)
{
float e;
e = a;
if(a <= b) return 0.0f;
if(c <= a) e = c;
return (e - b) / d;
}

View File

@ -17,7 +17,18 @@ public:
float m_fDistance;
int32 m_nBaseVolume;
// no methods
cAudioCollision() { Reset(); }
void Reset()
{
m_pEntity1 = nil;
m_pEntity2 = nil;
m_bSurface1 = 0;
m_bSurface2 = 0;
m_fIntensity1 = m_fIntensity2 = 0.0f;
m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
m_fDistance = 0.0f;
}
};
VALIDATE_SIZE(cAudioCollision, 40);
@ -31,7 +42,15 @@ public:
uint8 m_bCollisionsInQueue;
cAudioCollision m_sQueue;
cAudioCollisionManager();
cAudioCollisionManager()
{
m_sQueue.Reset();
for(int i = 0; i < NUMAUDIOCOLLISIONS; i++)
m_bIndicesTable[i] = NUMAUDIOCOLLISIONS;
m_bCollisionsInQueue = 0;
}
void AddCollisionToRequestedQueue();
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,37 +2,71 @@
#include "audio_enums.h"
#include "AudioCollision.h"
#include "PoliceRadio.h"
#include "PolRadio.h"
class tSound
{
public:
int32 m_nEntityIndex;
int32 m_nCounter;
int32 m_nSampleIndex;
uint8 m_nBankIndex;
bool m_bIs2D;
int32 m_nReleasingVolumeModificator;
uint32 m_nFrequency;
uint8 m_nVolume;
float m_fDistance;
int32 m_nLoopCount;
int32 m_nLoopStart;
int32 m_nEntityIndex; // audio entity index
#if GTA_VERSION >= GTA3_PC_10
uint32 m_nCounter; // I'm not sure what this is but it looks like a virtual counter to determine the same sound in queue
// Values higher than 255 are used by reflections
#else
uint8 m_nCounter;
#endif
uint32 m_nSampleIndex; // An index of sample from AudioSamples.h
uint8 m_nBankIndex; // A sound bank index. IDK what's the point of it here since samples are hardcoded anyway
bool8 m_bIs2D; // If TRUE then sound is played in 2D space (such as frontend or police radio)
uint32 m_nPriority; // The multiplier for the sound priority (see m_nFinalPriority below). Lesser value means higher priority
uint32 m_nFrequency; // Sound frequency, plain and simple
uint8 m_nVolume; // Sound volume (0..127), only used as an actual volume without EXTERNAL_3D_SOUND (see m_nEmittingVolume)
float m_fDistance; // Distance to camera (useless if m_bIs2D == TRUE)
uint32 m_nLoopCount; // 0 - always loop, 1 - don't loop, other values never seen
#ifndef GTA_PS2
// Loop offsets
uint32 m_nLoopStart;
int32 m_nLoopEnd;
uint8 m_nEmittingVolume;
float m_fSpeedMultiplier;
float m_fSoundIntensity;
bool m_bReleasingSoundFlag;
CVector m_vecPos;
bool m_bReverbFlag;
uint8 m_nLoopsRemaining;
bool m_bRequireReflection; // Used for oneshots
uint8 m_nOffset;
int32 m_nReleasingVolumeDivider;
bool m_bIsProcessed;
bool m_bLoopEnded;
int32 m_nCalculatedVolume;
int8 m_nVolumeChange;
#endif
#ifdef EXTERNAL_3D_SOUND
uint8 m_nEmittingVolume; // The volume in 3D space, provided to 3D audio engine
#endif
float m_fSpeedMultiplier; // Used for doppler effect. 0.0f - unaffected by doppler
#if GTA_VERSION >= GTA3_PC_10
float m_MaxDistance; // The maximum distance at which sound could be heard. Minimum distance = MaxDistance / 5 or MaxDistance / 4 in case of emitting volume (useless if m_bIs2D == TRUE)
#else
uint32 m_MaxDistance;
#endif
bool8 m_bStatic; // If TRUE then sound parameters cannot be changed during playback (frequency, position, etc.)
CVector m_vecPos; // Position of sound in 3D space. Unused if m_bIs2D == TRUE
bool8 m_bReverb; // Toggles reverb effect
#ifdef AUDIO_REFLECTIONS
uint8 m_nReflectionDelay; // Number of frames before reflection could be played. This is calculated internally by AudioManager and shouldn't be set by queued sample
bool8 m_bReflections; // Add sound reflections
#endif
uint8 m_nPan; // Sound panning (0-127). Controls the volume of the playback coming from left and right speaker. Calculated internally unless m_bIs2D==TRUE.
// 0 = L 100% R 0%
// 63 = L 100% R 100%
// 127 = L 0% R 100%
#ifndef FIX_BUGS
uint32 m_nFramesToPlay; // Number of frames the sound would be played (if it stops being queued).
// This one is being set by queued sample for looping sounds, otherwise calculated inside AudioManager
#else
float m_nFramesToPlay; // Made into float for high fps fix
#endif
// all fields below are internal to AudioManager calculations and aren't set by queued sample
bool8 m_bIsBeingPlayed; // Set to TRUE when the sound was added or changed on current frame to avoid it being overwritten
bool8 m_bIsPlayingFinished; // Not sure about the name. Set to TRUE when sampman channel becomes free
#if GTA_VERSION < GTA3_PC_10
int32 unk; // (inherited from GTA 2) Only on PS2, used by static non-looped sounds (AFAIK)
// Looks like it's keeping a number of frames left to play with the purpose of setting m_bIsPlayingFinished=TRUE once value reaches 0
// Default value is -3 for whatever reason
#endif
uint32 m_nFinalPriority; // Actual value used to compare priority, calculated using volume and m_nPriority. Lesser value means higher priority
int8 m_nVolumeChange; // How much m_nVolume should reduce per each frame.
#if defined(FIX_BUGS) && defined(EXTERNAL_3D_SOUND)
int8 m_nEmittingVolumeChange; // same as above but for m_nEmittingVolume
#endif
};
VALIDATE_SIZE(tSound, 92);
@ -45,8 +79,8 @@ class tAudioEntity
public:
eAudioType m_nType;
void *m_pEntity;
bool m_bIsUsed;
uint8 m_bStatus;
bool8 m_bIsUsed;
bool8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents;
@ -57,12 +91,15 @@ VALIDATE_SIZE(tAudioEntity, 40);
class tPedComment
{
public:
int32 m_nSampleIndex;
uint32 m_nSampleIndex;
int32 m_nEntityIndex;
CVector m_vecPos;
float m_fDistance;
uint8 m_bVolume;
int8 m_nProcess;
uint8 m_nVolume;
int8 m_nLoadingTimeout; // how many iterations we gonna wait until dropping the sample if it's still not loaded (only useful on PS2)
#if defined(EXTERNAL_3D_SOUND) && defined(FIX_BUGS)
uint8 m_nEmittingVolume;
#endif
};
VALIDATE_SIZE(tPedComment, 28);
@ -70,22 +107,22 @@ VALIDATE_SIZE(tPedComment, 28);
class cPedComments
{
public:
tPedComment m_asPedComments[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS];
uint8 m_nIndexMap[NUM_PED_COMMENTS_BANKS][NUM_PED_COMMENTS_SLOTS];
uint8 m_nCommentsInBank[NUM_PED_COMMENTS_BANKS];
uint8 m_nActiveBank;
tPedComment m_aPedCommentQueue[NUM_SOUND_QUEUES][NUM_PED_COMMENTS_SLOTS];
uint8 m_aPedCommentOrderList[NUM_SOUND_QUEUES][NUM_PED_COMMENTS_SLOTS];
uint8 m_nPedCommentCount[NUM_SOUND_QUEUES];
uint8 m_nActiveQueue;
cPedComments()
{
for (int i = 0; i < NUM_PED_COMMENTS_SLOTS; i++)
for (int j = 0; j < NUM_PED_COMMENTS_BANKS; j++) {
m_asPedComments[j][i].m_nProcess = -1;
m_nIndexMap[j][i] = NUM_PED_COMMENTS_SLOTS;
for (int j = 0; j < NUM_SOUND_QUEUES; j++) {
m_aPedCommentQueue[j][i].m_nLoadingTimeout = -1;
m_aPedCommentOrderList[j][i] = NUM_PED_COMMENTS_SLOTS;
}
for (int i = 0; i < NUM_PED_COMMENTS_BANKS; i++)
m_nCommentsInBank[i] = 0;
m_nActiveBank = 0;
for (int i = 0; i < NUM_SOUND_QUEUES; i++)
m_nPedCommentCount[i] = 0;
m_nActiveQueue = 0;
}
void Add(tPedComment *com);
void Process();
@ -93,22 +130,6 @@ public:
VALIDATE_SIZE(cPedComments, 1164);
class CEntity;
class cMissionAudio
{
public:
CVector m_vecPos;
bool m_bPredefinedProperties;
int32 m_nSampleIndex;
uint8 m_nLoadingStatus;
uint8 m_nPlayStatus;
bool m_bIsPlaying;
int32 m_nMissionAudioCounter;
bool m_bIsPlayed;
};
VALIDATE_SIZE(cMissionAudio, 32);
// name made up
class cAudioScriptObjectManager
{
@ -122,6 +143,7 @@ public:
class cTransmission;
class CEntity;
class CPlane;
class CVehicle;
class CPed;
@ -129,7 +151,7 @@ class CPed;
class cPedParams
{
public:
bool m_bDistanceCalculated;
bool8 m_bDistanceCalculated;
float m_fDistance;
CPed *m_pPed;
@ -144,11 +166,11 @@ public:
class cVehicleParams
{
public:
bool m_bDistanceCalculated;
bool8 m_bDistanceCalculated;
float m_fDistance;
CVehicle *m_pVehicle;
cTransmission *m_pTransmission;
int32 m_nIndex;
uint32 m_nIndex;
float m_fVelocityChange;
cVehicleParams()
@ -181,325 +203,385 @@ enum {
MAX_REFLECTIONS,
};
enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_LOADING };
class cAudioManager
{
public:
bool m_bIsInitialised;
bool m_bReverb; // unused
bool m_bFifthFrameFlag;
bool8 m_bIsInitialised;
bool8 m_bIsSurround; // unused until VC
bool8 m_bReduceReleasingPriority;
uint8 m_nActiveSamples;
uint8 field_4; // unused
bool m_bDynamicAcousticModelingStatus;
bool8 m_bDoubleVolume; // unused
#if GTA_VERSION >= GTA3_PC_10
bool8 m_bDynamicAcousticModelingStatus;
#endif
float m_fSpeedOfSound;
bool m_bTimerJustReset;
int32 m_nTimer;
bool8 m_bTimerJustReset;
uint32 m_nTimer;
tSound m_sQueueSample;
uint8 m_nActiveSampleQueue;
tSound m_asSamples[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_abSampleQueueIndexTable[NUM_SOUNDS_SAMPLES_BANKS][NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_SampleRequestQueuesStatus[NUM_SOUNDS_SAMPLES_BANKS];
tSound m_asActiveSamples[NUM_SOUNDS_SAMPLES_SLOTS];
uint8 m_nActiveQueue;
tSound m_aRequestedQueue[NUM_SOUND_QUEUES][NUM_CHANNELS_GENERIC];
uint8 m_aRequestedOrderList[NUM_SOUND_QUEUES][NUM_CHANNELS_GENERIC];
uint8 m_nRequestedCount[NUM_SOUND_QUEUES];
tSound m_asActiveSamples[NUM_CHANNELS_GENERIC];
tAudioEntity m_asAudioEntities[NUM_AUDIOENTITIES];
int32 m_anAudioEntityIndices[NUM_AUDIOENTITIES];
int32 m_nAudioEntitiesTotal;
CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS];
float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS];
uint32 m_aAudioEntityOrderList[NUM_AUDIOENTITIES];
uint32 m_nAudioEntitiesCount;
#ifdef AUDIO_REFLECTIONS
CVector m_avecReflectionsPos[MAX_REFLECTIONS];
float m_afReflectionsDistances[MAX_REFLECTIONS];
#endif
cAudioScriptObjectManager m_sAudioScriptObjectManager;
cPedComments m_sPedComments;
int32 m_nFireAudioEntity;
int32 m_nWaterCannonEntity;
int32 m_nPoliceChannelEntity;
cPoliceRadioQueue m_sPoliceRadioQueue;
cAMCrime m_aCrimes[10];
int32 m_nFrontEndEntity;
int32 m_nCollisionEntity;
cAudioCollisionManager m_sCollisionManager;
int32 m_nProjectileEntity;
int32 m_nBridgeEntity;
cMissionAudio m_sMissionAudio;
// Mission audio stuff
CVector m_vecMissionAudioPosition;
bool8 m_bIsMissionAudio2D;
uint32 m_nMissionAudioSampleIndex;
uint8 m_nMissionAudioLoadingStatus;
uint8 m_nMissionAudioPlayStatus;
bool8 m_bIsMissionAudioPlaying;
int32 m_nMissionAudioFramesToPlay; // possibly unsigned
bool8 m_bIsMissionAudioAllowedToPlay;
int32 m_anRandomTable[5];
uint8 m_nTimeSpent;
uint8 m_nUserPause;
uint8 m_nPreviousUserPause;
bool8 m_bIsPaused;
bool8 m_bWasPaused;
uint32 m_FrameCounter;
cAudioManager();
~cAudioManager();
// getters
uint32 GetFrameCounter() const { return m_FrameCounter; }
float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
int32 GetRandomNumberInRange(int32 idx, int32 low, int32 high) const { return (m_anRandomTable[idx] % (high - low + 1)) + low; }
bool ShouldDuckMissionAudio() const { return m_sMissionAudio.m_nPlayStatus == 1; }
// "Should" be in alphabetic order, except "getXTalkSfx"
void AddDetailsToRequestedOrderList(uint8 sample);
void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank,
uint8 counter, bool notLooping);
void AddReflectionsToRequestedQueue();
void AddReleasingSounds();
void AddSampleToRequestedQueue();
void AgeCrimes();
void CalculateDistance(bool &condition, float dist);
bool CheckForAnAudioFileOnCD() const;
void ClearActiveSamples();
void ClearMissionAudio();
void ClearRequestedQueue();
int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
float speedMultiplier) const;
int32 ComputePan(float, CVector *);
uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
int32 CreateEntity(eAudioType type, void *entity);
void DestroyAllGameCreatedEntities();
void DestroyEntity(int32 id);
void DoPoliceRadioCrackle();
// functions returning talk sfx,
// order from GetPedCommentSfx
uint32 GetPlayerTalkSfx(int16 sound);
uint32 GetCopTalkSfx(int16 sound);
uint32 GetSwatTalkSfx(int16 sound);
uint32 GetFBITalkSfx(int16 sound);
uint32 GetArmyTalkSfx(int16 sound);
uint32 GetMedicTalkSfx(int16 sound);
uint32 GetFiremanTalkSfx(int16 sound);
uint32 GetNormalMaleTalkSfx(int16 sound);
uint32 GetTaxiDriverTalkSfx(int16 sound);
uint32 GetPimpTalkSfx(int16 sound);
uint32 GetMafiaTalkSfx(int16 sound);
uint32 GetTriadTalkSfx(int16 sound);
uint32 GetDiabloTalkSfx(int16 sound);
uint32 GetYakuzaTalkSfx(int16 sound);
uint32 GetYardieTalkSfx(int16 sound);
uint32 GetColumbianTalkSfx(int16 sound);
uint32 GetHoodTalkSfx(int16 sound);
uint32 GetBlackCriminalTalkSfx(int16 sound);
uint32 GetWhiteCriminalTalkSfx(int16 sound);
uint32 GetMaleNo2TalkSfx(int16 sound);
uint32 GetBlackProjectMaleTalkSfx(int16 sound, int32 model);
uint32 GetWhiteFatMaleTalkSfx(int16 sound);
uint32 GetBlackFatMaleTalkSfx(int16 sound);
uint32 GetBlackCasualFemaleTalkSfx(int16 sound);
uint32 GetWhiteCasualFemaleTalkSfx(int16 sound);
uint32 GetFemaleNo3TalkSfx(int16 sound);
uint32 GetBlackFatFemaleTalkSfx(int16 sound);
uint32 GetWhiteFatFemaleTalkSfx(int16 sound);
uint32 GetBlackFemaleProstituteTalkSfx(int16 sound);
uint32 GetWhiteFemaleProstituteTalkSfx(int16 sound);
uint32 GetBlackProjectFemaleOldTalkSfx(int16 sound);
uint32 GetBlackProjectFemaleYoungTalkSfx(int16 sound);
uint32 GetChinatownMaleOldTalkSfx(int16 sound);
uint32 GetChinatownMaleYoungTalkSfx(int16 sound);
uint32 GetChinatownFemaleOldTalkSfx(int16 sound);
uint32 GetChinatownFemaleYoungTalkSfx(int16 sound);
uint32 GetLittleItalyMaleTalkSfx(int16 sound);
uint32 GetLittleItalyFemaleOldTalkSfx(int16 sound);
uint32 GetLittleItalyFemaleYoungTalkSfx(int16 sound);
uint32 GetWhiteDockerMaleTalkSfx(int16 sound);
uint32 GetBlackDockerMaleTalkSfx(int16 sound);
uint32 GetScumMaleTalkSfx(int16 sound);
uint32 GetScumFemaleTalkSfx(int16 sound);
uint32 GetWhiteWorkerMaleTalkSfx(int16 sound);
uint32 GetBlackWorkerMaleTalkSfx(int16 sound);
uint32 GetBusinessMaleYoungTalkSfx(int16 sound, int32 model);
uint32 GetBusinessMaleOldTalkSfx(int16 sound);
uint32 GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model);
uint32 GetBlackBusinessFemaleTalkSfx(int16 sound);
uint32 GetSupermodelMaleTalkSfx(int16 sound);
uint32 GetSupermodelFemaleTalkSfx(int16 sound);
uint32 GetStewardMaleTalkSfx(int16 sound);
uint32 GetStewardFemaleTalkSfx(int16 sound);
uint32 GetFanMaleTalkSfx(int16 sound, int32 model);
uint32 GetFanFemaleTalkSfx(int16 sound);
uint32 GetHospitalMaleTalkSfx(int16 sound);
uint32 GetHospitalFemaleTalkSfx(int16 sound);
uint32 GetWhiteConstructionWorkerTalkSfx(int16 sound);
uint32 GetBlackConstructionWorkerTalkSfx(int16 sound);
uint32 GetShopperFemaleTalkSfx(int16 sound, int32 model);
uint32 GetStudentMaleTalkSfx(int16 sound);
uint32 GetStudentFemaleTalkSfx(int16 sound);
uint32 GetCasualMaleOldTalkSfx(int16 sound);
uint32 GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound);
uint32 GetEightTalkSfx(int16 sound);
uint32 GetFrankieTalkSfx(int16 sound);
uint32 GetMistyTalkSfx(int16 sound);
uint32 GetOJGTalkSfx(int16 sound);
uint32 GetCatatalinaTalkSfx(int16 sound);
uint32 GetBomberTalkSfx(int16 sound);
uint32 GetSecurityGuardTalkSfx(int16 sound);
uint32 GetChunkyTalkSfx(int16 sound);
uint32 GetGenericMaleTalkSfx(int16 sound);
uint32 GetGenericFemaleTalkSfx(int16 sound);
// end of functions returning talk sfx
void GenerateIntegerRandomNumberTable();
char *Get3DProviderName(uint8 id) const;
uint8 GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const;
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const;
float GetCollisionRatio(float a, float b, float c, float d) const;
float GetDistanceSquared(const CVector &v) const;
int32 GetJumboTaxiFreq() const;
uint8 GetMissionAudioLoadingStatus() const;
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
uint8 GetNum3DProvidersAvailable() const;
int32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
cTransmission *transmission, float velocityChange);
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
cTransmission *transmission, float velocityChange);
bool HasAirBrakes(int32 model) const;
void Initialise();
void InitialisePoliceRadio();
void InitialisePoliceRadioZones();
void InterrogateAudioEntities();
bool IsAudioInitialised() const;
bool IsMissionAudioSampleFinished();
bool IsMP3RadioChannelAvailable() const;
bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
void PlayLoadedMissionAudio();
void PlayOneShot(int32 index, uint16 sound, float vol);
void PlaySuspectLastSeen(float x, float y, float z);
void PlayerJustGotInCar() const;
void PlayerJustLeftCar() const;
void PostInitialiseGameSpecificSetup();
void PostTerminateGameSpecificShutdown();
void PreInitialiseGameSpecificSetup() const;
void PreloadMissionAudio(Const char *name);
void PreTerminateGameSpecificShutdown();
/// processX - main logic of adding new sounds
void ProcessActiveQueues();
bool ProcessAirBrakes(cVehicleParams& params);
void ProcessAirportScriptObject(uint8 sound);
bool ProcessBoatEngine(cVehicleParams& params);
bool ProcessBoatMovingOverWater(cVehicleParams& params);
void ProcessBridge();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
void ProcessBridgeWarning();
bool ProcessCarBombTick(cVehicleParams& params);
void ProcessCesna(cVehicleParams& params);
void ProcessCinemaScriptObject(uint8 sound);
void ProcessCrane();
void ProcessDocksScriptObject(uint8 sound);
bool ProcessEngineDamage(cVehicleParams& params);
void ProcessEntity(int32 sound);
void ProcessExplosions(int32 explosion);
void ProcessFireHydrant();
void ProcessFires(int32 entity);
void ProcessFrontEnd();
void ProcessGarages();
bool ProcessHelicopter(cVehicleParams& params);
void ProcessHomeScriptObject(uint8 sound);
void ProcessJumbo(cVehicleParams& params);
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboDecel(CPlane *plane);
void ProcessJumboFlying();
void ProcessJumboLanding(CPlane *plane);
void ProcessJumboTakeOff(CPlane *plane);
void ProcessJumboTaxi();
void ProcessLaunderetteScriptObject(uint8 sound);
void ProcessLoopingScriptObject(uint8 sound);
void ProcessMissionAudio();
void ProcessModelCarEngine(cVehicleParams& params);
void ProcessOneShotScriptObject(uint8 sound);
void ProcessPed(CPhysical *ped);
void ProcessPedHeadphones(cPedParams &params);
void ProcessPedOneShots(cPedParams &params);
void ProcessPhysical(int32 id);
void ProcessPlane(cVehicleParams& params);
void ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *automobile);
void ProcessPoliceCellBeatingScriptObject(uint8 sound);
void ProcessPornCinema(uint8 sound);
void ProcessProjectiles();
void ProcessRainOnVehicle(cVehicleParams& params);
void ProcessReverb() const;
bool ProcessReverseGear(cVehicleParams& params);
void ProcessSawMillScriptObject(uint8 sound);
void ProcessScriptObject(int32 id);
void ProcessShopScriptObject(uint8 sound);
void ProcessSpecial();
bool ProcessTrainNoise(cVehicleParams& params);
void ProcessVehicle(CVehicle *vehicle);
bool ProcessVehicleDoors(cVehicleParams& params);
void ProcessVehicleEngine(cVehicleParams& params);
void ProcessVehicleHorn(cVehicleParams& params);
void ProcessVehicleOneShots(cVehicleParams& params);
bool ProcessVehicleReverseWarning(cVehicleParams& params);
bool ProcessVehicleRoadNoise(cVehicleParams& params);
bool ProcessVehicleSirenOrAlarm(cVehicleParams& params);
bool ProcessVehicleSkidding(cVehicleParams& params);
void ProcessWaterCannon(int32);
void ProcessWeather(int32 id);
bool ProcessWetRoadNoise(cVehicleParams& params);
void ProcessWorkShopScriptObject(uint8 sound);
int32 RandomDisplacement(uint32 seed) const;
void ReacquireDigitalHandle() const;
void ReleaseDigitalHandle() const;
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
float collisionPower, float intensity2);
void ReportCrime(eCrimeType crime, const CVector &pos);
void ResetAudioLogicTimers(uint32 timer);
void ResetPoliceRadio();
void ResetTimers(uint32 time);
void Service();
void ServiceCollisions();
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
void ServiceSoundEffects();
int8 SetCurrent3DProvider(uint8 which);
void SetDynamicAcousticModelingStatus(uint8 status);
void SetEffectsFadeVol(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
void SetEntityStatus(int32 id, uint8 status);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
void SetMissionAudioLocation(float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const;
void SetMonoMode(uint8 mono);
void SetMusicFadeVol(uint8 volume) const;
void SetMusicMasterVolume(uint8 volume) const;
void SetSpeakerConfig(int32 conf) const;
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
void SetUpOneShotCollisionSound(const cAudioCollision &col);
bool SetupCrimeReport();
bool SetupJumboEngineSound(uint8 vol, uint32 freq);
bool SetupJumboFlySound(uint8 emittingVol);
bool SetupJumboRumbleSound(uint8 emittingVol);
bool SetupJumboTaxiSound(uint8 vol);
bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
void SetupPedComments(cPedParams &params, uint16 sound);
void SetupSuspectLastSeenReport();
void Terminate();
void TranslateEntity(Const CVector *v1, CVector *v2) const;
void UpdateGasPedalAudio(CAutomobile *automobile);
void UpdateReflections();
bool UsesReverseWarning(int32 model) const;
bool UsesSiren(int32 model) const;
bool UsesSirenSwitching(int32 model) const;
void Service();
int32 CreateEntity(eAudioType type, void *entity);
void DestroyEntity(int32 id);
bool8 GetEntityStatus(int32 id);
void SetEntityStatus(int32 id, bool8 status);
void *GetEntityPointer(int32 id);
void PlayOneShot(int32 index, uint16 sound, float vol);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
void SetEffectsFadeVol(uint8 volume);
void SetMusicFadeVol(uint8 volume);
void SetMonoMode(bool8 mono);
void ResetTimers(uint32 time);
void DestroyAllGameCreatedEntities();
#ifdef GTA_PC
// only used in pc
void AdjustSamplesVolume();
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
uint8 GetNum3DProvidersAvailable();
char *Get3DProviderName(uint8 id);
int8 GetCurrent3DProviderIndex();
int8 SetCurrent3DProvider(uint8 which);
void SetSpeakerConfig(int32 conf);
bool8 IsMP3RadioChannelAvailable();
void ReleaseDigitalHandle();
void ReacquireDigitalHandle();
#ifdef AUDIO_REFLECTIONS
void SetDynamicAcousticModelingStatus(bool8 status);
#endif
bool8 CheckForAnAudioFileOnCD();
char GetCDAudioDriveLetter();
bool8 IsAudioInitialised();
#endif
void ServiceSoundEffects();
uint32 FL(float f); // not used
uint8 ComputeVolume(uint8 emittingVolume, float maxDistance, float distance);
void TranslateEntity(Const CVector *v1, CVector *v2);
int32 ComputePan(float, CVector *);
uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier); // inlined on PS2
int32 RandomDisplacement(uint32 seed);
void InterrogateAudioEntities(); // inlined on PS2
void AddSampleToRequestedQueue();
void AddDetailsToRequestedOrderList(uint8 sample); // inlined on PS2
#ifdef AUDIO_REFLECTIONS
void AddReflectionsToRequestedQueue();
void UpdateReflections();
#endif
void AddReleasingSounds();
void ProcessActiveQueues();
void ClearRequestedQueue(); // inlined on PS2
void ClearActiveSamples();
void GenerateIntegerRandomNumberTable(); // inlined on PS2
#ifdef GTA_PS2
bool8 LoadBankIfNecessary(uint8 bank); // this is used only on PS2 but technically not a platform code
#endif
#ifdef EXTERNAL_3D_SOUND // actually must have been && AUDIO_MSS as well
void AdjustSamplesVolume();
uint8 ComputeEmittingVolume(uint8 emittingVolume, float maxDistance, float distance);
#endif
// audio logic
void PreInitialiseGameSpecificSetup();
void PostInitialiseGameSpecificSetup();
void PreTerminateGameSpecificShutdown();
void PostTerminateGameSpecificShutdown();
void ResetAudioLogicTimers(uint32 timer);
void ProcessReverb();
float GetDistanceSquared(const CVector &v);
void CalculateDistance(bool8 &condition, float dist);
void ProcessSpecial();
void ProcessEntity(int32 id);
void ProcessPhysical(int32 id);
// vehicles
void ProcessVehicle(CVehicle *vehicle);
void ProcessRainOnVehicle(cVehicleParams &params);
bool8 ProcessReverseGear(cVehicleParams &params);
void ProcessModelCarEngine(cVehicleParams &params);
bool8 ProcessVehicleRoadNoise(cVehicleParams &params);
bool8 ProcessWetRoadNoise(cVehicleParams &params);
bool8 ProcessVehicleEngine(cVehicleParams &params);
void UpdateGasPedalAudio(CAutomobile *automobile); // inlined on PS2
void PlayerJustGotInCar();
void PlayerJustLeftCar();
void AddPlayerCarSample(uint8 emittingVolume, uint32 freq, uint32 sample, uint8 bank, uint8 counter, bool8 notLooping);
void ProcessCesna(cVehicleParams &params);
void ProcessPlayersVehicleEngine(cVehicleParams &params, CAutomobile *automobile);
bool8 ProcessVehicleSkidding(cVehicleParams &params);
float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange);
float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile, cTransmission *transmission, float velocityChange); // inlined on PS2
bool8 ProcessVehicleHorn(cVehicleParams &params);
bool8 UsesSiren(uint32 model); // inlined on PS2
bool8 UsesSirenSwitching(uint32 model); // inlined on PS2
bool8 ProcessVehicleSirenOrAlarm(cVehicleParams &params);
bool8 UsesReverseWarning(uint32 model); // inlined on PS2
bool8 ProcessVehicleReverseWarning(cVehicleParams &params);
bool8 ProcessVehicleDoors(cVehicleParams &params);
bool8 ProcessAirBrakes(cVehicleParams &params);
bool8 HasAirBrakes(uint32 model); // inlined on PS2
bool8 ProcessEngineDamage(cVehicleParams &params);
bool8 ProcessCarBombTick(cVehicleParams &params);
void ProcessVehicleOneShots(cVehicleParams &params);
bool8 ProcessTrainNoise(cVehicleParams &params);
bool8 ProcessBoatEngine(cVehicleParams &params);
bool8 ProcessBoatMovingOverWater(cVehicleParams &params);
bool8 ProcessHelicopter(cVehicleParams &params);
void ProcessPlane(cVehicleParams &params); // inlined on PS2
void ProcessJumbo(cVehicleParams &params);
void ProcessJumboTaxi(); // inlined on PS2
void ProcessJumboAccel(CPlane *plane);
void ProcessJumboTakeOff(CPlane *plane); // inlined on PS2
void ProcessJumboFlying(); // inlined on PS2
void ProcessJumboLanding(CPlane *plane); // inlined on PS2
void ProcessJumboDecel(CPlane *plane); // inlined on PS2
bool8 SetupJumboTaxiSound(uint8 vol);
bool8 SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
bool8 SetupJumboEngineSound(uint8 vol, uint32 freq);
bool8 SetupJumboFlySound(uint8 emittingVol);
bool8 SetupJumboRumbleSound(uint8 emittingVol);
int32 GetJumboTaxiFreq(); // inlined on PS2
// peds
void ProcessPed(CPhysical *ped); // inlined on PS2
void ProcessPedHeadphones(cPedParams &params);
void ProcessPedOneShots(cPedParams &params);
// ped comments
void SetupPedComments(cPedParams &params, uint16 sound);
int32 GetPedCommentSfx(CPed *ped, uint16 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset); // inlined on PS2
uint32 GetPlayerTalkSfx(uint16 sound); // inlined on PS2
uint32 GetCopTalkSfx(uint16 sound);
uint32 GetSwatTalkSfx(uint16 sound);
uint32 GetFBITalkSfx(uint16 sound);
uint32 GetArmyTalkSfx(uint16 sound);
uint32 GetMedicTalkSfx(uint16 sound);
uint32 GetFiremanTalkSfx(uint16 sound); // inlined on PS2
uint32 GetBusinessMaleOldTalkSfx(uint16 sound);
uint32 GetBusinessMaleYoungTalkSfx(uint16 sound, uint32 model);
uint32 GetMafiaTalkSfx(uint16 sound);
uint32 GetTriadTalkSfx(uint16 sound);
uint32 GetDiabloTalkSfx(uint16 sound);
uint32 GetYakuzaTalkSfx(uint16 sound);
uint32 GetYardieTalkSfx(uint16 sound);
uint32 GetColumbianTalkSfx(uint16 sound);
uint32 GetHoodTalkSfx(uint16 sound);
uint32 GetBlackCriminalTalkSfx(uint16 sound);
uint32 GetWhiteCriminalTalkSfx(uint16 sound);
uint32 GetCasualMaleOldTalkSfx(uint16 sound);
uint32 GetCasualMaleYoungTalkSfx(uint16 sound);
uint32 GetBlackCasualFemaleTalkSfx(uint16 sound);
uint32 GetWhiteCasualFemaleTalkSfx(uint16 sound);
uint32 GetFemaleNo3TalkSfx(uint16 sound);
uint32 GetWhiteBusinessFemaleTalkSfx(uint16 sound, uint32 model);
uint32 GetBlackFatFemaleTalkSfx(uint16 sound);
uint32 GetWhiteFatMaleTalkSfx(uint16 sound);
uint32 GetBlackFatMaleTalkSfx(uint16 sound);
uint32 GetWhiteFatFemaleTalkSfx(uint16 sound);
uint32 GetBlackFemaleProstituteTalkSfx(uint16 sound);
uint32 GetWhiteFemaleProstituteTalkSfx(uint16 sound);
uint32 GetBlackProjectMaleTalkSfx(uint16 sound, uint32 model);
uint32 GetBlackProjectFemaleOldTalkSfx(uint16 sound);
uint32 GetBlackProjectFemaleYoungTalkSfx(uint16 sound);
uint32 GetChinatownMaleOldTalkSfx(uint16 sound);
uint32 GetChinatownMaleYoungTalkSfx(uint16 sound);
uint32 GetChinatownFemaleOldTalkSfx(uint16 sound);
uint32 GetChinatownFemaleYoungTalkSfx(uint16 sound);
uint32 GetLittleItalyMaleTalkSfx(uint16 sound);
uint32 GetLittleItalyFemaleOldTalkSfx(uint16 sound);
uint32 GetLittleItalyFemaleYoungTalkSfx(uint16 sound);
uint32 GetWhiteDockerMaleTalkSfx(uint16 sound);
uint32 GetBlackDockerMaleTalkSfx(uint16 sound);
uint32 GetScumMaleTalkSfx(uint16 sound);
uint32 GetScumFemaleTalkSfx(uint16 sound);
uint32 GetWhiteWorkerMaleTalkSfx(uint16 sound);
uint32 GetBlackWorkerMaleTalkSfx(uint16 sound);
uint32 GetBlackBusinessFemaleTalkSfx(uint16 sound);
uint32 GetSupermodelMaleTalkSfx(uint16 sound);
uint32 GetSupermodelFemaleTalkSfx(uint16 sound);
uint32 GetStewardMaleTalkSfx(uint16 sound);
uint32 GetStewardFemaleTalkSfx(uint16 sound);
uint32 GetFanMaleTalkSfx(uint16 sound, uint32 model);
uint32 GetFanFemaleTalkSfx(uint16 sound);
uint32 GetHospitalMaleTalkSfx(uint16 sound);
uint32 GetHospitalFemaleTalkSfx(uint16 sound); // inlined on PS2
uint32 GetWhiteConstructionWorkerTalkSfx(uint16 sound);
uint32 GetBlackConstructionWorkerTalkSfx(uint16 sound);
uint32 GetShopperFemaleTalkSfx(uint16 sound, uint32 model);
uint32 GetStudentMaleTalkSfx(uint16 sound);
uint32 GetStudentFemaleTalkSfx(uint16 sound);
uint32 GetSpecialCharacterTalkSfx(uint32 modelIndex, uint16 sound);
uint32 GetEightBallTalkSfx(uint16 sound); // inlined on PS2
uint32 GetSalvatoreTalkSfx(uint16 sound); // inlined on PS2
uint32 GetMistyTalkSfx(uint16 sound);
uint32 GetOldJapTalkSfx(uint16 sound); // inlined on PS2
uint32 GetCatalinaTalkSfx(uint16 sound); // inlined on PS2
uint32 GetBomberTalkSfx(uint16 sound); // inlined on PS2
uint32 GetSecurityGuardTalkSfx(uint16 sound);
uint32 GetChunkyTalkSfx(uint16 sound); // inlined on PS2
uint32 GetAsianTaxiDriverTalkSfx(uint16 sound); // inlined on PS2
uint32 GetPimpTalkSfx(uint16 sound);
uint32 GetNormalMaleTalkSfx(uint16 sound);
uint32 GetGenericMaleTalkSfx(uint16 sound);
uint32 GetGenericFemaleTalkSfx(uint16 sound);
// particles
void ProcessExplosions(int32 id);
void ProcessFires(int32 id);
void ProcessWaterCannon(int32 id);
// script objects
void ProcessScriptObject(int32 id); // inlined on PS2
void ProcessOneShotScriptObject(uint8 sound);
void ProcessLoopingScriptObject(uint8 sound);
void ProcessPornCinema(uint8 sound);
void ProcessWorkShopScriptObject(uint8 sound);
void ProcessSawMillScriptObject(uint8 sound);
void ProcessLaunderetteScriptObject(uint8 sound);
void ProcessShopScriptObject(uint8 sound);
void ProcessAirportScriptObject(uint8 sound);
void ProcessCinemaScriptObject(uint8 sound);
void ProcessDocksScriptObject(uint8 sound);
void ProcessHomeScriptObject(uint8 sound);
void ProcessPoliceCellBeatingScriptObject(uint8 sound);
// misc
void ProcessWeather(int32 id);
void ProcessFrontEnd();
void ProcessCrane();
void ProcessProjectiles();
void ProcessGarages();
void ProcessFireHydrant();
// bridge
void ProcessBridge(); // inlined on PS2
void ProcessBridgeWarning();
void ProcessBridgeMotor();
void ProcessBridgeOneShots();
// mission audio
bool8 MissionScriptAudioUsesPoliceChannel(uint32 soundMission);
void PreloadMissionAudio(Const char *name);
uint8 GetMissionAudioLoadingStatus();
void SetMissionAudioLocation(float x, float y, float z);
void PlayLoadedMissionAudio();
bool8 IsMissionAudioSampleFinished();
bool8 IsMissionAudioSamplePlaying() { return m_nMissionAudioPlayStatus == PLAY_STATUS_PLAYING; }
bool8 ShouldDuckMissionAudio() { return IsMissionAudioSamplePlaying(); }
void ClearMissionAudio();
void ProcessMissionAudio();
// police radio
void InitialisePoliceRadioZones();
void InitialisePoliceRadio();
void ResetPoliceRadio();
void SetMissionScriptPoliceAudio(uint32 sfx);
int8 GetMissionScriptPoliceAudioPlayingStatus();
void DoPoliceRadioCrackle();
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
bool8 SetupCrimeReport();
void SetupSuspectLastSeenReport();
void ReportCrime(eCrimeType crime, const CVector &pos);
void PlaySuspectLastSeen(float x, float y, float z);
void AgeCrimes(); // inlined on PS2
// collision stuff
void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2);
void ServiceCollisions();
void SetUpOneShotCollisionSound(const cAudioCollision &col);
void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
float GetCollisionOneShotRatio(uint32 a, float b);
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c); // not used
float GetCollisionRatio(float a, float b, float c, float d); // inlined on PS2
};
#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
#ifdef EXTERNAL_3D_SOUND
#define SET_EMITTING_VOLUME(vol) m_sQueueSample.m_nEmittingVolume = vol
#else
#define SET_EMITTING_VOLUME(vol)
#endif
#ifdef AUDIO_REFLECTIONS
#define SET_SOUND_REFLECTION(b) m_sQueueSample.m_bReflections = b
#else
#define SET_SOUND_REFLECTION(b)
#endif
#if defined(AUDIO_MSS) && !defined(PS2_AUDIO_CHANNELS)
static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
#endif
extern cAudioManager AudioManager;
enum
{
PED_COMMENT_VOLUME = 127,
PED_COMMENT_VOLUME_BEHIND_WALL = 31,
COLLISION_MAX_DIST = 60,
};

View File

@ -564,8 +564,9 @@ enum eSfxSample
// bank 59
SFX_EXPLOSION_1,
SFX_BRIDGE_OPEN_WARNING,
#ifndef GTA_PS2
SFX_PAGER, // used to be ped comment on PS2
#endif
SFX_COP_VOICE_1_ARREST_1,
SFX_COP_VOICE_1_ARREST_2,
@ -703,6 +704,9 @@ enum eSfxSample
SFX_POLICE_HELI_27,
SFX_POLICE_HELI_28,
SFX_POLICE_HELI_29,
#ifdef GTA_PS2
SFX_MISSION_CAT1,
#endif
SFX_CHUNKY_DEATH,
SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_1,
SFX_BLACK_DOCKER_VOICE_1_DRIVER_ABUSE_2,
@ -761,6 +765,9 @@ enum eSfxSample
SFX_ARMY_VOICE_2_CHASE_13,
SFX_ARMY_VOICE_2_CHASE_14,
SFX_ARMY_VOICE_2_CHASE_15,
#ifdef GTA_PS2
SFX_PAGER,
#endif
SFX_CLAUDE_LOW_DAMAGE_GRUNT_1,
SFX_CLAUDE_LOW_DAMAGE_GRUNT_2,
SFX_CLAUDE_LOW_DAMAGE_GRUNT_3,
@ -3140,14 +3147,127 @@ enum eSfxSample
SFX_AMMU_D,
SFX_AMMU_E,
SFX_AMMU_F,
#ifdef GTA_PS2
SFX_MISSION_LIB_A1,
SFX_MISSION_LIB_A2,
SFX_MISSION_LIB_A,
SFX_MISSION_LIB_B,
SFX_MISSION_LIB_C,
SFX_MISSION_LIB_D,
SFX_MISSION_L2_A,
SFX_MISSION_J4T_1,
SFX_MISSION_J4T_2,
SFX_MISSION_J4T_3,
SFX_MISSION_J4T_4,
SFX_MISSION_J4_A,
SFX_MISSION_J4_B,
SFX_MISSION_J4_C,
SFX_MISSION_J4_D,
SFX_MISSION_J4_E,
SFX_MISSION_J4_F,
SFX_MISSION_J6_1,
SFX_MISSION_J6_A,
SFX_MISSION_J6_B,
SFX_MISSION_J6_C,
SFX_MISSION_J6_D,
SFX_MISSION_T4_A,
SFX_MISSION_S1_A,
SFX_MISSION_S1_A1,
SFX_MISSION_S1_B,
SFX_MISSION_S1_C,
SFX_MISSION_S1_C1,
SFX_MISSION_S1_D,
SFX_MISSION_S1_E,
SFX_MISSION_S1_F,
SFX_MISSION_S1_G,
SFX_MISSION_S1_H,
SFX_MISSION_S1_I,
SFX_MISSION_S1_J,
SFX_MISSION_S1_K,
SFX_MISSION_S1_L,
SFX_MISSION_S3_A,
SFX_MISSION_S3_B,
SFX_MISSION_EL3_A,
SFX_MISSION_MF1_A,
SFX_MISSION_MF2_A,
SFX_MISSION_MF3_A,
SFX_MISSION_MF3_B,
SFX_MISSION_MF3_B1,
SFX_MISSION_MF3_C,
SFX_MISSION_MF4_A,
SFX_MISSION_MF4_B,
SFX_MISSION_MF4_C,
SFX_MISSION_A1_A,
SFX_MISSION_A3_A,
SFX_MISSION_A5_A,
SFX_MISSION_A4_A,
SFX_MISSION_A4_B,
SFX_MISSION_A4_C,
SFX_MISSION_A4_D,
SFX_MISSION_K1_A,
SFX_MISSION_K3_A,
SFX_MISSION_R1_A,
SFX_MISSION_R2_A,
SFX_MISSION_R2_B,
SFX_MISSION_R2_C,
SFX_MISSION_R2_D,
SFX_MISSION_R2_E,
SFX_MISSION_R2_F,
SFX_MISSION_R2_G,
SFX_MISSION_R2_H,
SFX_MISSION_R5_A,
SFX_MISSION_R6_A,
SFX_MISSION_R6_A1,
SFX_MISSION_R6_B,
SFX_MISSION_LO2_A,
SFX_MISSION_LO6_A,
SFX_MISSION_YD2_A,
SFX_MISSION_YD2_B,
SFX_MISSION_YD2_C,
SFX_MISSION_YD2_C1,
SFX_MISSION_YD2_D,
SFX_MISSION_YD2_E,
SFX_MISSION_YD2_F,
SFX_MISSION_YD2_G,
SFX_MISSION_YD2_H,
SFX_MISSION_YD2_ASS,
SFX_MISSION_YD2_OK,
SFX_MISSION_H5_A,
SFX_MISSION_H5_B,
SFX_MISSION_H5_C,
SFX_MISSION_DOOR_1,
SFX_MISSION_DOOR_2,
SFX_MISSION_DOOR_3,
SFX_MISSION_DOOR_4,
SFX_MISSION_DOOR_5,
SFX_MISSION_DOOR_6,
SFX_MISSION_T3_A,
SFX_MISSION_T3_B,
SFX_MISSION_T3_C,
SFX_MISSION_K1_B,
SFX_MISSION_AMMU_A,
SFX_MISSION_AMMU_B,
SFX_MISSION_AMMU_C,
#endif
TOTAL_AUDIO_SAMPLES,
NO_SAMPLE,
// shorthands
SAMPLEBANK_START = SFX_CAR_HORN_JEEP,
#ifdef GTA_PS2
SAMPLEBANK_END = SFX_INFO,
SAMPLEBANK_MAX = SFX_INFO + 1,
#else
SAMPLEBANK_END = SFX_PAGER,
SAMPLEBANK_MAX = SFX_PAGER + 1,
#endif
SAMPLEBANK_PED_START = SFX_COP_VOICE_1_ARREST_1,
#ifdef GTA_PS2
SAMPLEBANK_PED_END = SFX_MISSION_AMMU_C,
SAMPLEBANK_PED_MAX = SFX_MISSION_AMMU_C + 1,
#else
SAMPLEBANK_PED_END = SFX_AMMU_F,
SAMPLEBANK_PED_MAX = SFX_AMMU_F + 1,
#endif
};

View File

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

View File

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

View File

@ -38,8 +38,14 @@ cDMAudio::DestroyEntity(int32 audioEntity)
AudioManager.DestroyEntity(audioEntity);
}
bool8
cDMAudio::GetEntityStatus(int32 audioEntity)
{
return AudioManager.GetEntityStatus(audioEntity);
}
void
cDMAudio::SetEntityStatus(int32 audioEntity, uint8 status)
cDMAudio::SetEntityStatus(int32 audioEntity, bool8 status)
{
AudioManager.SetEntityStatus(audioEntity, status);
}
@ -57,7 +63,7 @@ cDMAudio::DestroyAllGameCreatedEntities(void)
}
void
cDMAudio::SetMonoMode(uint8 mono)
cDMAudio::SetMonoMode(bool8 mono)
{
AudioManager.SetMonoMode(mono);
}
@ -128,7 +134,7 @@ cDMAudio::SetSpeakerConfig(int32 config)
AudioManager.SetSpeakerConfig(config);
}
bool
bool8
cDMAudio::IsMP3RadioChannelAvailable(void)
{
return AudioManager.IsMP3RadioChannelAvailable();
@ -147,12 +153,14 @@ cDMAudio::ReacquireDigitalHandle(void)
}
void
cDMAudio::SetDynamicAcousticModelingStatus(uint8 status)
cDMAudio::SetDynamicAcousticModelingStatus(bool8 status)
{
#ifdef AUDIO_REFLECTIONS
AudioManager.SetDynamicAcousticModelingStatus(status);
#endif
}
bool
bool8
cDMAudio::CheckForAnAudioFileOnCD(void)
{
return AudioManager.CheckForAnAudioFileOnCD();
@ -164,12 +172,18 @@ cDMAudio::GetCDAudioDriveLetter(void)
return AudioManager.GetCDAudioDriveLetter();
}
bool
bool8
cDMAudio::IsAudioInitialised(void)
{
return AudioManager.IsAudioInitialised();
}
void
cDMAudio::ResetPoliceRadio()
{
AudioManager.ResetPoliceRadio();
}
void
cDMAudio::ReportCrime(eCrimeType crime, const CVector &pos)
{
@ -182,7 +196,7 @@ cDMAudio::CreateLoopingScriptObject(cAudioScriptObject *scriptObject)
int32 audioEntity = AudioManager.CreateEntity(AUDIOTYPE_SCRIPTOBJECT, scriptObject);
if ( AEHANDLE_IS_OK(audioEntity) )
AudioManager.SetEntityStatus(audioEntity, true);
AudioManager.SetEntityStatus(audioEntity, TRUE);
return audioEntity;
}
@ -200,7 +214,7 @@ cDMAudio::CreateOneShotScriptObject(cAudioScriptObject *scriptObject)
if ( AEHANDLE_IS_OK(audioEntity) )
{
AudioManager.SetEntityStatus(audioEntity, true);
AudioManager.SetEntityStatus(audioEntity, TRUE);
AudioManager.PlayOneShot(audioEntity, scriptObject->AudioId, 0.0f);
}
}
@ -230,7 +244,7 @@ cDMAudio::PlayRadioAnnouncement(uint8 announcement)
}
void
cDMAudio::PlayFrontEndTrack(uint8 track, uint8 frontendFlag)
cDMAudio::PlayFrontEndTrack(uint8 track, bool8 frontendFlag)
{
MusicManager.PlayFrontEndTrack(track, frontendFlag);
}
@ -295,7 +309,7 @@ cDMAudio::PlayLoadedMissionAudio(void)
AudioManager.PlayLoadedMissionAudio();
}
bool
bool8
cDMAudio::IsMissionAudioSampleFinished(void)
{
return AudioManager.IsMissionAudioSampleFinished();

View File

@ -22,11 +22,12 @@ public:
int32 CreateEntity(eAudioType type, void *UID);
void DestroyEntity(int32 audioEntity);
void SetEntityStatus(int32 audioEntity, uint8 status);
bool8 GetEntityStatus(int32 audioEntity);
void SetEntityStatus(int32 audioEntity, bool8 status);
void PlayOneShot(int32 audioEntity, uint16 oneShot, float volume);
void DestroyAllGameCreatedEntities(void);
void SetMonoMode(uint8 mono);
void SetMonoMode(bool8 mono);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
void SetEffectsFadeVol(uint8 volume);
@ -40,18 +41,19 @@ public:
void SetSpeakerConfig(int32 config);
bool IsMP3RadioChannelAvailable(void);
bool8 IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle(void);
void ReacquireDigitalHandle(void);
void SetDynamicAcousticModelingStatus(uint8 status);
void SetDynamicAcousticModelingStatus(bool8 status);
bool CheckForAnAudioFileOnCD(void);
bool8 CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter(void);
bool IsAudioInitialised(void);
bool8 IsAudioInitialised(void);
void ResetPoliceRadio();
void ReportCrime(eCrimeType crime, CVector const &pos);
int32 CreateLoopingScriptObject(cAudioScriptObject *scriptObject);
@ -64,7 +66,7 @@ public:
void PlayFrontEndSound(uint16 frontend, uint32 volume);
void PlayRadioAnnouncement(uint8 announcement);
void PlayFrontEndTrack(uint8 track, uint8 frontendFlag);
void PlayFrontEndTrack(uint8 track, bool8 frontendFlag);
void StopFrontEndTrack(void);
void ResetTimers(uint32 time);
@ -79,7 +81,7 @@ public:
uint8 GetMissionAudioLoadingStatus(void);
void SetMissionAudioLocation(float x, float y, float z);
void PlayLoadedMissionAudio(void);
bool IsMissionAudioSampleFinished(void);
bool8 IsMissionAudioSampleFinished(void);
void ClearMissionAudio(void);
uint8 GetRadioInCar(void);

View File

@ -22,42 +22,42 @@ static_assert(false, "RADIO_SCROLL_TO_PREV_STATION and RADIO_OFF_TEXT won't work
cMusicManager MusicManager;
int32 gNumRetunePresses;
int32 gRetuneCounter;
bool bHasStarted;
bool8 bHasStarted;
cMusicManager::cMusicManager()
{
m_bIsInitialised = false;
m_bDisabled = false;
m_bIsInitialised = FALSE;
m_bDisabled = FALSE;
m_nMusicMode = MUSICMODE_DISABLED;
m_nNextTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
m_bFrontendTrackFinished = false;
m_bPlayInFrontend = false;
m_bSetNextStation = false;
m_bFrontendTrackFinished = FALSE;
m_bPlayInFrontend = FALSE;
m_bSetNextStation = FALSE;
m_nAnnouncement = NO_TRACK;
m_bPreviousPlayerInCar = false;
m_bPlayerInCar = false;
m_bAnnouncementInProgress = false;
m_bVerifyAmbienceTrackStartedToPlay = false;
bHasStarted = false;
m_bPreviousPlayerInCar = FALSE;
m_bPlayerInCar = FALSE;
m_bAnnouncementInProgress = FALSE;
m_bVerifyAmbienceTrackStartedToPlay = FALSE;
bHasStarted = FALSE;
}
bool
bool8
cMusicManager::PlayerInCar()
{
if(!FindPlayerVehicle())
return false;
return FALSE;
int32 State = FindPlayerPed()->m_nPedState;
if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
return false;
return FALSE;
if (!FindPlayerVehicle())
return true;
return TRUE;
if (FindPlayerVehicle()->GetStatus() == STATUS_WRECKED)
return false;
return FALSE;
switch (FindPlayerVehicle()->GetModelIndex()) {
case MI_FIRETRUCK:
@ -67,8 +67,8 @@ cMusicManager::PlayerInCar()
case MI_TRAIN:
case MI_SPEEDER:
case MI_REEFER:
case MI_GHOST: return false;
default: return true;
case MI_GHOST: return FALSE;
default: return TRUE;
}
}
@ -195,7 +195,11 @@ cMusicManager::DisplayRadioStationName()
cDisplay = 60;
} else {
if(cDisplay == 0) return;
#ifdef FIX_BUGS
cDisplay -= CTimer::GetLogicalFramesPassed();
#else
cDisplay--;
#endif
}
CFont::SetJustifyOff();
@ -224,7 +228,7 @@ cMusicManager::DisplayRadioStationName()
}
}
bool
bool8
cMusicManager::Initialise()
{
int pos;
@ -232,23 +236,23 @@ cMusicManager::Initialise()
if (!IsInitialised()) {
time_t timevalue = time(0);
if (timevalue == -1) {
pos = AudioManager.GetRandomNumber(0);
pos = AudioManager.m_anRandomTable[0];
} else {
tm *pTm = localtime(&timevalue);
if (pTm->tm_sec == 0)
pTm->tm_sec = AudioManager.GetRandomNumber(0);
pTm->tm_sec = AudioManager.m_anRandomTable[0];
if (pTm->tm_min == 0)
pTm->tm_min = AudioManager.GetRandomNumber(1);
pTm->tm_min = AudioManager.m_anRandomTable[1];
if (pTm->tm_hour == 0)
pTm->tm_hour = AudioManager.GetRandomNumber(2);
pTm->tm_hour = AudioManager.m_anRandomTable[2];
if (pTm->tm_mday == 0)
pTm->tm_mday = AudioManager.GetRandomNumber(3);
pTm->tm_mday = AudioManager.m_anRandomTable[3];
if (pTm->tm_mon == 0)
pTm->tm_mon = AudioManager.GetRandomNumber(4);
pTm->tm_mon = AudioManager.m_anRandomTable[4];
if (pTm->tm_year == 0)
pTm->tm_year = AudioManager.GetRandomNumber(3);
pTm->tm_year = AudioManager.m_anRandomTable[3];
if (pTm->tm_wday == 0)
pTm->tm_wday = AudioManager.GetRandomNumber(2);
pTm->tm_wday = AudioManager.m_anRandomTable[2];
pos = pTm->tm_yday
* pTm->tm_wday
* pTm->tm_year
@ -261,22 +265,22 @@ cMusicManager::Initialise()
for (int i = 0; i < TOTAL_STREAMED_SOUNDS; i++) {
m_aTracks[i].m_nLength = SampleManager.GetStreamedFileLength(i);
m_aTracks[i].m_nPosition = pos * AudioManager.GetRandomNumber(i % 5) % m_aTracks[i].m_nLength;
m_aTracks[i].m_nPosition = pos * AudioManager.m_anRandomTable[i % 5] % m_aTracks[i].m_nLength;
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
m_bResetTimers = false;
m_bResetTimers = FALSE;
m_nResetTime = 0;
m_nTimer = m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
m_bDoTrackService = false;
m_bIgnoreTimeDelay = false;
m_bRadioSetByScript = false;
m_bDoTrackService = FALSE;
m_bIgnoreTimeDelay = FALSE;
m_bRadioSetByScript = FALSE;
m_nRadioStationScript = HEAD_RADIO;
m_nRadioPosition = -1;
m_nRadioInCar = NO_TRACK;
gNumRetunePresses = 0;
gRetuneCounter = 0;
m_bIsInitialised = true;
m_bIsInitialised = TRUE;
}
return m_bIsInitialised;
}
@ -286,12 +290,12 @@ cMusicManager::Terminate()
{
if (!IsInitialised()) return;
if (SampleManager.IsStreamPlaying(0)) {
SampleManager.StopStreamedFile(0);
if (SampleManager.IsStreamPlaying()) {
SampleManager.StopStreamedFile();
m_nNextTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
}
m_bIsInitialised = false;
m_bIsInitialised = FALSE;
}
void
@ -302,7 +306,16 @@ cMusicManager::ChangeMusicMode(uint8 mode)
uint8 mode2;
switch (mode)
{
case MUSICMODE_FRONTEND: mode2 = MUSICMODE_FRONTEND; break;
case MUSICMODE_FRONTEND:
mode2 = MUSICMODE_FRONTEND;
#ifdef PAUSE_RADIO_IN_FRONTEND
// rewind those streams we weren't listening right now
for (uint32 i = STREAMED_SOUND_RADIO_HEAD; i < STREAMED_SOUND_CUTSCENE_LUIGI1_LG; i++) {
m_aTracks[i].m_nPosition = GetTrackStartPos(i);
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
#endif
break;
case MUSICMODE_GAME: mode2 = MUSICMODE_GAME; break;
case MUSICMODE_CUTSCENE: mode2 = MUSICMODE_CUTSCENE; break;
case MUSICMODE_DISABLE: mode2 = MUSICMODE_DISABLED; break;
@ -316,25 +329,25 @@ cMusicManager::ChangeMusicMode(uint8 mode)
case MUSICMODE_GAME:
case MUSICMODE_CUTSCENE:
case MUSICMODE_DISABLED:
if (SampleManager.IsStreamPlaying(0)) {
if (SampleManager.IsStreamPlaying()) {
if (m_nNextTrack < TOTAL_STREAMED_SOUNDS) {
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
}
m_nNextTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
m_bFrontendTrackFinished = false;
m_bPlayInFrontend = false;
m_bSetNextStation = false;
m_bPreviousPlayerInCar = false;
m_bPlayerInCar = false;
m_bAnnouncementInProgress = false;
m_bFrontendTrackFinished = FALSE;
m_bPlayInFrontend = FALSE;
m_bSetNextStation = FALSE;
m_bPreviousPlayerInCar = FALSE;
m_bPlayerInCar = FALSE;
m_bAnnouncementInProgress = FALSE;
m_nTimer = m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
m_bDoTrackService = false;
m_bIgnoreTimeDelay = true;
m_bVerifyAmbienceTrackStartedToPlay = false;
m_bDoTrackService = FALSE;
m_bIgnoreTimeDelay = TRUE;
m_bVerifyAmbienceTrackStartedToPlay = FALSE;
m_nMusicMode = mode2;
break;
default: return;
@ -350,14 +363,14 @@ cMusicManager::GetRadioInCar(void)
CVehicle *veh = FindPlayerVehicle();
if (veh != nil){
if (UsesPoliceRadio(veh)) {
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0))
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && !AudioManager.m_bIsPaused))
return POLICE_RADIO;
return m_nRadioInCar;
} else return veh->m_nRadioStation;
}
}
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && AudioManager.m_nUserPause == 0))
if (m_nRadioInCar == NO_TRACK || (CReplay::IsPlayingBack() && !AudioManager.m_bIsPaused))
return RADIO_OFF;
return m_nRadioInCar;
}
@ -383,7 +396,7 @@ void
cMusicManager::SetRadioChannelByScript(uint8 station, int32 pos)
{
if (m_bIsInitialised && station < RADIO_OFF) {
m_bRadioSetByScript = true;
m_bRadioSetByScript = TRUE;
m_nRadioStationScript = station;
m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
}
@ -393,21 +406,21 @@ cMusicManager::SetRadioChannelByScript(uint8 station, int32 pos)
void
cMusicManager::ResetMusicAfterReload()
{
m_bRadioSetByScript = false;
m_bRadioSetByScript = FALSE;
m_nRadioStationScript = 0;
m_nRadioPosition = -1;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bSetNextStation = false;
m_bAnnouncementInProgress = FALSE;
m_bSetNextStation = FALSE;
gRetuneCounter = 0;
gNumRetunePresses = 0;
}
void
cMusicManager::ResetTimers(int32 time)
cMusicManager::ResetTimers(uint32 time)
{
m_bResetTimers = true;
m_bResetTimers = TRUE;
m_nResetTime = time;
}
@ -415,26 +428,26 @@ void
cMusicManager::Service()
{
if (m_bResetTimers) {
m_bResetTimers = false;
m_bResetTimers = FALSE;
m_nLastTrackServiceTime = m_nResetTime;
}
if (!m_bIsInitialised || m_bDisabled) return;
if (m_nMusicMode == MUSICMODE_CUTSCENE) {
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE);
return;
}
m_nTimer = CTimer::GetTimeInMillisecondsPauseMode();
if (m_nTimer > (m_nLastTrackServiceTime + 2000) || m_bIgnoreTimeDelay) {
m_bIgnoreTimeDelay = false;
m_bDoTrackService = true;
m_bIgnoreTimeDelay = FALSE;
m_bDoTrackService = TRUE;
m_nLastTrackServiceTime = m_nTimer;
} else m_bDoTrackService = false;
} else m_bDoTrackService = FALSE;
if (m_nNextTrack == NO_TRACK && SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile(0);
if (m_nNextTrack == NO_TRACK && SampleManager.IsStreamPlaying())
SampleManager.StopStreamedFile();
else switch (m_nMusicMode) {
case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break;
case MUSICMODE_GAME: ServiceGameMode(); break;
@ -444,13 +457,19 @@ cMusicManager::Service()
void
cMusicManager::ServiceFrontEndMode()
{
#ifdef PAUSE_RADIO_IN_FRONTEND
// pause radio
for (uint32 i = STREAMED_SOUND_RADIO_HEAD; i < STREAMED_SOUND_CUTSCENE_LUIGI1_LG; i++)
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
#endif
if (m_nNextTrack < TOTAL_STREAMED_SOUNDS) {
if (m_bFrontendTrackFinished) {
if (!SampleManager.IsStreamPlaying(0)) {
if (!SampleManager.IsStreamPlaying()) {
switch (m_nNextTrack)
{
case STREAMED_SOUND_MISSION_COMPLETED:
if (!AudioManager.m_nUserPause)
if (!AudioManager.m_bIsPaused)
ChangeMusicMode(MUSICMODE_GAME);
break;
case STREAMED_SOUND_GAME_COMPLETED:
@ -463,25 +482,25 @@ cMusicManager::ServiceFrontEndMode()
m_nPlayingTrack = NO_TRACK;
}
} else if (bHasStarted) {
if (!SampleManager.IsStreamPlaying(0))
SampleManager.StartStreamedFile(m_nNextTrack, 0, 0);
if (!SampleManager.IsStreamPlaying())
SampleManager.StartStreamedFile(m_nNextTrack, 0);
} else {
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
if (!SampleManager.StartStreamedFile(m_nNextTrack, m_nNextTrack < NUM_RADIOS ? GetTrackStartPos(m_nNextTrack) : 0, 0))
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
if (!SampleManager.StartStreamedFile(m_nNextTrack, m_nNextTrack < NUM_RADIOS ? GetTrackStartPos(m_nNextTrack) : 0))
return;
SampleManager.SetStreamedVolumeAndPan(100, 63, 0, 0);
if (m_bPlayInFrontend) bHasStarted = true;
else m_bFrontendTrackFinished = true;
SampleManager.SetStreamedVolumeAndPan(100, 63, FALSE);
if (m_bPlayInFrontend) bHasStarted = TRUE;
else m_bFrontendTrackFinished = TRUE;
}
}
if (SampleManager.IsStreamPlaying(0))
SampleManager.SetStreamedVolumeAndPan((CPad::GetPad(0)->bDisplayNoControllerMessage || CPad::GetPad(0)->bObsoleteControllerMessage) ? 0 : 100, 63, 0, 0);
if (SampleManager.IsStreamPlaying())
SampleManager.SetStreamedVolumeAndPan((CPad::GetPad(0)->bDisplayNoControllerMessage || CPad::GetPad(0)->bObsoleteControllerMessage) ? 0 : 100, 63, FALSE);
}
void
cMusicManager::ServiceGameMode()
{
bool bRadioOff = false;
bool8 bRadioOff = FALSE;
static int8 nFramesSinceCutsceneEnded = -1;
uint8 volume;
@ -508,7 +527,7 @@ cMusicManager::ServiceGameMode()
#endif
}
#ifdef RADIO_SCROLL_TO_PREV_STATION
else if(CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
else if(!CPad::GetPad(0)->ArePlayerControlsDisabled() && (CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown())) {
int scrollNext = ControlsManager.GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, MOUSE);
int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON : scrollNext == rsMOUSEWHEELDOWNBUTTON ? rsMOUSEWHEELUPBUTTON : -1;
@ -524,8 +543,8 @@ cMusicManager::ServiceGameMode()
nFramesSinceCutsceneEnded = -1;
}
if (AudioManager.m_nPreviousUserPause)
m_bPreviousPlayerInCar = false;
if (AudioManager.m_bWasPaused)
m_bPreviousPlayerInCar = FALSE;
if (!m_bPlayerInCar) {
if (m_bPreviousPlayerInCar) {
if (m_nNextTrack != STREAMED_SOUND_RADIO_POLICE)
@ -541,7 +560,7 @@ cMusicManager::ServiceGameMode()
&& ServiceAnnouncement())
{
if (m_bAnnouncementInProgress) {
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
return;
}
m_nPlayingTrack = m_nNextTrack;
@ -558,7 +577,7 @@ cMusicManager::ServiceGameMode()
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
gRetuneCounter = 0;
gNumRetunePresses = 0;
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
}
// Because when you switch radio back and forth, gNumRetunePresses will be 0 but gRetuneCounter won't.
#ifdef RADIO_SCROLL_TO_PREV_STATION
@ -566,24 +585,24 @@ cMusicManager::ServiceGameMode()
if (gRetuneCounter > 1) gRetuneCounter--;
else if (gRetuneCounter == 1) gRetuneCounter = -1;
else if (gRetuneCounter == -1) {
m_bSetNextStation = true;
m_bSetNextStation = TRUE;
gRetuneCounter = 0;
}
}
#else
if (gNumRetunePresses) {
if (gRetuneCounter != 0) gRetuneCounter--;
else m_bSetNextStation = true;
else m_bSetNextStation = TRUE;
}
#endif
if (gRetuneCounter)
AudioManager.DoPoliceRadioCrackle();
if (m_bSetNextStation) {
m_bSetNextStation = false;
m_bSetNextStation = FALSE;
m_nPlayingTrack = m_nNextTrack;
m_nNextTrack = GetNextCarTuning();
if (m_nNextTrack == STREAMED_SOUND_CITY_AMBIENT || m_nNextTrack == STREAMED_SOUND_WATER_AMBIENT)
bRadioOff = true;
bRadioOff = TRUE;
if (m_nPlayingTrack == STREAMED_SOUND_CITY_AMBIENT || m_nPlayingTrack == STREAMED_SOUND_WATER_AMBIENT)
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f);
@ -592,7 +611,7 @@ cMusicManager::ServiceGameMode()
if (ChangeRadioChannel()) {
ServiceTrack();
} else {
m_bPlayerInCar = false;
m_bPlayerInCar = FALSE;
if (FindPlayerVehicle())
FindPlayerVehicle()->m_nRadioStation = m_nNextTrack;
m_nNextTrack = NO_TRACK;
@ -601,7 +620,7 @@ cMusicManager::ServiceGameMode()
if (TheCamera.pTargetEntity != nil) {
float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr();
if (DistToTargetSq >= SQR(55.0f)) {
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
} else if (DistToTargetSq >= SQR(10.0f)) {
volume = ((45.0f - (Sqrt(DistToTargetSq) - 10.0f)) / 45.0f * 100.0f);
uint8 pan;
@ -616,17 +635,17 @@ cMusicManager::ServiceGameMode()
}
if (gRetuneCounter)
volume /= 4;
SampleManager.SetStreamedVolumeAndPan(volume, pan, 0, 0);
SampleManager.SetStreamedVolumeAndPan(volume, pan, FALSE);
} else if (AudioManager.ShouldDuckMissionAudio()) {
SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(25, 63, FALSE);
} else if (gRetuneCounter) {
SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(25, 63, FALSE);
} else {
SampleManager.SetStreamedVolumeAndPan(100, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(100, 63, FALSE);
}
}
} else if (AudioManager.ShouldDuckMissionAudio()) {
SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(25, 63, FALSE);
nFramesSinceCutsceneEnded = 0;
} else {
if (nFramesSinceCutsceneEnded == -1) {
@ -643,7 +662,7 @@ cMusicManager::ServiceGameMode()
}
if (gRetuneCounter != 0)
volume /= 4;
SampleManager.SetStreamedVolumeAndPan(volume, 63, 0, 0);
SampleManager.SetStreamedVolumeAndPan(volume, 63, FALSE);
}
return;
}
@ -663,8 +682,8 @@ cMusicManager::ServiceGameMode()
m_nNextTrack = m_nRadioStationScript;
if (FindPlayerVehicle()->m_nRadioStation == m_nNextTrack) {
m_nPlayingTrack = NO_TRACK;
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.StopStreamedFile(0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
SampleManager.StopStreamedFile();
}
if (m_nRadioPosition != -1) {
m_aTracks[m_nNextTrack].m_nPosition = m_nRadioPosition;
@ -680,11 +699,11 @@ cMusicManager::ServiceGameMode()
}
if (ChangeRadioChannel()) {
if (m_bRadioSetByScript) {
m_bRadioSetByScript = false;
m_bRadioSetByScript = FALSE;
FindPlayerVehicle()->m_nRadioStation = m_nNextTrack;
}
} else {
m_bPlayerInCar = false;
m_bPlayerInCar = FALSE;
m_nNextTrack = NO_TRACK;
}
}
@ -693,9 +712,9 @@ void
cMusicManager::StopFrontEndTrack()
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_FRONTEND && m_nNextTrack != NO_TRACK) {
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
m_nPlayingTrack = NO_TRACK;
m_nNextTrack = NO_TRACK;
}
@ -709,33 +728,33 @@ cMusicManager::PlayAnnouncement(uint8 announcement)
}
void
cMusicManager::PlayFrontEndTrack(uint8 track, uint8 bPlayInFrontend)
cMusicManager::PlayFrontEndTrack(uint8 track, bool8 bPlayInFrontend)
{
if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS) {
if (m_nMusicMode == MUSICMODE_GAME) {
if (m_nNextTrack != NO_TRACK) {
if (m_bAnnouncementInProgress) {
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
}
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
} else if (m_nMusicMode == MUSICMODE_FRONTEND) {
if (m_nNextTrack != NO_TRACK) {
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
}
m_nPlayingTrack = m_nNextTrack;
m_nNextTrack = track;
m_bPlayInFrontend = !!bPlayInFrontend;
m_bFrontendTrackFinished = false;
m_bDoTrackService = true;
bHasStarted = false;
m_bPlayInFrontend = bPlayInFrontend;
m_bFrontendTrackFinished = FALSE;
m_bDoTrackService = TRUE;
bHasStarted = FALSE;
if (m_nNextTrack < NUM_RADIOS) {
gRetuneCounter = 0;
gNumRetunePresses = 0;
@ -748,10 +767,10 @@ cMusicManager::PreloadCutSceneMusic(uint8 track)
{
if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && m_nMusicMode == MUSICMODE_CUTSCENE) {
AudioManager.ResetPoliceRadio();
while (SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile(0);
SampleManager.PreloadStreamedFile(track, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0);
while (SampleManager.IsStreamPlaying())
SampleManager.StopStreamedFile();
SampleManager.PreloadStreamedFile(track);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE);
m_nNextTrack = track;
}
}
@ -760,14 +779,14 @@ void
cMusicManager::PlayPreloadedCutSceneMusic(void)
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE)
SampleManager.StartPreloadedStreamedFile(0);
SampleManager.StartPreloadedStreamedFile();
}
void
cMusicManager::StopCutSceneMusic(void)
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) {
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
m_nNextTrack = NO_TRACK;
}
}
@ -787,7 +806,7 @@ cMusicManager::GetTrackStartPos(uint8 track)
}
bool
bool8
cMusicManager::UsesPoliceRadio(CVehicle *veh)
{
switch (veh->GetModelIndex())
@ -798,9 +817,9 @@ cMusicManager::UsesPoliceRadio(CVehicle *veh)
case MI_PREDATOR:
case MI_RHINO:
case MI_BARRACKS:
return true;
return TRUE;
}
return false;
return FALSE;
}
void
@ -810,19 +829,19 @@ cMusicManager::ServiceAmbience()
if (m_bAnnouncementInProgress) {
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
}
if (m_nNextTrack < RADIO_OFF) {
if (SampleManager.IsStreamPlaying(0)) {
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
if (SampleManager.IsStreamPlaying()) {
m_aTracks[m_nNextTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
m_nNextTrack = NO_TRACK;
return;
}
m_nNextTrack = RADIO_OFF;
}
if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING && !SampleManager.IsStreamPlaying(0)) {
if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING && !SampleManager.IsStreamPlaying()) {
m_nNextTrack = NO_TRACK;
return;
}
@ -831,31 +850,31 @@ cMusicManager::ServiceAmbience()
m_nNextTrack = TheCamera.DistanceToWater <= 45.0f ? STREAMED_SOUND_WATER_AMBIENT : STREAMED_SOUND_CITY_AMBIENT;
if (m_nNextTrack == m_nPlayingTrack) {
ComputeAmbienceVol(false, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
ComputeAmbienceVol(FALSE, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
if (m_bVerifyAmbienceTrackStartedToPlay) {
if (SampleManager.IsStreamPlaying(0))
m_bVerifyAmbienceTrackStartedToPlay = false;
if (SampleManager.IsStreamPlaying())
m_bVerifyAmbienceTrackStartedToPlay = FALSE;
} else ServiceTrack();
} else {
if (m_nPlayingTrack < TOTAL_STREAMED_SOUNDS) {
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
}
uint32 pos = GetTrackStartPos(m_nNextTrack);
SampleManager.SetStreamedVolumeAndPan(0, 63, 1, 0);
if (SampleManager.StartStreamedFile(m_nNextTrack, pos, 0)) {
ComputeAmbienceVol(true, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
m_bVerifyAmbienceTrackStartedToPlay = true;
SampleManager.SetStreamedVolumeAndPan(0, 63, TRUE);
if (SampleManager.StartStreamedFile(m_nNextTrack, pos)) {
ComputeAmbienceVol(TRUE, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, TRUE);
m_bVerifyAmbienceTrackStartedToPlay = TRUE;
} else
m_nNextTrack = NO_TRACK;
}
}
void
cMusicManager::ComputeAmbienceVol(uint8 reset, uint8 &outVolume)
cMusicManager::ComputeAmbienceVol(bool8 reset, uint8 &outVolume)
{
static float fVol = 0.0f;
@ -878,49 +897,49 @@ void
cMusicManager::ServiceTrack()
{
if (m_bDoTrackService) {
if (!SampleManager.IsStreamPlaying(0))
SampleManager.StartStreamedFile(m_nNextTrack, 0, 0);
if (!SampleManager.IsStreamPlaying())
SampleManager.StartStreamedFile(m_nNextTrack, 0);
}
}
bool
bool8
cMusicManager::ServiceAnnouncement()
{
static int8 cCheck = 0;
if (m_bAnnouncementInProgress) {
if (!SampleManager.IsStreamPlaying(0)) {
if (!SampleManager.IsStreamPlaying()) {
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_bAnnouncementInProgress = FALSE;
}
return true;
return TRUE;
}
if (++cCheck >= 30) {
cCheck = 0;
int pos = SampleManager.GetStreamedFilePosition(0);
if (SampleManager.IsStreamPlaying(0)) {
int pos = SampleManager.GetStreamedFilePosition();
if (SampleManager.IsStreamPlaying()) {
if (m_nNextTrack != NO_TRACK) {
m_aTracks[m_nNextTrack].m_nPosition = pos;
m_aTracks[m_nNextTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
SampleManager.StopStreamedFile(0);
SampleManager.StopStreamedFile();
}
}
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
if (SampleManager.StartStreamedFile(m_nAnnouncement, 0, 0)) {
SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, 0, 0);
m_bAnnouncementInProgress = true;
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
if (SampleManager.StartStreamedFile(m_nAnnouncement, 0)) {
SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, FALSE);
m_bAnnouncementInProgress = TRUE;
m_nPlayingTrack = m_nNextTrack;
m_nNextTrack = m_nAnnouncement;
return true;
return TRUE;
}
if (cCheck != 0) cCheck--;
else cCheck = 30;
return false;
return FALSE;
}
return false;
return FALSE;
}
uint8
@ -930,7 +949,7 @@ cMusicManager::GetCarTuning()
if (veh == nil) return RADIO_OFF;
if (UsesPoliceRadio(veh)) return POLICE_RADIO;
if (veh->m_nRadioStation == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable())
veh->m_nRadioStation = AudioManager.GetRandomNumber(2) % USERTRACK;
veh->m_nRadioStation = AudioManager.m_anRandomTable[2] % USERTRACK;
return veh->m_nRadioStation;
}
@ -987,21 +1006,21 @@ cMusicManager::GetNextCarTuning()
return veh->m_nRadioStation;
}
bool
bool8
cMusicManager::ChangeRadioChannel()
{
if (m_nNextTrack != m_nPlayingTrack) {
if (m_nPlayingTrack < TOTAL_STREAMED_SOUNDS) {
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition();
m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.StopStreamedFile(0);
SampleManager.SetStreamedVolumeAndPan(0, 63, FALSE);
SampleManager.StopStreamedFile();
}
if (SampleManager.IsStreamPlaying(0))
return false;
if (!SampleManager.StartStreamedFile(m_nNextTrack, GetTrackStartPos(m_nNextTrack), 0))
return false;
SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, 0, 0);
if (SampleManager.IsStreamPlaying())
return FALSE;
if (!SampleManager.StartStreamedFile(m_nNextTrack, GetTrackStartPos(m_nNextTrack)))
return FALSE;
SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, FALSE);
}
return true;
return TRUE;
}

View File

@ -15,48 +15,48 @@ class CVehicle;
class cMusicManager
{
public:
bool m_bIsInitialised;
bool m_bDisabled;
bool8 m_bIsInitialised;
bool8 m_bDisabled;
uint8 m_nMusicMode;
uint8 m_nNextTrack;
uint8 m_nPlayingTrack;
bool m_bFrontendTrackFinished;
bool m_bPlayInFrontend;
bool m_bSetNextStation;
bool8 m_bFrontendTrackFinished;
bool8 m_bPlayInFrontend;
bool8 m_bSetNextStation;
uint8 m_nAnnouncement;
bool m_bPreviousPlayerInCar;
bool m_bPlayerInCar;
bool m_bAnnouncementInProgress;
bool8 m_bPreviousPlayerInCar;
bool8 m_bPlayerInCar;
bool8 m_bAnnouncementInProgress;
tStreamedSample m_aTracks[TOTAL_STREAMED_SOUNDS];
bool m_bResetTimers;
bool8 m_bResetTimers;
uint32 m_nResetTime;
uint32 m_nLastTrackServiceTime;
uint32 m_nTimer;
bool m_bDoTrackService;
bool m_bIgnoreTimeDelay;
bool m_bVerifyAmbienceTrackStartedToPlay;
bool m_bRadioSetByScript;
bool8 m_bDoTrackService;
bool8 m_bIgnoreTimeDelay;
bool8 m_bVerifyAmbienceTrackStartedToPlay;
bool8 m_bRadioSetByScript;
uint8 m_nRadioStationScript;
int32 m_nRadioPosition;
uint8 m_nRadioInCar;
public:
cMusicManager();
bool IsInitialised() { return m_bIsInitialised; }
bool8 IsInitialised() { return m_bIsInitialised; }
uint32 GetMusicMode() { return m_nMusicMode; }
uint8 GetNextTrack() { return m_nNextTrack; }
bool Initialise();
bool8 Initialise();
void Terminate();
void ChangeMusicMode(uint8 mode);
void StopFrontEndTrack();
bool PlayerInCar();
bool8 PlayerInCar();
void DisplayRadioStationName();
void PlayAnnouncement(uint8);
void PlayFrontEndTrack(uint8, uint8);
void PlayFrontEndTrack(uint8, bool8);
void PreloadCutSceneMusic(uint8);
void PlayPreloadedCutSceneMusic(void);
void StopCutSceneMusic(void);
@ -66,22 +66,22 @@ public:
void ResetMusicAfterReload();
void ResetTimers(int32);
void ResetTimers(uint32);
void Service();
void ServiceFrontEndMode();
void ServiceGameMode();
void ServiceAmbience();
void ServiceTrack();
bool UsesPoliceRadio(CVehicle *veh);
bool8 UsesPoliceRadio(CVehicle *veh);
uint32 GetTrackStartPos(uint8);
void ComputeAmbienceVol(uint8 reset, uint8& outVolume);
bool ServiceAnnouncement();
void ComputeAmbienceVol(bool8 reset, uint8& outVolume);
bool8 ServiceAnnouncement();
uint8 GetCarTuning();
uint8 GetNextCarTuning();
bool ChangeRadioChannel();
bool8 ChangeRadioChannel();
};
VALIDATE_SIZE(cMusicManager, 0x95C);

View File

@ -7,7 +7,7 @@
#include "AudioSamples.h"
#include "MusicManager.h"
#include "PlayerPed.h"
#include "PoliceRadio.h"
#include "PolRadio.h"
#include "Replay.h"
#include "Vehicle.h"
#include "World.h"
@ -15,9 +15,6 @@
#include "sampman.h"
#include "Wanted.h"
const int channels = ARRAY_SIZE(AudioManager.m_asActiveSamples);
const int policeChannel = channels + 1;
struct tPoliceRadioZone {
char m_aName[8];
uint32 m_nSampleIndex;
@ -28,9 +25,9 @@ tPoliceRadioZone ZoneSfx[NUMAUDIOZONES];
char SubZo2Label[8];
char SubZo3Label[8];
int32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 g_nMissionAudioPlayingStatus = 2;
uint8 gSpecialSuspectLastSeenReport;
uint32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 g_nMissionAudioPlayingStatus = PLAY_STATUS_FINISHED;
bool8 gSpecialSuspectLastSeenReport;
uint32 gMinTimeToNextReport[NUM_CRIME_TYPES];
void
@ -88,14 +85,12 @@ cAudioManager::InitialisePoliceRadioZones()
void
cAudioManager::InitialisePoliceRadio()
{
m_sPoliceRadioQueue.policeChannelTimer = 0;
m_sPoliceRadioQueue.policeChannelTimerSeconds = 0;
m_sPoliceRadioQueue.policeChannelCounterSeconds = 0;
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
m_sPoliceRadioQueue.Reset();
for (int32 i = 0; i < ARRAY_SIZE(m_aCrimes); i++)
m_aCrimes[i].type = CRIME_NONE;
SampleManager.SetChannelReverbFlag(policeChannel, false);
gSpecialSuspectLastSeenReport = false;
SampleManager.SetChannelReverbFlag(CHANNEL_POLICE_RADIO, FALSE);
gSpecialSuspectLastSeenReport = FALSE;
for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++)
gMinTimeToNextReport[i] = m_FrameCounter;
}
@ -104,22 +99,22 @@ void
cAudioManager::ResetPoliceRadio()
{
if (!m_bIsInitialised) return;
if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
InitialisePoliceRadio();
}
void
cAudioManager::SetMissionScriptPoliceAudio(int32 sfx) const
cAudioManager::SetMissionScriptPoliceAudio(uint32 sfx)
{
if (!m_bIsInitialised) return;
if (g_nMissionAudioPlayingStatus != 1) {
g_nMissionAudioPlayingStatus = 0;
if (g_nMissionAudioPlayingStatus != PLAY_STATUS_PLAYING) {
g_nMissionAudioPlayingStatus = PLAY_STATUS_STOPPED;
g_nMissionAudioSfx = sfx;
}
}
int8
cAudioManager::GetMissionScriptPoliceAudioPlayingStatus() const
cAudioManager::GetMissionScriptPoliceAudioPlayingStatus()
{
return g_nMissionAudioPlayingStatus;
}
@ -131,19 +126,18 @@ cAudioManager::DoPoliceRadioCrackle()
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_nSampleIndex = SFX_POLICE_RADIO_CRACKLE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = true;
m_sQueueSample.m_nReleasingVolumeModificator = 10;
m_sQueueSample.m_bIs2D = TRUE;
m_sQueueSample.m_nPriority = 10;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_nVolume = m_anRandomTable[2] % 20 + 15;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nEmittingVolume = m_sQueueSample.m_nVolume;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_POLICE_RADIO_CRACKLE);
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_nOffset = 63;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bRequireReflection = false;
SET_EMITTING_VOLUME(m_sQueueSample.m_nVolume);
SET_LOOP_OFFSETS(SFX_POLICE_RADIO_CRACKLE)
m_sQueueSample.m_bStatic = FALSE;
m_sQueueSample.m_bReverb = FALSE;
m_sQueueSample.m_nPan = 63;
m_sQueueSample.m_nFramesToPlay = 3;
SET_SOUND_REFLECTION(FALSE);
AddSampleToRequestedQueue();
}
@ -155,17 +149,21 @@ cAudioManager::ServicePoliceRadio()
if(!m_bIsInitialised) return;
if(m_nUserPause == 0) {
bool crimeReport = SetupCrimeReport();
if(!m_bIsPaused) {
bool8 crimeReport = SetupCrimeReport();
#ifdef FIX_BUGS // Crash at 0x5fe6ef
if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
return;
#endif
wantedLevel = FindPlayerPed()->m_pWanted->GetWantedLevel();
if(!crimeReport) {
if(wantedLevel != 0) {
if(nLastSeen != 0) {
--nLastSeen;
if (!crimeReport) {
if (wantedLevel != 0) {
if (nLastSeen != 0) {
#ifdef FIX_BUGS
nLastSeen -= CTimer::GetLogicalFramesPassed();
#else
nLastSeen--;
#endif
} else {
nLastSeen = m_anRandomTable[1] % 1000 + 2000;
SetupSuspectLastSeenReport();
@ -179,104 +177,133 @@ cAudioManager::ServicePoliceRadio()
void
cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
{
bool processed = false;
bool8 processed = FALSE;
uint32 sample;
int32 freq;
uint32 freq;
static int cWait = 0;
static bool bChannelOpen = false;
static uint8 bMissionAudioPhysicalPlayingStatus = 0;
static int32 PoliceChannelFreq = 5500;
static bool8 bChannelOpen = FALSE;
static uint8 bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_STOPPED;
static uint32 PoliceChannelFreq = 5500;
if (!m_bIsInitialised) return;
if (m_nUserPause != 0) {
if (SampleManager.GetChannelUsedFlag(policeChannel)) SampleManager.StopChannel(policeChannel);
if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 &&
SampleManager.IsStreamPlaying(1)) {
SampleManager.PauseStream(1, 1);
}
if (m_bIsPaused) {
#ifdef GTA_PS2
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO))
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, 0);
#else
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) SampleManager.StopChannel(CHANNEL_POLICE_RADIO);
if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_PLAYING &&
SampleManager.IsStreamPlaying(1))
SampleManager.PauseStream(TRUE, 1);
#endif
} else {
if (m_nPreviousUserPause && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES &&
bMissionAudioPhysicalPlayingStatus == 1) {
SampleManager.PauseStream(0, 1);
}
if (m_sPoliceRadioQueue.policeChannelTimer == 0) bChannelOpen = false;
#ifdef GTA_PS2
if (m_bWasPaused)
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, PoliceChannelFreq);
#else
if (m_bWasPaused && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES &&
bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_PLAYING)
SampleManager.PauseStream(FALSE, 1);
#endif
if (m_sPoliceRadioQueue.m_nSamplesInQueue == 0) bChannelOpen = FALSE;
if (cWait) {
#ifdef FIX_BUGS
cWait -= CTimer::GetLogicalFramesPassed();
#else
--cWait;
#endif
return;
}
if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && !bChannelOpen) {
if (g_nMissionAudioPlayingStatus) {
if (g_nMissionAudioPlayingStatus == 1 && !bMissionAudioPhysicalPlayingStatus &&
if (g_nMissionAudioPlayingStatus != PLAY_STATUS_STOPPED) {
if (g_nMissionAudioPlayingStatus == PLAY_STATUS_PLAYING && bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_STOPPED &&
#ifdef GTA_PS2
SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) {
#else
SampleManager.IsStreamPlaying(1)) {
bMissionAudioPhysicalPlayingStatus = 1;
#endif
bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_PLAYING;
}
if (bMissionAudioPhysicalPlayingStatus == 1) {
if (bMissionAudioPhysicalPlayingStatus == PLAY_STATUS_PLAYING) {
#ifdef GTA_PS2
if (SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) {
#else
if (SampleManager.IsStreamPlaying(1)) {
#endif
DoPoliceRadioCrackle();
} else {
bMissionAudioPhysicalPlayingStatus = 2;
g_nMissionAudioPlayingStatus = 2;
bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_FINISHED;
g_nMissionAudioPlayingStatus = PLAY_STATUS_FINISHED;
g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
cWait = 30;
}
return;
}
} else if (!SampleManager.GetChannelUsedFlag(policeChannel)) {
} else if (!SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO)) {
#ifdef GTA_PS2
SampleManager.InitialiseChannel(CHANNEL_POLICE_RADIO, g_nMissionAudioSfx, SFX_BANK_PED_COMMENTS);
PoliceChannelFreq = SampleManager.GetSampleBaseFrequency(g_nMissionAudioSfx);
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, PoliceChannelFreq);
SampleManager.SetChannelVolume(CHANNEL_POLICE_RADIO, MAX_VOLUME);
SampleManager.SetChannelPan(CHANNEL_POLICE_RADIO, 63);
SampleManager.StartChannel(CHANNEL_POLICE_RADIO);
#else
SampleManager.PreloadStreamedFile(g_nMissionAudioSfx, 1);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 1);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, TRUE, 1);
SampleManager.StartPreloadedStreamedFile(1);
g_nMissionAudioPlayingStatus = 1;
bMissionAudioPhysicalPlayingStatus = 0;
#endif
g_nMissionAudioPlayingStatus = PLAY_STATUS_PLAYING;
bMissionAudioPhysicalPlayingStatus = PLAY_STATUS_STOPPED;
return;
}
}
if (bChannelOpen) DoPoliceRadioCrackle();
if ((g_nMissionAudioSfx == TOTAL_AUDIO_SAMPLES || g_nMissionAudioPlayingStatus != 1) &&
!SampleManager.GetChannelUsedFlag(policeChannel) && m_sPoliceRadioQueue.policeChannelTimer) {
if (m_sPoliceRadioQueue.policeChannelTimer) {
sample = m_sPoliceRadioQueue.crimesSamples[m_sPoliceRadioQueue.policeChannelCounterSeconds];
m_sPoliceRadioQueue.policeChannelTimer--;
m_sPoliceRadioQueue.policeChannelCounterSeconds = (m_sPoliceRadioQueue.policeChannelCounterSeconds + 1) % 60;
} else {
sample = TOTAL_AUDIO_SAMPLES;
}
if ((g_nMissionAudioSfx == TOTAL_AUDIO_SAMPLES || g_nMissionAudioPlayingStatus != PLAY_STATUS_PLAYING) &&
!SampleManager.GetChannelUsedFlag(CHANNEL_POLICE_RADIO) && m_sPoliceRadioQueue.m_nSamplesInQueue != 0) {
sample = m_sPoliceRadioQueue.Remove();
if (wantedLevel == 0) {
if (gSpecialSuspectLastSeenReport) {
gSpecialSuspectLastSeenReport = 0;
gSpecialSuspectLastSeenReport = FALSE;
} else if (((sample >= SFX_POLICE_RADIO_MESSAGE_NOISE_1) && (sample <= SFX_POLICE_RADIO_MESSAGE_NOISE_3)) || sample == TOTAL_AUDIO_SAMPLES) {
bChannelOpen = false;
processed = true;
bChannelOpen = FALSE;
processed = TRUE;
}
}
if (sample == TOTAL_AUDIO_SAMPLES) {
if (!processed) cWait = 30;
} else {
SampleManager.InitialiseChannel(policeChannel, sample, 0);
SampleManager.InitialiseChannel(CHANNEL_POLICE_RADIO, sample, SFX_BANK_0);
switch (sample) {
case SFX_POLICE_RADIO_MESSAGE_NOISE_1:
case SFX_POLICE_RADIO_MESSAGE_NOISE_2:
case SFX_POLICE_RADIO_MESSAGE_NOISE_3:
freq = m_anRandomTable[4] % 2000 + 10025;
bChannelOpen = bChannelOpen == false;
bChannelOpen = bChannelOpen == FALSE;
break;
default: freq = SampleManager.GetSampleBaseFrequency(sample); break;
}
PoliceChannelFreq = freq;
SampleManager.SetChannelFrequency(policeChannel, freq);
SampleManager.SetChannelVolume(policeChannel, 100);
SampleManager.SetChannelPan(policeChannel, 63);
SampleManager.SetChannelLoopCount(policeChannel, 1);
SampleManager.SetChannelLoopPoints(policeChannel, 0, -1);
SampleManager.StartChannel(policeChannel);
#ifdef USE_TIME_SCALE_FOR_AUDIO
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq * CTimer::GetTimeScale());
#else
SampleManager.SetChannelFrequency(CHANNEL_POLICE_RADIO, freq);
#endif
SampleManager.SetChannelVolume(CHANNEL_POLICE_RADIO, 100);
SampleManager.SetChannelPan(CHANNEL_POLICE_RADIO, 63);
SampleManager.SetChannelLoopCount(CHANNEL_POLICE_RADIO, 1);
#ifndef GTA_PS2
SampleManager.SetChannelLoopPoints(CHANNEL_POLICE_RADIO, 0, -1);
#endif
SampleManager.StartChannel(CHANNEL_POLICE_RADIO);
}
if (processed) ResetPoliceRadio();
}
}
}
bool
bool8
cAudioManager::SetupCrimeReport()
{
int16 audioZoneId;
@ -288,23 +315,23 @@ cAudioManager::SetupCrimeReport()
float quarterX;
float quarterY;
int i;
int32 sampleIndex;
bool processed = false;
uint32 sampleIndex;
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 (POLICE_RADIO_QUEUE_MAX_SAMPLES - m_sPoliceRadioQueue.m_nSamplesInQueue <= 9) {
AgeCrimes();
return true;
return TRUE;
}
for (i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE)
for (i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {
if (m_aCrimes[i].type != CRIME_NONE)
break;
}
if (i == ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) return false;
audioZoneId = CTheZones::FindAudioZone(&m_sPoliceRadioQueue.crimes[i].position);
if (i == ARRAY_SIZE(m_aCrimes)) return FALSE;
audioZoneId = CTheZones::FindAudioZone(&m_aCrimes[i].position);
if (audioZoneId >= 0 && audioZoneId < NUMAUDIOZONES) {
zone = CTheZones::GetAudioZone(audioZoneId);
for (int j = 0; j < NUMAUDIOZONES; j++) {
@ -313,14 +340,14 @@ cAudioManager::SetupCrimeReport()
m_sPoliceRadioQueue.Add(m_anRandomTable[4] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(m_anRandomTable[0] % 3 + SFX_WEVE_GOT);
m_sPoliceRadioQueue.Add(m_anRandomTable[1] % 2 + SFX_A_10_1);
switch (m_sPoliceRadioQueue.crimes[i].type) {
case CRIME_PED_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_PED; break;
case CRIME_COP_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_HIT_COP; break;
case CRIME_VEHICLE_BURNED: m_sPoliceRadioQueue.crimes[i].type = CRIME_STEAL_CAR; break;
case CRIME_DESTROYED_CESSNA: m_sPoliceRadioQueue.crimes[i].type = CRIME_SHOOT_HELI; break;
switch (m_aCrimes[i].type) {
case CRIME_PED_BURNED: m_aCrimes[i].type = CRIME_HIT_PED; break;
case CRIME_COP_BURNED: m_aCrimes[i].type = CRIME_HIT_COP; break;
case CRIME_VEHICLE_BURNED: m_aCrimes[i].type = CRIME_STEAL_CAR; break;
case CRIME_DESTROYED_CESSNA: m_aCrimes[i].type = CRIME_SHOOT_HELI; break;
default: break;
}
m_sPoliceRadioQueue.Add(m_sPoliceRadioQueue.crimes[i].type + SFX_CRIME_1 - 1);
m_sPoliceRadioQueue.Add(m_aCrimes[i].type + SFX_CRIME_1 - 1);
m_sPoliceRadioQueue.Add(SFX_IN);
if (sampleIndex == SFX_POLICE_RADIO_SHORESIDE_VALE &&
(strcmp(zone->name, SubZo2Label) == 0 || strcmp(zone->name, SubZo3Label) == 0)) {
@ -334,17 +361,17 @@ cAudioManager::SetupCrimeReport()
quarterX = 0.25f * rangeX;
quarterY = 0.25f * rangeY;
if (m_sPoliceRadioQueue.crimes[i].position.y > halfY + quarterY) {
if (m_aCrimes[i].position.y > halfY + quarterY) {
m_sPoliceRadioQueue.Add(SFX_NORTH);
processed = true;
} else if (m_sPoliceRadioQueue.crimes[i].position.y < halfY - quarterY) {
processed = TRUE;
} else if (m_aCrimes[i].position.y < halfY - quarterY) {
m_sPoliceRadioQueue.Add(SFX_SOUTH);
processed = true;
processed = TRUE;
}
if (m_sPoliceRadioQueue.crimes[i].position.x > halfX + quarterX)
if (m_aCrimes[i].position.x > halfX + quarterX)
m_sPoliceRadioQueue.Add(SFX_EAST);
else if (m_sPoliceRadioQueue.crimes[i].position.x < halfX - quarterX)
else if (m_aCrimes[i].position.x < halfX - quarterX)
m_sPoliceRadioQueue.Add(SFX_WEST);
else if (!processed)
m_sPoliceRadioQueue.Add(SFX_CENTRAL);
@ -357,180 +384,180 @@ cAudioManager::SetupCrimeReport()
}
}
}
m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
m_aCrimes[i].type = CRIME_NONE;
AgeCrimes();
return true;
return TRUE;
}
Const uint32 gCarColourTable[][3] = {
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_BLUE},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_GREY},
#else
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#else
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#endif
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}
};
void
cAudioManager::SetupSuspectLastSeenReport()
{
CVehicle *veh;
uint8 color1;
int32 main_color;
int32 sample;
uint32 main_color;
uint32 sample;
int32 color_pre_modifier;
int32 color_post_modifier;
const int32 gCarColourTable[][3] = {
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLACK, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_WHITE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_BRIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, SFX_POLICE_RADIO_GREY},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_RED, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_ORANGE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_YELLOW, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_GREEN, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_BLUE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_BLUE},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, SFX_POLICE_RADIO_GREY},
#else
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_PURPLE, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#else
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
#endif
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#ifdef FIX_BUGS
{SFX_POLICE_RADIO_LIGHT, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#else
{TOTAL_AUDIO_SAMPLES, SFX_POLICE_RADIO_SILVER, TOTAL_AUDIO_SAMPLES},
#endif
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_LIGHT, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES},
{SFX_POLICE_RADIO_DARK, TOTAL_AUDIO_SAMPLES, TOTAL_AUDIO_SAMPLES}
};
uint32 color_pre_modifier;
uint32 color_post_modifier;
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
veh = FindPlayerVehicle();
if (veh != nil) {
if (60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
if (POLICE_RADIO_QUEUE_MAX_SAMPLES - m_sPoliceRadioQueue.m_nSamplesInQueue > 9) {
color1 = veh->m_currentColour1;
if (color1 >= ARRAY_SIZE(gCarColourTable)) {
debug("\n *** UNKNOWN CAR COLOUR %d *** ", color1);
@ -663,7 +690,7 @@ cAudioManager::SetupSuspectLastSeenReport()
m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
}
}
} else if (60 - m_sPoliceRadioQueue.policeChannelTimer > 4) {
} else if (POLICE_RADIO_QUEUE_MAX_SAMPLES - m_sPoliceRadioQueue.m_nSamplesInQueue > 4) {
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_SUSPECT);
m_sPoliceRadioQueue.Add(SFX_POLICE_RADIO_ON_FOOT);
@ -673,19 +700,17 @@ cAudioManager::SetupSuspectLastSeenReport()
}
}
void
cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
{
int32 lastCrime = ARRAY_SIZE(m_sPoliceRadioQueue.crimes);
int32 lastCrime = ARRAY_SIZE(m_aCrimes);
if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->GetWantedLevel() > 0 &&
(type > CRIME_NONE || type < NUM_CRIME_TYPES) && m_FrameCounter >= gMinTimeToNextReport[type]) {
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
if (m_sPoliceRadioQueue.crimes[i].type) {
if (m_sPoliceRadioQueue.crimes[i].type == type) {
m_sPoliceRadioQueue.crimes[i].position = pos;
m_sPoliceRadioQueue.crimes[i].timer = 0;
for (int32 i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {
if (m_aCrimes[i].type != CRIME_NONE) {
if (m_aCrimes[i].type == type) {
m_aCrimes[i].position = pos;
m_aCrimes[i].timer = 0;
return;
}
} else {
@ -693,10 +718,10 @@ cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
}
}
if (lastCrime < ARRAY_SIZE(m_sPoliceRadioQueue.crimes)) {
m_sPoliceRadioQueue.crimes[lastCrime].type = type;
m_sPoliceRadioQueue.crimes[lastCrime].position = pos;
m_sPoliceRadioQueue.crimes[lastCrime].timer = 0;
if (lastCrime < ARRAY_SIZE(m_aCrimes)) {
m_aCrimes[lastCrime].type = type;
m_aCrimes[lastCrime].position = pos;
m_aCrimes[lastCrime].timer = 0;
gMinTimeToNextReport[type] = m_FrameCounter + 500;
}
}
@ -713,13 +738,13 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
float halfY;
float quarterX;
float quarterY;
int32 sample;
bool processed = false;
uint32 sample;
bool8 processed = FALSE;
CVector vec = CVector(x, y, z);
if (!m_bIsInitialised) return;
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && 60 - m_sPoliceRadioQueue.policeChannelTimer > 9) {
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && POLICE_RADIO_QUEUE_MAX_SAMPLES - m_sPoliceRadioQueue.m_nSamplesInQueue > 9) {
audioZone = CTheZones::FindAudioZone(&vec);
if (audioZone >= 0 && audioZone < NUMAUDIOZONES) {
zone = CTheZones::GetAudioZone(audioZone);
@ -745,10 +770,10 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
if (vec.y > halfY + quarterY) {
m_sPoliceRadioQueue.Add(SFX_NORTH);
processed = true;
processed = TRUE;
} else if (vec.y < halfY - quarterY) {
m_sPoliceRadioQueue.Add(SFX_SOUTH);
processed = true;
processed = TRUE;
}
if (vec.x > halfX + quarterX)
@ -761,7 +786,7 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
m_sPoliceRadioQueue.Add(sample);
m_sPoliceRadioQueue.Add(m_anRandomTable[2] % 3 + SFX_POLICE_RADIO_MESSAGE_NOISE_1);
m_sPoliceRadioQueue.Add(TOTAL_AUDIO_SAMPLES);
gSpecialSuspectLastSeenReport = true;
gSpecialSuspectLastSeenReport = TRUE;
break;
}
}
@ -772,9 +797,9 @@ cAudioManager::PlaySuspectLastSeen(float x, float y, float z)
void
cAudioManager::AgeCrimes()
{
for (uint8 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++) {
if (m_sPoliceRadioQueue.crimes[i].type != CRIME_NONE) {
if (++m_sPoliceRadioQueue.crimes[i].timer > 1500) m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
for (uint8 i = 0; i < ARRAY_SIZE(m_aCrimes); i++) {
if (m_aCrimes[i].type != CRIME_NONE) {
if (++m_aCrimes[i].timer > 1500) m_aCrimes[i].type = CRIME_NONE;
}
}
}

66
src/audio/PolRadio.h Normal file
View File

@ -0,0 +1,66 @@
#pragma once
#include "Crime.h"
#include "AudioSamples.h"
struct cAMCrime {
int32 type;
CVector position;
uint16 timer;
cAMCrime()
{
type = CRIME_NONE;
position = CVector(0.0f, 0.0f, 0.0f);
timer = 0;
}
};
VALIDATE_SIZE(cAMCrime, 20);
#define POLICE_RADIO_QUEUE_MAX_SAMPLES 60
class cPoliceRadioQueue
{
public:
uint32 m_aSamples[POLICE_RADIO_QUEUE_MAX_SAMPLES];
uint8 m_nSamplesInQueue;
uint8 m_nAddOffset;
uint8 m_nRemoveOffset;
cPoliceRadioQueue()
{
Reset();
}
void Reset()
{
m_nAddOffset = 0;
m_nRemoveOffset = 0;
m_nSamplesInQueue = 0;
}
bool8 Add(uint32 sample)
{
if (m_nSamplesInQueue != POLICE_RADIO_QUEUE_MAX_SAMPLES) {
m_aSamples[m_nAddOffset] = sample;
m_nSamplesInQueue++;
m_nAddOffset = (m_nAddOffset + 1) % POLICE_RADIO_QUEUE_MAX_SAMPLES;
return TRUE;
}
return FALSE;
}
uint32 Remove()
{
if (m_nSamplesInQueue != 0) {
uint32 sample = m_aSamples[m_nRemoveOffset];
m_nSamplesInQueue--;
m_nRemoveOffset = (m_nRemoveOffset + 1) % POLICE_RADIO_QUEUE_MAX_SAMPLES;
return sample;
}
return TOTAL_AUDIO_SAMPLES;
}
};
VALIDATE_SIZE(cPoliceRadioQueue, 244);

View File

@ -1,46 +0,0 @@
#pragma once
#include "Crime.h"
struct cAMCrime {
int32 type;
CVector position;
uint16 timer;
cAMCrime()
{
type = CRIME_NONE;
position = CVector(0.0f, 0.0f, 0.0f);
timer = 0;
}
};
VALIDATE_SIZE(cAMCrime, 20);
class cPoliceRadioQueue
{
public:
int32 crimesSamples[60];
uint8 policeChannelTimer;
uint8 policeChannelTimerSeconds;
uint8 policeChannelCounterSeconds;
cAMCrime crimes[10];
cPoliceRadioQueue()
{
policeChannelTimerSeconds = 0;
policeChannelCounterSeconds = 0;
policeChannelTimer = 0;
}
void Add(uint32 sample)
{
if (policeChannelTimer != 60) {
crimesSamples[policeChannelTimerSeconds] = sample;
policeChannelTimer++;
policeChannelTimerSeconds = (policeChannelTimerSeconds + 1) % 60;
}
}
};
VALIDATE_SIZE(cPoliceRadioQueue, 444);

View File

@ -123,107 +123,109 @@ enum eStreamedSounds
STREAMED_SOUND_CUTSCENE_MARTY_PH4,
STREAMED_SOUND_MISSION_COMPLETED,
STREAMED_SOUND_GAME_COMPLETED,
STREAMED_SOUND_MISSION_LIB_A1,
STREAMED_SOUND_MISSION_LIB_A2,
STREAMED_SOUND_MISSION_LIB_A,
STREAMED_SOUND_MISSION_LIB_B,
STREAMED_SOUND_MISSION_LIB_C,
STREAMED_SOUND_MISSION_LIB_D,
STREAMED_SOUND_MISSION_L2_A,
STREAMED_SOUND_MISSION_J4T_1,
STREAMED_SOUND_MISSION_J4T_2,
STREAMED_SOUND_MISSION_J4T_3,
STREAMED_SOUND_MISSION_J4T_4,
STREAMED_SOUND_MISSION_J4_A,
STREAMED_SOUND_MISSION_J4_B,
STREAMED_SOUND_MISSION_J4_C,
STREAMED_SOUND_MISSION_J4_D,
STREAMED_SOUND_MISSION_J4_E,
STREAMED_SOUND_MISSION_J4_F,
STREAMED_SOUND_MISSION_J6_1,
STREAMED_SOUND_MISSION_J6_A,
STREAMED_SOUND_MISSION_J6_B,
STREAMED_SOUND_MISSION_J6_C,
STREAMED_SOUND_MISSION_J6_D,
STREAMED_SOUND_MISSION_T4_A,
STREAMED_SOUND_MISSION_S1_A,
STREAMED_SOUND_MISSION_S1_A1,
STREAMED_SOUND_MISSION_S1_B,
STREAMED_SOUND_MISSION_S1_C,
STREAMED_SOUND_MISSION_S1_C1,
STREAMED_SOUND_MISSION_S1_D,
STREAMED_SOUND_MISSION_S1_E,
STREAMED_SOUND_MISSION_S1_F,
STREAMED_SOUND_MISSION_S1_G,
STREAMED_SOUND_MISSION_S1_H,
STREAMED_SOUND_MISSION_S1_I,
STREAMED_SOUND_MISSION_S1_J,
STREAMED_SOUND_MISSION_S1_K,
STREAMED_SOUND_MISSION_S1_L,
STREAMED_SOUND_MISSION_S3_A,
STREAMED_SOUND_MISSION_S3_B,
STREAMED_SOUND_MISSION_EL3_A,
STREAMED_SOUND_MISSION_MF1_A,
STREAMED_SOUND_MISSION_MF2_A,
STREAMED_SOUND_MISSION_MF3_A,
STREAMED_SOUND_MISSION_MF3_B,
STREAMED_SOUND_MISSION_MF3_B1,
STREAMED_SOUND_MISSION_MF3_C,
STREAMED_SOUND_MISSION_MF4_A,
STREAMED_SOUND_MISSION_MF4_B,
STREAMED_SOUND_MISSION_MF4_C,
STREAMED_SOUND_MISSION_A1_A,
STREAMED_SOUND_MISSION_A3_A,
STREAMED_SOUND_MISSION_A5_A,
STREAMED_SOUND_MISSION_A4_A,
STREAMED_SOUND_MISSION_A4_B,
STREAMED_SOUND_MISSION_A4_C,
STREAMED_SOUND_MISSION_A4_D,
STREAMED_SOUND_MISSION_K1_A,
STREAMED_SOUND_MISSION_K3_A,
STREAMED_SOUND_MISSION_R1_A,
STREAMED_SOUND_MISSION_R2_A,
STREAMED_SOUND_MISSION_R2_B,
STREAMED_SOUND_MISSION_R2_C,
STREAMED_SOUND_MISSION_R2_D,
STREAMED_SOUND_MISSION_R2_E,
STREAMED_SOUND_MISSION_R2_F,
STREAMED_SOUND_MISSION_R2_G,
STREAMED_SOUND_MISSION_R2_H,
STREAMED_SOUND_MISSION_R5_A,
STREAMED_SOUND_MISSION_R6_A,
STREAMED_SOUND_MISSION_R6_A1,
STREAMED_SOUND_MISSION_R6_B,
STREAMED_SOUND_MISSION_LO2_A,
STREAMED_SOUND_MISSION_LO6_A,
STREAMED_SOUND_MISSION_YD2_A,
STREAMED_SOUND_MISSION_YD2_B,
STREAMED_SOUND_MISSION_YD2_C,
STREAMED_SOUND_MISSION_YD2_C1,
STREAMED_SOUND_MISSION_YD2_D,
STREAMED_SOUND_MISSION_YD2_E,
STREAMED_SOUND_MISSION_YD2_F,
STREAMED_SOUND_MISSION_YD2_G,
STREAMED_SOUND_MISSION_YD2_H,
STREAMED_SOUND_MISSION_YD2_ASS,
STREAMED_SOUND_MISSION_YD2_OK,
STREAMED_SOUND_MISSION_H5_A,
STREAMED_SOUND_MISSION_H5_B,
STREAMED_SOUND_MISSION_H5_C,
STREAMED_SOUND_MISSION_AMMU_A,
STREAMED_SOUND_MISSION_AMMU_B,
STREAMED_SOUND_MISSION_AMMU_C,
STREAMED_SOUND_MISSION_DOOR_1,
STREAMED_SOUND_MISSION_DOOR_2,
STREAMED_SOUND_MISSION_DOOR_3,
STREAMED_SOUND_MISSION_DOOR_4,
STREAMED_SOUND_MISSION_DOOR_5,
STREAMED_SOUND_MISSION_DOOR_6,
STREAMED_SOUND_MISSION_T3_A,
STREAMED_SOUND_MISSION_T3_B,
STREAMED_SOUND_MISSION_T3_C,
STREAMED_SOUND_MISSION_K1_B,
STREAMED_SOUND_MISSION_CAT1,
#ifndef GTA_PS2
SFX_MISSION_LIB_A1,
SFX_MISSION_LIB_A2,
SFX_MISSION_LIB_A,
SFX_MISSION_LIB_B,
SFX_MISSION_LIB_C,
SFX_MISSION_LIB_D,
SFX_MISSION_L2_A,
SFX_MISSION_J4T_1,
SFX_MISSION_J4T_2,
SFX_MISSION_J4T_3,
SFX_MISSION_J4T_4,
SFX_MISSION_J4_A,
SFX_MISSION_J4_B,
SFX_MISSION_J4_C,
SFX_MISSION_J4_D,
SFX_MISSION_J4_E,
SFX_MISSION_J4_F,
SFX_MISSION_J6_1,
SFX_MISSION_J6_A,
SFX_MISSION_J6_B,
SFX_MISSION_J6_C,
SFX_MISSION_J6_D,
SFX_MISSION_T4_A,
SFX_MISSION_S1_A,
SFX_MISSION_S1_A1,
SFX_MISSION_S1_B,
SFX_MISSION_S1_C,
SFX_MISSION_S1_C1,
SFX_MISSION_S1_D,
SFX_MISSION_S1_E,
SFX_MISSION_S1_F,
SFX_MISSION_S1_G,
SFX_MISSION_S1_H,
SFX_MISSION_S1_I,
SFX_MISSION_S1_J,
SFX_MISSION_S1_K,
SFX_MISSION_S1_L,
SFX_MISSION_S3_A,
SFX_MISSION_S3_B,
SFX_MISSION_EL3_A,
SFX_MISSION_MF1_A,
SFX_MISSION_MF2_A,
SFX_MISSION_MF3_A,
SFX_MISSION_MF3_B,
SFX_MISSION_MF3_B1,
SFX_MISSION_MF3_C,
SFX_MISSION_MF4_A,
SFX_MISSION_MF4_B,
SFX_MISSION_MF4_C,
SFX_MISSION_A1_A,
SFX_MISSION_A3_A,
SFX_MISSION_A5_A,
SFX_MISSION_A4_A,
SFX_MISSION_A4_B,
SFX_MISSION_A4_C,
SFX_MISSION_A4_D,
SFX_MISSION_K1_A,
SFX_MISSION_K3_A,
SFX_MISSION_R1_A,
SFX_MISSION_R2_A,
SFX_MISSION_R2_B,
SFX_MISSION_R2_C,
SFX_MISSION_R2_D,
SFX_MISSION_R2_E,
SFX_MISSION_R2_F,
SFX_MISSION_R2_G,
SFX_MISSION_R2_H,
SFX_MISSION_R5_A,
SFX_MISSION_R6_A,
SFX_MISSION_R6_A1,
SFX_MISSION_R6_B,
SFX_MISSION_LO2_A,
SFX_MISSION_LO6_A,
SFX_MISSION_YD2_A,
SFX_MISSION_YD2_B,
SFX_MISSION_YD2_C,
SFX_MISSION_YD2_C1,
SFX_MISSION_YD2_D,
SFX_MISSION_YD2_E,
SFX_MISSION_YD2_F,
SFX_MISSION_YD2_G,
SFX_MISSION_YD2_H,
SFX_MISSION_YD2_ASS,
SFX_MISSION_YD2_OK,
SFX_MISSION_H5_A,
SFX_MISSION_H5_B,
SFX_MISSION_H5_C,
SFX_MISSION_AMMU_A,
SFX_MISSION_AMMU_B,
SFX_MISSION_AMMU_C,
SFX_MISSION_DOOR_1,
SFX_MISSION_DOOR_2,
SFX_MISSION_DOOR_3,
SFX_MISSION_DOOR_4,
SFX_MISSION_DOOR_5,
SFX_MISSION_DOOR_6,
SFX_MISSION_T3_A,
SFX_MISSION_T3_B,
SFX_MISSION_T3_C,
SFX_MISSION_K1_B,
SFX_MISSION_CAT1,
#endif
TOTAL_STREAMED_SOUNDS,
NO_TRACK,
};
@ -254,3 +256,25 @@ enum eAudioType
AUDIOTYPE_POLICERADIO,
TOTAL_AUDIO_TYPES,
};
#ifdef GTA_PS2
enum
{
NUM_CHANNELS_GENERIC = 43,
CHANNEL_POLICE_RADIO = NUM_CHANNELS_GENERIC,
CHANNEL_MISSION_AUDIO,
CHANNEL_PLAYER_VEHICLE_ENGINE,
NUM_CHANNELS
};
#else
enum
{
#ifdef PS2_AUDIO_CHANNELS
NUM_CHANNELS_GENERIC = 43,
#else
NUM_CHANNELS_GENERIC = 27,
#endif
CHANNEL_POLICE_RADIO,
NUM_CHANNELS
};
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,8 @@
#include "common.h"
#ifdef AUDIO_OAL
#include "stream.h"
#include "sampman.h"
#if defined _MSC_VER && !defined RE3_NO_AUTOLINK
#if defined _MSC_VER && !defined CMAKE_NO_AUTOLINK
#ifdef AUDIO_OAL_USE_SNDFILE
#pragma comment( lib, "libsndfile-1.lib" )
#endif
@ -22,6 +20,29 @@
#include <opusfile.h>
#endif
#include <queue>
#include <utility>
#ifdef MULTITHREADED_AUDIO
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "MusicManager.h"
#include "stream.h"
std::thread gAudioThread;
std::mutex gAudioThreadQueueMutex;
std::condition_variable gAudioThreadCv;
bool gAudioThreadTerm = false;
std::queue<CStream*> gStreamsToProcess; // values are not unique, we will handle that ourself
std::queue<std::pair<IDecoder*, void*>> gStreamsToClose;
#else
#include "stream.h"
#endif
#include "sampman.h"
#ifndef _WIN32
#include "crossplatform.h"
#endif
@ -39,6 +60,10 @@ class CSortStereoBuffer
{
uint16* PcmBuf;
size_t BufSize;
//#ifdef MULTITHREADED_AUDIO
// std::mutex Mutex;
//#endif
public:
CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {}
~CSortStereoBuffer()
@ -65,6 +90,9 @@ public:
void SortStereo(void* buf, size_t size)
{
//#ifdef MULTITHREADED_AUDIO
// std::lock_guard<std::mutex> lock(Mutex);
//#endif
uint16* InBuf = (uint16*)buf;
uint16* OutBuf = GetBuffer(size);
@ -134,7 +162,7 @@ public:
else
StepIndex--;
StepIndex = clamp(StepIndex, 0, 88);
StepIndex = Clamp(StepIndex, 0, 88);
int delta = step >> 3;
if (adpcm & 1) delta += step >> 2;
@ -143,7 +171,7 @@ public:
if (adpcm & 8) delta = -delta;
int newSample = Sample + delta;
Sample = clamp(newSample, -32768, 32767);
Sample = Clamp(newSample, -32768, 32767);
return Sample;
}
};
@ -279,6 +307,10 @@ public:
#undef CLOSE_ON_ERROR
}
void FileOpen()
{
}
~CWavFile()
{
Close();
@ -289,6 +321,7 @@ public:
return m_bIsOpen;
}
uint32 GetSampleSize()
{
return sizeof(uint16);
@ -405,6 +438,10 @@ public:
m_pfSound = sf_open(path, SFM_READ, &m_soundInfo);
}
void FileOpen()
{
}
~CSndFile()
{
if ( m_pfSound )
@ -464,46 +501,59 @@ public:
#endif
#ifdef AUDIO_OAL_USE_MPG123
// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though)
#define MP3_USE_FUZZY_SEEK
class CMP3File : public IDecoder
{
protected:
mpg123_handle *m_pMH;
bool m_bOpened;
uint32 m_nRate;
uint32 m_nChannels;
const char* m_pPath;
bool m_bFileNotOpenedYet;
public:
CMP3File(const char *path) :
m_pMH(nil),
m_bOpened(false),
m_nRate(0),
m_nChannels(0)
m_nChannels(0),
m_pPath(path),
m_bFileNotOpenedYet(false)
{
m_pMH = mpg123_new(nil, nil);
if ( m_pMH )
{
#ifdef MP3_USE_FUZZY_SEEK
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0);
#endif
long rate = 0;
int channels = 0;
int encoding = 0;
m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
m_nRate = rate;
m_nChannels = channels;
if ( IsOpened() )
{
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
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
}
}
void FileOpen()
{
if(!m_bFileNotOpenedYet) return;
long rate = 0;
int channels = 0;
int encoding = 0;
m_bOpened = mpg123_open(m_pMH, m_pPath) == MPG123_OK
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if(IsOpened()) {
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
m_bFileNotOpenedYet = false;
}
~CMP3File()
{
if ( m_pMH )
@ -526,7 +576,7 @@ public:
uint32 GetSampleCount()
{
if ( !IsOpened() ) return 0;
if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
return mpg123_length(m_pMH);
}
@ -542,19 +592,19 @@ public:
void Seek(uint32 milliseconds)
{
if ( !IsOpened() ) return;
if ( !IsOpened() || m_bFileNotOpenedYet ) return;
mpg123_seek(m_pMH, ms2samples(milliseconds), SEEK_SET);
}
uint32 Tell()
{
if ( !IsOpened() ) return 0;
if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
return samples2ms(mpg123_tell(m_pMH));
}
uint32 Decode(void *buffer)
{
if ( !IsOpened() ) return 0;
if ( !IsOpened() || m_bFileNotOpenedYet ) return 0;
size_t size;
int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size);
@ -596,7 +646,7 @@ public:
static short quantize(double sample)
{
int a = int(sample + 0.5);
return short(clamp(a, -32768, 32767));
return short(Clamp(a, -32768, 32767));
}
void Decode(void* _inbuf, int16* _outbuf, size_t size)
@ -685,6 +735,10 @@ public:
m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE];
}
void FileOpen()
{
}
~CVbFile()
{
if (m_pFile)
@ -837,6 +891,10 @@ public:
m_bOpened = true;
}
}
void FileOpen()
{
}
~COpusFile()
{
@ -902,11 +960,173 @@ public:
};
#endif
// For multi-thread: Someone always acquire stream's mutex before entering here
void
CStream::BuffersShouldBeFilled()
{
#ifdef MULTITHREADED_AUDIO
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
std::queue<std::pair<ALuint, ALuint>> tempQueue;
for(int i = 0; i < NUM_STREAMBUFFERS / 2; i++) {
tempQueue.push(std::pair<ALuint, ALuint>(m_alBuffers[i * 2], m_alBuffers[i * 2 + 1]));
}
m_fillBuffers.swap(tempQueue);
FlagAsToBeProcessed();
m_bActive = true; // to allow Update() to queue the filled buffers & play
return;
}
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
#endif
if ( FillBuffers() != 0 )
{
SetPlay(true);
}
}
// returns whether it's queued (not on multi-thread)
bool
CStream::BufferShouldBeFilledAndQueued(std::pair<ALuint, ALuint>* bufs)
{
#ifdef MULTITHREADED_AUDIO
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE)
m_fillBuffers.push(*bufs);
else
#endif
{
ALuint alBuffers[2] = {(*bufs).first, (*bufs).second}; // left - right
if (FillBuffer(alBuffers)) {
alSourceQueueBuffers(m_pAlSources[0], 1, &alBuffers[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &alBuffers[1]);
return true;
}
}
return false;
}
#ifdef MULTITHREADED_AUDIO
void
CStream::FlagAsToBeProcessed(bool close)
{
if (!close && MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE)
return;
gAudioThreadQueueMutex.lock();
if (close)
gStreamsToClose.push(std::pair<IDecoder*, void*>(m_pSoundFile ? m_pSoundFile : nil, m_pBuffer ? m_pBuffer : nil));
else
gStreamsToProcess.push(this);
gAudioThreadQueueMutex.unlock();
gAudioThreadCv.notify_one();
}
void audioFileOpsThread()
{
do
{
CStream *stream;
{
// Just a semaphore
std::unique_lock<std::mutex> queueMutex(gAudioThreadQueueMutex);
gAudioThreadCv.wait(queueMutex, [] { return gStreamsToProcess.size() > 0 || gStreamsToClose.size() > 0 || gAudioThreadTerm; });
if (gAudioThreadTerm)
return;
if (!gStreamsToClose.empty()) {
auto streamToClose = gStreamsToClose.front();
gStreamsToClose.pop();
if (streamToClose.first) { // pSoundFile
delete streamToClose.first;
}
if (streamToClose.second) { // pBuffer
free(streamToClose.second);
}
}
if (!gStreamsToProcess.empty()) {
stream = gStreamsToProcess.front();
gStreamsToProcess.pop();
} else
continue;
}
std::unique_lock<std::mutex> lock(stream->m_mutex);
std::pair<ALuint, ALuint> buffers, *lastBufAddr;
bool insertBufsAfterCheck = false;
do {
if (!stream->IsOpened()) {
break;
}
if (stream->m_bReset)
break;
// We gave up this idea for now
/*
stream->m_pSoundFile->FileOpen();
// Deffered allocation, do it now
if (stream->m_pBuffer == nil) {
stream->m_pBuffer = malloc(stream->m_pSoundFile->GetBufferSize());
ASSERT(stream->m_pBuffer != nil);
}
*/
if (stream->m_bDoSeek) {
stream->m_bDoSeek = false;
int pos = stream->m_SeekPos;
lock.unlock();
stream->m_pSoundFile->Seek(pos);
lock.lock();
continue; // let's do the checks again, make sure we didn't miss anything while Seeking
}
if (insertBufsAfterCheck) {
stream->m_queueBuffers.push(buffers);
insertBufsAfterCheck = false;
}
if (!stream->m_fillBuffers.empty()) {
lastBufAddr = &stream->m_fillBuffers.front();
buffers = *lastBufAddr;
lock.unlock();
ALuint alBuffers[2] = {buffers.first, buffers.second}; // left - right
bool filled = stream->FillBuffer(alBuffers);
lock.lock();
// Make sure queue isn't touched after we released mutex
if (!stream->m_fillBuffers.empty() && lastBufAddr == &stream->m_fillBuffers.front()) {
stream->m_fillBuffers.pop();
if (filled)
insertBufsAfterCheck = true; // Also make sure stream's properties aren't changed. So make one more pass, and push it to m_queueBuffers only if it pass checks again.
}
} else
break;
} while (true);
} while(true);
}
#endif
void CStream::Initialise()
{
#ifdef AUDIO_OAL_USE_MPG123
mpg123_init();
#endif
#ifdef MULTITHREADED_AUDIO
gAudioThread = std::thread(audioFileOpsThread);
#endif
}
void CStream::Terminate()
@ -914,14 +1134,27 @@ void CStream::Terminate()
#ifdef AUDIO_OAL_USE_MPG123
mpg123_exit();
#endif
#ifdef MULTITHREADED_AUDIO
gAudioThreadQueueMutex.lock();
gAudioThreadTerm = true;
gAudioThreadQueueMutex.unlock();
gAudioThreadCv.notify_one();
gAudioThread.join();
#endif
}
CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate) :
CStream::CStream(ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
m_pAlSources(sources),
m_alBuffers(buffers),
m_pBuffer(nil),
m_bPaused(false),
m_bActive(false),
#ifdef MULTITHREADED_AUDIO
m_bIExist(false),
m_bDoSeek(false),
m_SeekPos(0),
#endif
m_pSoundFile(nil),
m_bReset(false),
m_nVolume(0),
@ -930,6 +1163,27 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
m_nLoopCount(1)
{
}
bool CStream::Open(const char* filename, uint32 overrideSampleRate)
{
if (IsOpened()) return false;
#ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex);
m_bDoSeek = false;
m_SeekPos = 0;
#endif
m_bPaused = false;
m_bActive = false;
m_bReset = false;
m_nVolume = 0;
m_nPan = 0;
m_nPosBeforeReset = 0;
m_nLoopCount = 1;
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
char *real = casepath(filename);
@ -964,44 +1218,67 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
else
m_pSoundFile = nil;
if ( IsOpened() )
if ( m_pSoundFile && m_pSoundFile->IsOpened() )
{
m_pBuffer = malloc(m_pSoundFile->GetBufferSize());
ASSERT(m_pBuffer!=nil);
DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
DEV("Channels: %d\n", m_pSoundFile->GetChannels());
DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples());
DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate())));
DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
return;
uint32 bufSize = m_pSoundFile->GetBufferSize();
if(bufSize != 0) { // Otherwise it's deferred
m_pBuffer = malloc(bufSize);
ASSERT(m_pBuffer != nil);
DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
DEV("Channels: %d\n", m_pSoundFile->GetChannels());
DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples());
DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate())));
DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
}
#ifdef MULTITHREADED_AUDIO
m_bIExist = true;
#endif
return true;
}
return false;
}
CStream::~CStream()
{
Delete();
assert(!IsOpened());
}
void CStream::Delete()
void CStream::Close()
{
if(!IsOpened()) return;
#ifdef MULTITHREADED_AUDIO
{
std::lock_guard<std::mutex> lock(m_mutex);
Stop();
ClearBuffers();
m_bIExist = false;
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, mutex is acquired
}
FlagAsToBeProcessed(true);
#else
Stop();
ClearBuffers();
if ( m_pSoundFile )
{
delete m_pSoundFile;
m_pSoundFile = nil;
}
if ( m_pBuffer )
{
free(m_pBuffer);
m_pBuffer = nil;
}
#endif
}
bool CStream::HasSource()
@ -1009,9 +1286,14 @@ bool CStream::HasSource()
return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE);
}
// m_bIExist only written in main thread, thus mutex is not needed on main thread
bool CStream::IsOpened()
{
#ifdef MULTITHREADED_AUDIO
return m_bIExist;
#else
return m_pSoundFile && m_pSoundFile->IsOpened();
#endif
}
bool CStream::IsPlaying()
@ -1025,6 +1307,14 @@ bool CStream::IsPlaying()
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
return true;
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
// Streams are designed in such a way that m_fillBuffers and m_queueBuffers will be *always* filled if audio is playing, and mutex is acquired
if (!m_fillBuffers.empty() || !m_queueBuffers.emptyNts())
return true;
#endif
}
return false;
@ -1086,10 +1376,10 @@ void CStream::SetVolume(uint32 nVol)
void CStream::SetPan(uint8 nPan)
{
m_nPan = clamp((int8)nPan - 63, 0, 63);
m_nPan = Clamp((int8)nPan - 63, 0, 63);
SetPosition(0, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
m_nPan = clamp((int8)nPan + 64, 64, 127);
m_nPan = Clamp((int8)nPan + 64, 64, 127);
SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
m_nPan = nPan;
@ -1099,8 +1389,24 @@ void CStream::SetPan(uint8 nPan)
void CStream::SetPosMS(uint32 nPos)
{
if ( !IsOpened() ) return;
m_pSoundFile->Seek(nPos);
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, second thread always access it when stream mutex acquired
if (MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE) {
m_bDoSeek = true;
m_SeekPos = nPos;
} else
#endif
{
m_pSoundFile->Seek(nPos);
}
ClearBuffers();
// adding to gStreamsToProcess not needed, someone always calls Start() / BuffersShouldBeFilled() after SetPosMS
}
uint32 CStream::GetPosMS()
@ -1108,10 +1414,16 @@ uint32 CStream::GetPosMS()
if ( !HasSource() ) return 0;
if ( !IsOpened() ) return 0;
// Deferred init causes division by zero
if (m_pSoundFile->GetChannels() == 0)
return 0;
ALint offset;
//alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset);
//std::lock_guard<std::mutex> lock(m_mutex);
return m_pSoundFile->Tell()
- m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels()
+ m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels();
@ -1125,6 +1437,7 @@ uint32 CStream::GetLengthMS()
bool CStream::FillBuffer(ALuint *alBuffer)
{
#ifndef MULTITHREADED_AUDIO
if ( !HasSource() )
return false;
if ( !IsOpened() )
@ -1133,7 +1446,8 @@ bool CStream::FillBuffer(ALuint *alBuffer)
return false;
if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) )
return false;
#endif
uint32 size = m_pSoundFile->Decode(m_pBuffer);
if( size == 0 )
return false;
@ -1149,6 +1463,26 @@ bool CStream::FillBuffer(ALuint *alBuffer)
return true;
}
#ifdef MULTITHREADED_AUDIO
bool CStream::QueueBuffers()
{
bool buffersQueued = false;
std::pair<ALuint, ALuint> buffers;
while (m_queueBuffers.peekPop(&buffers)) // beware: m_queueBuffers is tsQueue
{
ALuint leftBuf = buffers.first;
ALuint rightBuf = buffers.second;
alSourceQueueBuffers(m_pAlSources[0], 1, &leftBuf);
alSourceQueueBuffers(m_pAlSources[1], 1, &rightBuf);
buffersQueued = true;
}
return buffersQueued;
}
#endif
// Only used in single-threaded audio or cutscene audio
int32 CStream::FillBuffers()
{
int32 i = 0;
@ -1178,17 +1512,33 @@ void CStream::ClearBuffers()
alSourceUnqueueBuffers(m_pAlSources[1], 1, &value);
}
bool CStream::Setup(bool imSureQueueIsEmpty)
bool CStream::Setup(bool imSureQueueIsEmpty, bool lock)
{
if ( IsOpened() )
{
alSourcei(m_pAlSources[0], AL_LOOPING, AL_FALSE);
alSourcei(m_pAlSources[1], AL_LOOPING, AL_FALSE);
#ifdef MULTITHREADED_AUDIO
if (lock)
m_mutex.lock();
#endif
if (!imSureQueueIsEmpty) {
SetPlay(false);
Stop();
ClearBuffers();
}
#ifdef MULTITHREADED_AUDIO
if (MusicManager.m_nMusicMode == MUSICMODE_CUTSCENE) {
m_pSoundFile->Seek(0);
} else {
m_bDoSeek = true;
m_SeekPos = 0;
}
if (lock)
m_mutex.unlock();
#else
m_pSoundFile->Seek(0);
#endif
//SetPosition(0.0f, 0.0f, 0.0f);
SetPitch(1.0f);
//SetPan(m_nPan);
@ -1241,8 +1591,12 @@ void CStream::SetPlay(bool state)
void CStream::Start()
{
if ( !HasSource() ) return;
if ( FillBuffers() != 0 )
SetPlay(true);
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // TSness not required, second thread always access it when stream mutex acquired
#endif
BuffersShouldBeFilled();
}
void CStream::Stop()
@ -1264,9 +1618,23 @@ void CStream::Update()
if ( !m_bPaused )
{
ALint totalBuffers[2] = { 0, 0 };
ALint buffersProcessed[2] = { 0, 0 };
bool buffersQueuedAndStarted = false;
bool buffersQueuedButNotStarted = false;
#ifdef MULTITHREADED_AUDIO
// Put it in here because we need totalBuffers after queueing to decide when to loop audio
if (m_bActive)
{
buffersQueuedAndStarted = QueueBuffers();
if(buffersQueuedAndStarted) {
SetPlay(true);
}
}
#endif
ALint totalBuffers[2] = {0, 0};
ALint buffersProcessed[2] = {0, 0};
// Relying a lot on left buffer states in here
do
@ -1278,44 +1646,66 @@ void CStream::Update()
alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &totalBuffers[1]);
alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]);
} while (buffersProcessed[0] != buffersProcessed[1]);
assert(buffersProcessed[0] == buffersProcessed[1]);
// Correcting OpenAL concepts here:
// AL_BUFFERS_QUEUED = Number of *all* buffers in queue, including processed, processing and pending
// AL_BUFFERS_PROCESSED = Index of the buffer being processing right now. Buffers coming after that(have greater index) are pending buffers.
// which means: totalBuffers[0] - buffersProcessed[0] = pending buffers
bool buffersRefilled = false;
// We should wait queue to be cleared to loop track, because position calculation relies on queue.
if (m_nLoopCount != 1 && m_bActive && totalBuffers[0] == 0)
{
Setup(true);
buffersRefilled = FillBuffers() != 0;
if (m_nLoopCount != 0)
m_nLoopCount--;
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
if (m_fillBuffers.empty() && m_queueBuffers.emptyNts()) // we already acquired stream mutex, which is enough for second thread. thus Nts variant
#endif
{
Setup(true, false);
BuffersShouldBeFilled(); // will also call SetPlay(true)
if (m_nLoopCount != 0)
m_nLoopCount--;
}
}
else
{
while( buffersProcessed[0]-- )
static std::queue<std::pair<ALuint, ALuint>> tempFillBuffer;
while ( buffersProcessed[0]-- )
{
ALuint buffer[2];
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
if (m_bActive && FillBuffer(buffer))
if (m_bActive)
{
buffersRefilled = true;
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
tempFillBuffer.push(std::pair<ALuint, ALuint>(buffer[0], buffer[1]));
}
}
if (m_bActive && buffersProcessed[1])
{
#ifdef MULTITHREADED_AUDIO
m_mutex.lock();
#endif
while (!tempFillBuffer.empty()) {
auto elem = tempFillBuffer.front();
tempFillBuffer.pop();
buffersQueuedButNotStarted = BufferShouldBeFilledAndQueued(&elem);
}
#ifdef MULTITHREADED_AUDIO
m_mutex.unlock();
FlagAsToBeProcessed();
#endif
}
}
// Two reasons: 1-Source may be starved to audio and stopped itself, 2- We're already waiting it to starve and die for looping track!
if (m_bActive && (buffersRefilled || (totalBuffers[1] - buffersProcessed[1] != 0)))
// Source may be starved to audio and stopped itself
if (m_bActive && !buffersQueuedAndStarted && (buffersQueuedButNotStarted || (totalBuffers[1] - buffersProcessed[1] != 0)))
SetPlay(true);
}
}
@ -1324,28 +1714,45 @@ void CStream::ProviderInit()
{
if ( m_bReset )
{
if ( Setup(true) )
if ( Setup(true, false) ) // lock not needed, thread can't process streams with m_bReset set
{
SetPan(m_nPan);
SetVolume(m_nVolume);
SetLoopCount(m_nLoopCount);
SetPosMS(m_nPosBeforeReset);
if (m_bActive)
FillBuffers();
SetPlay(m_bActive);
if ( m_bPaused )
#ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex);
#endif
if(m_bActive)
BuffersShouldBeFilled();
if (m_bPaused)
Pause();
m_bReset = false;
} else {
#ifdef MULTITHREADED_AUDIO
std::unique_lock<std::mutex> lock(m_mutex);
#endif
m_bReset = false;
}
m_bReset = false;
}
}
void CStream::ProviderTerm()
{
#ifdef MULTITHREADED_AUDIO
std::lock_guard<std::mutex> lock(m_mutex);
// unlike Close() we will reuse this stream, so clearing queues are important.
std::queue<std::pair<ALuint, ALuint>>().swap(m_fillBuffers);
tsQueue<std::pair<ALuint, ALuint>>().swapNts(m_queueBuffers); // stream mutex is already acquired, thus Nts variant
#endif
m_bReset = true;
m_nPosBeforeReset = GetPosMS();
Stop();
ClearBuffers();
}

View File

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

View File

@ -1,14 +1,15 @@
#pragma once
#include "AudioSamples.h"
#include "audio_enums.h"
#define MAX_VOLUME 127
#define MAX_FREQ DIGITALRATE
struct tSample {
int32 nOffset;
uint32 nOffset;
uint32 nSize;
int32 nFrequency;
int32 nLoopStart;
uint32 nFrequency;
uint32 nLoopStart;
int32 nLoopEnd;
};
@ -99,10 +100,15 @@ enum
#define MAXPROVIDERS 64
#define MAXCHANNELS 28
#define MAXCHANNELS_SURROUND 24
#ifdef EXTERNAL_3D_SOUND
#define MAXCHANNELS (NUM_CHANNELS_GENERIC+1)
#define MAXCHANNELS_SURROUND (MAXCHANNELS-4)
#define MAX2DCHANNELS 1
#define CHANNEL2D MAXCHANNELS
#else
#define MAXCHANNELS 0
#define MAXCHANNELS_SURROUND 0
#define MAX2DCHANNELS NUM_CHANNELS
#endif
#define MAX_STREAMS 2
@ -110,7 +116,13 @@ enum
#define DIGITALBITS 16
#define DIGITALCHANNELS 2
#define MAX_DIGITAL_MIXER_CHANNELS 32
#ifdef FIX_BUGS
#define MAX_DIGITAL_MIXER_CHANNELS (MAXCHANNELS+MAX_STREAMS*2+MAX2DCHANNELS)
#else
#define MAX_DIGITAL_MIXER_CHANNELS (MAXCHANNELS+MAX_STREAMS*2)
#endif
static_assert( NUM_CHANNELS == MAXCHANNELS + MAX2DCHANNELS, "The number of channels doesn't match with an enum" );
class cSampleManager
{
@ -118,10 +130,10 @@ class cSampleManager
uint8 m_nMusicVolume;
uint8 m_nEffectsFadeVolume;
uint8 m_nMusicFadeVolume;
uint8 m_nMonoMode;
bool8 m_nMonoMode;
char unk;
char m_szCDRomRootPath[80];
bool m_bInitialised;
bool8 m_bInitialised;
uint8 m_nNumberOfProviders;
char *m_aAudioProviders[MAXPROVIDERS];
tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
@ -132,7 +144,8 @@ public:
cSampleManager(void);
~cSampleManager(void);
#ifdef EXTERNAL_3D_SOUND
void SetSpeakerConfig(int32 nConfig);
uint32 GetMaximumSupportedChannels(void);
@ -144,17 +157,18 @@ public:
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
#endif
bool IsMP3RadioChannelAvailable(void);
bool8 IsMP3RadioChannelAvailable(void);
void ReleaseDigitalHandle (void);
void ReacquireDigitalHandle(void);
bool Initialise(void);
void Terminate (void);
bool8 Initialise(void);
void Terminate (void);
bool CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter (void);
bool8 CheckForAnAudioFileOnCD(void);
char GetCDAudioDriveLetter (void);
void UpdateEffectsVolume(void);
@ -162,52 +176,54 @@ public:
void SetMusicMasterVolume (uint8 nVolume);
void SetEffectsFadeVolume (uint8 nVolume);
void SetMusicFadeVolume (uint8 nVolume);
void SetMonoMode (uint8 nMode);
void SetMonoMode (bool8 nMode);
bool LoadSampleBank (uint8 nBank);
void UnloadSampleBank (uint8 nBank);
bool IsSampleBankLoaded(uint8 nBank);
bool8 LoadSampleBank (uint8 nBank);
void UnloadSampleBank (uint8 nBank);
int8 IsSampleBankLoaded(uint8 nBank);
bool IsPedCommentLoaded(uint32 nComment);
bool LoadPedComment (uint32 nComment);
uint8 IsPedCommentLoaded(uint32 nComment);
bool8 LoadPedComment (uint32 nComment);
int32 GetBankContainingSound(uint32 offset);
int32 _GetPedCommentSlot(uint32 nComment);
int32 GetSampleBaseFrequency (uint32 nSample);
int32 GetSampleLoopStartOffset(uint32 nSample);
uint32 GetSampleBaseFrequency (uint32 nSample);
uint32 GetSampleLoopStartOffset(uint32 nSample);
int32 GetSampleLoopEndOffset (uint32 nSample);
uint32 GetSampleLength (uint32 nSample);
bool UpdateReverb(void);
bool8 UpdateReverb(void);
void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
void SetChannelReverbFlag (uint32 nChannel, bool8 nReverbFlag);
bool8 InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
#ifdef EXTERNAL_3D_SOUND
void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
#endif
void SetChannelVolume (uint32 nChannel, uint32 nVolume);
void SetChannelPan (uint32 nChannel, uint32 nPan);
void SetChannelFrequency (uint32 nChannel, uint32 nFreq);
void SetChannelLoopPoints (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
void SetChannelLoopCount (uint32 nChannel, uint32 nLoopCount);
bool GetChannelUsedFlag (uint32 nChannel);
bool8 GetChannelUsedFlag (uint32 nChannel);
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
void PreloadStreamedFile (uint8 nFile, uint8 nStream);
void PauseStream (uint8 nPauseFlag, uint8 nStream);
void StartPreloadedStreamedFile (uint8 nStream);
bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
void StopStreamedFile (uint8 nStream);
int32 GetStreamedFilePosition (uint8 nStream);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
int32 GetStreamedFileLength (uint8 nStream);
bool IsStreamPlaying (uint8 nStream);
void PreloadStreamedFile (uint8 nFile, uint8 nStream = 0);
void PauseStream (bool8 nPauseFlag, uint8 nStream = 0);
void StartPreloadedStreamedFile (uint8 nStream = 0);
bool8 StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream = 0);
void StopStreamedFile (uint8 nStream = 0);
int32 GetStreamedFilePosition (uint8 nStream = 0);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, bool8 nEffectFlag, uint8 nStream = 0);
int32 GetStreamedFileLength (uint8 nStream = 0);
bool8 IsStreamPlaying (uint8 nStream = 0);
#ifdef AUDIO_OAL
void Service(void);
#endif
bool InitialiseSampleBanks(void);
bool8 InitialiseSampleBanks(void);
};
extern cSampleManager SampleManager;
@ -253,8 +269,8 @@ static char StreamedNameTable[][25] = {
"AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS",
"AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"};
#else
#if defined(PS2_AUDIO_PATHS)
static char StreamedNameTable[][25]=
#ifdef PS2_AUDIO_PATHS
static char PS2StreamedNameTable[][25]=
{
"AUDIO\\MUSIC\\HEAD.VB",
"AUDIO\\MUSIC\\CLASS.VB",
@ -351,7 +367,110 @@ static char StreamedNameTable[][25]=
"AUDIO\\PHONE\\MT_PH4.VB",
"AUDIO\\MUSIC\\MISCOM.VB",
"AUDIO\\MUSIC\\END.VB",
#else
"AUDIO\\lib_a1.WAV",
"AUDIO\\lib_a2.WAV",
"AUDIO\\lib_a.WAV",
"AUDIO\\lib_b.WAV",
"AUDIO\\lib_c.WAV",
"AUDIO\\lib_d.WAV",
"AUDIO\\l2_a.WAV",
"AUDIO\\j4t_1.WAV",
"AUDIO\\j4t_2.WAV",
"AUDIO\\j4t_3.WAV",
"AUDIO\\j4t_4.WAV",
"AUDIO\\j4_a.WAV",
"AUDIO\\j4_b.WAV",
"AUDIO\\j4_c.WAV",
"AUDIO\\j4_d.WAV",
"AUDIO\\j4_e.WAV",
"AUDIO\\j4_f.WAV",
"AUDIO\\j6_1.WAV",
"AUDIO\\j6_a.WAV",
"AUDIO\\j6_b.WAV",
"AUDIO\\j6_c.WAV",
"AUDIO\\j6_d.WAV",
"AUDIO\\t4_a.WAV",
"AUDIO\\s1_a.WAV",
"AUDIO\\s1_a1.WAV",
"AUDIO\\s1_b.WAV",
"AUDIO\\s1_c.WAV",
"AUDIO\\s1_c1.WAV",
"AUDIO\\s1_d.WAV",
"AUDIO\\s1_e.WAV",
"AUDIO\\s1_f.WAV",
"AUDIO\\s1_g.WAV",
"AUDIO\\s1_h.WAV",
"AUDIO\\s1_i.WAV",
"AUDIO\\s1_j.WAV",
"AUDIO\\s1_k.WAV",
"AUDIO\\s1_l.WAV",
"AUDIO\\s3_a.WAV",
"AUDIO\\s3_b.WAV",
"AUDIO\\el3_a.WAV",
"AUDIO\\mf1_a.WAV",
"AUDIO\\mf2_a.WAV",
"AUDIO\\mf3_a.WAV",
"AUDIO\\mf3_b.WAV",
"AUDIO\\mf3_b1.WAV",
"AUDIO\\mf3_c.WAV",
"AUDIO\\mf4_a.WAV",
"AUDIO\\mf4_b.WAV",
"AUDIO\\mf4_c.WAV",
"AUDIO\\a1_a.WAV",
"AUDIO\\a3_a.WAV",
"AUDIO\\a5_a.WAV",
"AUDIO\\a4_a.WAV",
"AUDIO\\a4_b.WAV",
"AUDIO\\a4_c.WAV",
"AUDIO\\a4_d.WAV",
"AUDIO\\k1_a.WAV",
"AUDIO\\k3_a.WAV",
"AUDIO\\r1_a.WAV",
"AUDIO\\r2_a.WAV",
"AUDIO\\r2_b.WAV",
"AUDIO\\r2_c.WAV",
"AUDIO\\r2_d.WAV",
"AUDIO\\r2_e.WAV",
"AUDIO\\r2_f.WAV",
"AUDIO\\r2_g.WAV",
"AUDIO\\r2_h.WAV",
"AUDIO\\r5_a.WAV",
"AUDIO\\r6_a.WAV",
"AUDIO\\r6_a1.WAV",
"AUDIO\\r6_b.WAV",
"AUDIO\\lo2_a.WAV",
"AUDIO\\lo6_a.WAV",
"AUDIO\\yd2_a.WAV",
"AUDIO\\yd2_b.WAV",
"AUDIO\\yd2_c.WAV",
"AUDIO\\yd2_c1.WAV",
"AUDIO\\yd2_d.WAV",
"AUDIO\\yd2_e.WAV",
"AUDIO\\yd2_f.WAV",
"AUDIO\\yd2_g.WAV",
"AUDIO\\yd2_h.WAV",
"AUDIO\\yd2_ass.WAV",
"AUDIO\\yd2_ok.WAV",
"AUDIO\\h5_a.WAV",
"AUDIO\\h5_b.WAV",
"AUDIO\\h5_c.WAV",
"AUDIO\\ammu_a.WAV",
"AUDIO\\ammu_b.WAV",
"AUDIO\\ammu_c.WAV",
"AUDIO\\door_1.WAV",
"AUDIO\\door_2.WAV",
"AUDIO\\door_3.WAV",
"AUDIO\\door_4.WAV",
"AUDIO\\door_5.WAV",
"AUDIO\\door_6.WAV",
"AUDIO\\t3_a.WAV",
"AUDIO\\t3_b.WAV",
"AUDIO\\t3_c.WAV",
"AUDIO\\k1_b.WAV",
"AUDIO\\cat1.WAV"
};
#endif
static char StreamedNameTable[][25] =
{
"AUDIO\\HEAD.WAV",
@ -449,7 +568,6 @@ static char StreamedNameTable[][25] =
"AUDIO\\MT_PH4.MP3",
"AUDIO\\MISCOM.WAV",
"AUDIO\\END.MP3",
#endif
"AUDIO\\lib_a1.WAV",
"AUDIO\\lib_a2.WAV",
"AUDIO\\lib_a.WAV",

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#include "AudioManager.h"
cSampleManager SampleManager;
bool _bSampmanInitialised = false;
bool8 _bSampmanInitialised = FALSE;
uint32 BankStartOffset[MAX_SFX_BANKS];
uint32 nNumMP3s;
@ -19,6 +19,7 @@ cSampleManager::~cSampleManager(void)
}
#ifdef EXTERNAL_3D_SOUND
void cSampleManager::SetSpeakerConfig(int32 nConfig)
{
@ -59,8 +60,9 @@ int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
{
return 0;
}
#endif
bool
bool8
cSampleManager::IsMP3RadioChannelAvailable(void)
{
return nNumMP3s != 0;
@ -75,10 +77,10 @@ void cSampleManager::ReacquireDigitalHandle(void)
{
}
bool
bool8
cSampleManager::Initialise(void)
{
return true;
return TRUE;
}
void
@ -87,9 +89,9 @@ cSampleManager::Terminate(void)
}
bool cSampleManager::CheckForAnAudioFileOnCD(void)
bool8 cSampleManager::CheckForAnAudioFileOnCD(void)
{
return true;
return TRUE;
}
char cSampleManager::GetCDAudioDriveLetter(void)
@ -128,11 +130,11 @@ cSampleManager::SetMonoMode(uint8 nMode)
{
}
bool
bool8
cSampleManager::LoadSampleBank(uint8 nBank)
{
ASSERT( nBank < MAX_SFX_BANKS );
return false;
return FALSE;
}
void
@ -141,20 +143,20 @@ cSampleManager::UnloadSampleBank(uint8 nBank)
ASSERT( nBank < MAX_SFX_BANKS );
}
bool
int8
cSampleManager::IsSampleBankLoaded(uint8 nBank)
{
ASSERT( nBank < MAX_SFX_BANKS );
return false;
return LOADING_STATUS_NOT_LOADED;
}
bool
uint8
cSampleManager::IsPedCommentLoaded(uint32 nComment)
{
ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
return false;
return LOADING_STATUS_NOT_LOADED;
}
@ -164,11 +166,11 @@ cSampleManager::_GetPedCommentSlot(uint32 nComment)
return -1;
}
bool
bool8
cSampleManager::LoadPedComment(uint32 nComment)
{
ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
return false;
return FALSE;
}
int32
@ -177,14 +179,14 @@ cSampleManager::GetBankContainingSound(uint32 offset)
return INVALID_SFX_BANK;
}
int32
uint32
cSampleManager::GetSampleBaseFrequency(uint32 nSample)
{
ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
return 0;
}
int32
uint32
cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
{
ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
@ -205,56 +207,58 @@ cSampleManager::GetSampleLength(uint32 nSample)
return 0;
}
bool cSampleManager::UpdateReverb(void)
bool8 cSampleManager::UpdateReverb(void)
{
return false;
return FALSE;
}
void
cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
cSampleManager::SetChannelReverbFlag(uint32 nChannel, bool8 nReverbFlag)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
bool
bool8
cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
return false;
return FALSE;
}
#ifdef EXTERNAL_3D_SOUND
void
cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
{
ASSERT( nChannel != CHANNEL2D );
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
{
ASSERT( nChannel != CHANNEL2D );
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
{
ASSERT( nChannel != CHANNEL2D );
ASSERT( nChannel < MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
#endif
void
cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
{
ASSERT( nChannel == CHANNEL2D );
ASSERT( nChannel >= MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
void
cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
{
ASSERT(nChannel == CHANNEL2D);
ASSERT( nChannel >= MAXCHANNELS );
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
@ -276,12 +280,12 @@ cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
}
bool
bool8
cSampleManager::GetChannelUsedFlag(uint32 nChannel)
{
ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
return false;
return FALSE;
}
void
@ -303,7 +307,7 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
}
void
cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
cSampleManager::PauseStream(bool8 nPauseFlag, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
}
@ -314,12 +318,12 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
ASSERT( nStream < MAX_STREAMS );
}
bool
bool8
cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
return false;
return FALSE;
}
void
@ -350,19 +354,19 @@ cSampleManager::GetStreamedFileLength(uint8 nStream)
return 1;
}
bool
bool8
cSampleManager::IsStreamPlaying(uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
return false;
return FALSE;
}
bool
bool8
cSampleManager::InitialiseSampleBanks(void)
{
return true;
return TRUE;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -212,8 +212,8 @@ enum eScriptSounds {
SCRIPT_SOUND_WORK_SHOP_LOOP_L,
SCRIPT_SOUND_SAWMILL_LOOP_S,
SCRIPT_SOUND_SAWMILL_LOOP_L,
SCRIPT_SOUND_38,
SCRIPT_SOUND_39,
SCRIPT_SOUND_DOG_FOOD_FACTORY_S,
SCRIPT_SOUND_DOG_FOOD_FACTORY_L,
SCRIPT_SOUND_LAUNDERETTE_LOOP_S,
SCRIPT_SOUND_LAUNDERETTE_LOOP_L,
SCRIPT_SOUND_CHINATOWN_RESTAURANT_S,

View File

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

View File

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

View File

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

View File

@ -5,8 +5,8 @@
class CTreadable : public CBuilding
{
public:
static void *operator new(size_t);
static void operator delete(void*, size_t);
static void *operator new(size_t) throw();
static void operator delete(void*, size_t) throw();
int16 m_nodeIndices[2][12]; // first car, then ped

View File

@ -130,7 +130,7 @@ GetCollisionInSectorList(CPtrList &list)
for(node = list.first; node; node = node->next){
e = (CEntity*)node->item;
level = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel()->level;
level = CModelInfo::GetColModel(e->GetModelIndex())->level;
if(level != LEVEL_GENERIC)
return (eLevelName)level;
}

View File

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

View File

@ -510,8 +510,18 @@ void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle)
{
if (pVehicle->pDriver){
pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
if (pVehicle->GetModelIndex() == MI_AMBULAN)
switch (pVehicle->GetModelIndex()) {
case MI_FIRETRUCK:
case MI_FBICAR:
case MI_ENFORCER:
case MI_BARRACKS:
case MI_RHINO:
case MI_POLICE:
break;
case MI_AMBULAN:
pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
break;
}
}
int timer = 100;
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++){

View File

@ -77,7 +77,7 @@ int32 CCarCtrl::NumRandomCars;
int32 CCarCtrl::NumParkedCars;
int32 CCarCtrl::NumPermanentCars;
int8 CCarCtrl::CountDownToCarsAtStart;
int32 CCarCtrl::MaxNumberOfCarsInUse = 12;
int32 CCarCtrl::MaxNumberOfCarsInUse = DEFAULT_MAX_NUMBER_OF_CARS;
uint32 CCarCtrl::LastTimeLawEnforcerCreated;
uint32 CCarCtrl::LastTimeFireTruckCreated;
uint32 CCarCtrl::LastTimeAmbulanceCreated;
@ -354,7 +354,7 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->m_bSirenOrAlarm = true;
pVehicle->AutoPilot.m_nNextPathNodeInfo = connectionId;
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane = CGeneral::GetRandomNumber() % lanesOnCurrentRoad;
CColBox* boundingBox = &CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel()->boundingBox;
CColBox* boundingBox = &CModelInfo::GetColModel(pVehicle->GetModelIndex())->boundingBox;
float carLength = 1.0f + (boundingBox->max.y - boundingBox->min.y) / 2;
float distanceBetweenNodes = (pCurNode->GetPosition() - pNextNode->GetPosition()).Magnitude2D();
/* If car is so long that it doesn't fit between two car nodes, place it directly in the middle. */
@ -731,6 +731,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
}
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
float threshold = 50.0f;
#ifndef EXTENDED_OFFSCREEN_DESPAWN_RANGE
if (pVehicle->GetIsOnScreen() ||
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
@ -741,7 +742,9 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
pVehicle->GetModelIndex() == MI_FIRETRUCK ||
pVehicle->bIsLawEnforcer ||
pVehicle->bIsCarParkVehicle
){
)
#endif
{
threshold = 130.0f * TheCamera.GenerationDistMultiplier;
}
if (pVehicle->bExtendedRange)
@ -770,14 +773,16 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
delete pVehicle;
return;
}
if (pVehicle->GetStatus() != STATUS_WRECKED || pVehicle->m_nTimeOfDeath == 0)
return;
if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nTimeOfDeath + 60000 &&
!(pVehicle->GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(pVehicle)) ){
if ((pVehicle->GetPosition() - vecPlayerPos).MagnitudeSqr() > SQR(7.5f)){
if (!CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
CWorld::Remove(pVehicle);
delete pVehicle;
if (pVehicle->GetStatus() == STATUS_WRECKED) {
if (pVehicle->m_nTimeOfDeath != 0) {
if (CTimer::GetTimeInMilliseconds() > pVehicle->m_nTimeOfDeath + 60000 &&
!(pVehicle->GetIsOnScreen() && CRenderer::IsEntityCullZoneVisible(pVehicle))) {
if ((pVehicle->GetPosition() - vecPlayerPos).MagnitudeSqr() > SQR(7.5f)) {
if (!CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())) {
CWorld::Remove(pVehicle);
delete pVehicle;
}
}
}
}
}
@ -805,8 +810,8 @@ CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
pVehicle->AutoPilot.ModifySpeed(0.0f);
if (CTimer::GetTimeInMilliseconds() > pVehicle->AutoPilot.m_nTempAction){
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
pVehicle->AutoPilot.m_nAntiReverseTimer = 0;
pVehicle->AutoPilot.m_nTimeToStartMission = 0;
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
pVehicle->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
}
return;
}
@ -1330,8 +1335,8 @@ void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float
forward.NormaliseSafe();
float forwardAngle = CGeneral::GetATanOfXY(forward.x, forward.y);
float angleDiff = angleBetweenVehicles - forwardAngle;
float lenProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.y * sin(angleDiff));
float widthProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.x * cos(angleDiff));
float lenProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.y * Sin(angleDiff));
float widthProjection = ABS(pOtherCar->GetColModel()->boundingBox.max.x * Cos(angleDiff));
float lengthToEvade = (2 * (lenProjection + widthProjection) + WIDTH_COEF_TO_WEAVE_SAFELY * 2 * pVehicle->GetColModel()->boundingBox.max.x) / distance;
float diffToLeftAngle = LimitRadianAngle(angleBetweenVehicles - *pAngleToWeaveLeft);
diffToLeftAngle = ABS(diffToLeftAngle);

View File

@ -24,13 +24,7 @@
#include "Vehicle.h"
#include "Wanted.h"
#include "World.h"
#define CRUSHER_GARAGE_X1 (1135.5f)
#define CRUSHER_GARAGE_Y1 (57.0f)
#define CRUSHER_GARAGE_Z1 (-1.0f)
#define CRUSHER_GARAGE_X2 (1149.5f)
#define CRUSHER_GARAGE_Y2 (63.7f)
#define CRUSHER_GARAGE_Z2 (3.5f)
#include "SaveBuf.h"
#define ROTATED_DOOR_OPEN_SPEED (0.015f)
#define ROTATED_DOOR_CLOSE_SPEED (0.02f)
@ -160,7 +154,7 @@ void CGarages::Init(void)
aCarsInSafeHouse3[i].Init();
hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (hGarages >= 0)
DMAudio.SetEntityStatus(hGarages, true);
DMAudio.SetEntityStatus(hGarages, TRUE);
AddOne(
CVector(CRUSHER_GARAGE_X1, CRUSHER_GARAGE_Y1, CRUSHER_GARAGE_Z1),
CVector(CRUSHER_GARAGE_X2, CRUSHER_GARAGE_Y2, CRUSHER_GARAGE_Z2),
@ -1882,11 +1876,12 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
m_nRadioStation = pVehicle->m_nRadioStation;
m_nVariationA = pVehicle->m_aExtras[0];
m_nVariationB = pVehicle->m_aExtras[1];
m_bBulletproof = pVehicle->bBulletProof;
m_bFireproof = pVehicle->bFireProof;
m_bExplosionproof = pVehicle->bExplosionProof;
m_bCollisionproof = pVehicle->bCollisionProof;
m_bMeleeproof = pVehicle->bMeleeProof;
m_nFlags = 0;
if (pVehicle->bBulletProof) m_nFlags |= FLAG_BULLETPROOF;
if (pVehicle->bFireProof) m_nFlags |= FLAG_FIREPROOF;
if (pVehicle->bExplosionProof) m_nFlags |= FLAG_EXPLOSIONPROOF;
if (pVehicle->bCollisionProof) m_nFlags |= FLAG_COLLISIONPROOF;
if (pVehicle->bMeleeProof) m_nFlags |= FLAG_MELEEPROOF;
if (pVehicle->IsCar())
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType;
}
@ -1935,11 +1930,11 @@ CVehicle* CStoredCar::RestoreCar()
}
pVehicle->bHasBeenOwnedByPlayer = true;
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
pVehicle->bBulletProof = m_bBulletproof;
pVehicle->bFireProof = m_bFireproof;
pVehicle->bExplosionProof = m_bExplosionproof;
pVehicle->bCollisionProof = m_bCollisionproof;
pVehicle->bMeleeProof = m_bMeleeproof;
if (m_nFlags & FLAG_BULLETPROOF) pVehicle->bBulletProof = true;
if (m_nFlags & FLAG_FIREPROOF) pVehicle->bFireProof = true;
if (m_nFlags & FLAG_EXPLOSIONPROOF) pVehicle->bExplosionProof = true;
if (m_nFlags & FLAG_COLLISIONPROOF) pVehicle->bCollisionProof = true;
if (m_nFlags & FLAG_MELEEPROOF) pVehicle->bMeleeProof = true;
return pVehicle;
}
@ -2028,7 +2023,7 @@ void CGarages::GivePlayerDetonator()
float CGarages::FindDoorHeightForMI(int32 mi)
{
return CModelInfo::GetModelInfo(mi)->GetColModel()->boundingBox.max.z - CModelInfo::GetModelInfo(mi)->GetColModel()->boundingBox.min.z - 0.1f;
return CModelInfo::GetColModel(mi)->boundingBox.max.z - CModelInfo::GetColModel(mi)->boundingBox.min.z - 0.1f;
}
void CGarage::TidyUpGarage()
@ -2310,6 +2305,9 @@ void CGarages::Save(uint8 * buf, uint32 * size)
*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
#else
* size = 5484;
#endif
#if !defined THIS_IS_STUPID && !defined FIX_GARAGE_SIZE && defined COMPATIBLE_SAVES
memset(buf + 5240, 0, *size - 5240); // garbage data is written otherwise
#endif
CloseHideOutGaragesBeforeSave();
WriteSaveBuf(buf, NumGarages);
@ -2326,8 +2324,47 @@ void CGarages::Save(uint8 * buf, uint32 * size)
WriteSaveBuf(buf, aCarsInSafeHouse2[i]);
WriteSaveBuf(buf, aCarsInSafeHouse3[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].field_2);
WriteSaveBuf(buf, aGarages[i].m_bClosingWithoutTargetCar);
WriteSaveBuf(buf, aGarages[i].m_bDeactivated);
WriteSaveBuf(buf, aGarages[i].m_bResprayHappened);
ZeroSaveBuf(buf, 2);
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_fX1);
WriteSaveBuf(buf, aGarages[i].m_fX2);
WriteSaveBuf(buf, aGarages[i].m_fY1);
WriteSaveBuf(buf, aGarages[i].m_fY2);
WriteSaveBuf(buf, aGarages[i].m_fZ1);
WriteSaveBuf(buf, aGarages[i].m_fZ2);
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 + 4);
ZeroSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
WriteSaveBuf(buf, aGarages[i]);
#endif
}
#ifdef FIX_GARAGE_SIZE
VALIDATESAVEBUF(*size);
#endif
@ -2338,11 +2375,7 @@ const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
m_nModelIndex = other.m_nModelIndex;
m_vecPos = other.m_vecPos;
m_vecAngle = other.m_vecAngle;
m_bBulletproof = other.m_bBulletproof;
m_bFireproof = other.m_bFireproof;
m_bExplosionproof = other.m_bExplosionproof;
m_bCollisionproof = other.m_bCollisionproof;
m_bMeleeproof = other.m_bMeleeproof;
m_nFlags = other.m_nFlags;
m_nPrimaryColor = other.m_nPrimaryColor;
m_nSecondaryColor = other.m_nSecondaryColor;
m_nRadioStation = other.m_nRadioStation;
@ -2356,27 +2389,68 @@ void CGarages::Load(uint8* buf, uint32 size)
{
#ifdef FIX_GARAGE_SIZE
INITSAVEBUF
assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage)));
#else
assert(size == 5484);
#endif
CloseHideOutGaragesBeforeSave();
NumGarages = ReadSaveBuf<uint32>(buf);
BombsAreFree = ReadSaveBuf<uint32>(buf);
RespraysAreFree = ReadSaveBuf<uint32>(buf);
CarsCollected = ReadSaveBuf<int32>(buf);
BankVansCollected = ReadSaveBuf<int32>(buf);
PoliceCarsCollected = ReadSaveBuf<int32>(buf);
ReadSaveBuf(&NumGarages, buf);
int32 tempInt;
ReadSaveBuf(&tempInt, buf);
BombsAreFree = tempInt ? true : false;
ReadSaveBuf(&tempInt, buf);
RespraysAreFree = tempInt ? true : false;
ReadSaveBuf(&CarsCollected, buf);
ReadSaveBuf(&BankVansCollected, buf);
ReadSaveBuf(&PoliceCarsCollected, buf);
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
CarTypesCollected[i] = ReadSaveBuf<uint32>(buf);
LastTimeHelpMessage = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&CarTypesCollected[i], buf);
ReadSaveBuf(&LastTimeHelpMessage, buf);
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
aCarsInSafeHouse1[i] = ReadSaveBuf<CStoredCar>(buf);
aCarsInSafeHouse2[i] = ReadSaveBuf<CStoredCar>(buf);
aCarsInSafeHouse3[i] = ReadSaveBuf<CStoredCar>(buf);
ReadSaveBuf(&aCarsInSafeHouse1[i], buf);
ReadSaveBuf(&aCarsInSafeHouse2[i], buf);
ReadSaveBuf(&aCarsInSafeHouse3[i], buf);
}
for (int i = 0; i < NUM_GARAGES; i++) {
aGarages[i] = ReadSaveBuf<CGarage>(buf);
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aGarages[i].m_eGarageType, buf);
ReadSaveBuf(&aGarages[i].m_eGarageState, buf);
ReadSaveBuf(&aGarages[i].field_2, buf);
ReadSaveBuf(&aGarages[i].m_bClosingWithoutTargetCar, buf);
ReadSaveBuf(&aGarages[i].m_bDeactivated, buf);
ReadSaveBuf(&aGarages[i].m_bResprayHappened, buf);
SkipSaveBuf(buf, 2);
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_fX1, buf);
ReadSaveBuf(&aGarages[i].m_fX2, buf);
ReadSaveBuf(&aGarages[i].m_fY1, buf);
ReadSaveBuf(&aGarages[i].m_fY2, buf);
ReadSaveBuf(&aGarages[i].m_fZ1, buf);
ReadSaveBuf(&aGarages[i].m_fZ2, 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 + 4);
SkipSaveBuf(buf, sizeof(aGarages[i].m_sStoredCar));
#else
ReadSaveBuf(&aGarages[i], buf);
#endif
aGarages[i].m_pDoor1 = nil;
aGarages[i].m_pDoor2 = nil;
aGarages[i].m_pTarget = nil;

View File

@ -51,14 +51,17 @@ enum
class CStoredCar
{
enum {
FLAG_BULLETPROOF = 0x1,
FLAG_FIREPROOF = 0x2,
FLAG_EXPLOSIONPROOF = 0x4,
FLAG_COLLISIONPROOF = 0x8,
FLAG_MELEEPROOF = 0x10,
};
int32 m_nModelIndex;
CVector m_vecPos;
CVector m_vecAngle;
int32 m_bBulletproof : 1;
int32 m_bFireproof : 1;
int32 m_bExplosionproof : 1;
int32 m_bCollisionproof : 1;
int32 m_bMeleeproof : 1;
int32 m_nFlags;
int8 m_nPrimaryColor;
int8 m_nSecondaryColor;
int8 m_nRadioStation;
@ -78,6 +81,13 @@ VALIDATE_SIZE(CStoredCar, 0x28);
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
#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)
class CGarage
{
public:
@ -87,7 +97,7 @@ public:
bool m_bClosingWithoutTargetCar;
bool m_bDeactivated;
bool m_bResprayHappened;
int m_nTargetModelIndex;
int32 m_nTargetModelIndex;
CEntity *m_pDoor1;
CEntity *m_pDoor2;
uint8 m_bDoor1PoolIndex;

View File

@ -8,112 +8,111 @@
#include "Script.h"
#include "OnscreenTimer.h"
void COnscreenTimer::Init() {
void
COnscreenTimer::Init()
{
m_bDisabled = false;
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
m_sEntries[i].m_nTimerOffset = 0;
m_sEntries[i].m_nCounterOffset = 0;
for(uint32 j = 0; j < 10; j++) {
m_sEntries[i].m_aTimerText[j] = 0;
m_sEntries[i].m_aCounterText[j] = 0;
m_sEntries[i].m_aTimerText[j] = '\0';
m_sEntries[i].m_aCounterText[j] = '\0';
}
m_sEntries[i].m_nType = COUNTER_DISPLAY_NUMBER;
m_sEntries[i].m_bTimerProcessed = 0;
m_sEntries[i].m_bCounterProcessed = 0;
m_sEntries[i].m_bTimerProcessed = false;
m_sEntries[i].m_bCounterProcessed = false;
}
}
void COnscreenTimer::Process() {
if(!CReplay::IsPlayingBack() && !m_bDisabled) {
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
void
COnscreenTimer::Process()
{
if(!CReplay::IsPlayingBack() && !m_bDisabled)
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
m_sEntries[i].Process();
}
}
}
void COnscreenTimer::ProcessForDisplay() {
void
COnscreenTimer::ProcessForDisplay()
{
if(CHud::m_Wants_To_Draw_Hud) {
m_bProcessed = false;
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
if(m_sEntries[i].ProcessForDisplay()) {
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
if(m_sEntries[i].ProcessForDisplay())
m_bProcessed = true;
}
}
}
}
void COnscreenTimer::ClearCounter(uint32 offset) {
void
COnscreenTimer::ClearCounter(uint32 offset)
{
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
if(offset == m_sEntries[i].m_nCounterOffset) {
m_sEntries[i].m_nCounterOffset = 0;
m_sEntries[i].m_aCounterText[0] = 0;
m_sEntries[i].m_aCounterText[0] = '\0';
m_sEntries[i].m_nType = COUNTER_DISPLAY_NUMBER;
m_sEntries[i].m_bCounterProcessed = 0;
m_sEntries[i].m_bCounterProcessed = false;
}
}
}
void COnscreenTimer::ClearClock(uint32 offset) {
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
void
COnscreenTimer::ClearClock(uint32 offset)
{
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
if(offset == m_sEntries[i].m_nTimerOffset) {
m_sEntries[i].m_nTimerOffset = 0;
m_sEntries[i].m_aTimerText[0] = 0;
m_sEntries[i].m_bTimerProcessed = 0;
m_sEntries[i].m_aTimerText[0] = '\0';
m_sEntries[i].m_bTimerProcessed = false;
}
}
}
void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text) {
uint32 i = 0;
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
void
COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text)
{
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
if(m_sEntries[i].m_nCounterOffset == 0) {
m_sEntries[i].m_nCounterOffset = offset;
if (text)
strncpy(m_sEntries[i].m_aCounterText, text, 10);
else
m_sEntries[i].m_aCounterText[0] = '\0';
m_sEntries[i].m_nType = type;
break;
}
return;
}
m_sEntries[i].m_nCounterOffset = offset;
if(text) {
strncpy(m_sEntries[i].m_aCounterText, text, 10);
} else {
m_sEntries[i].m_aCounterText[0] = 0;
}
m_sEntries[i].m_nType = type;
}
void COnscreenTimer::AddClock(uint32 offset, char* text) {
uint32 i = 0;
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
void
COnscreenTimer::AddClock(uint32 offset, char* text)
{
for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++)
if(m_sEntries[i].m_nTimerOffset == 0) {
m_sEntries[i].m_nTimerOffset = offset;
if (text)
strncpy(m_sEntries[i].m_aTimerText, text, 10);
else
m_sEntries[i].m_aTimerText[0] = '\0';
break;
}
return;
}
m_sEntries[i].m_nTimerOffset = offset;
if(text) {
strncpy(m_sEntries[i].m_aTimerText, text, 10);
} else {
m_sEntries[i].m_aTimerText[0] = 0;
}
}
void COnscreenTimerEntry::Process() {
if(m_nTimerOffset == 0) {
void
COnscreenTimerEntry::Process()
{
if(m_nTimerOffset == 0)
return;
}
int32* timerPtr = CTheScripts::GetPointerToScriptVariable(m_nTimerOffset);
int32 oldTime = *timerPtr;
int32 newTime = oldTime - int32(CTimer::GetTimeStepInSeconds() * 1000);
int32 newTime = oldTime - int32(CTimer::GetTimeStepInMilliseconds());
if(newTime < 0) {
*timerPtr = 0;
m_bTimerProcessed = 0;
m_bTimerProcessed = false;
m_nTimerOffset = 0;
m_aTimerText[0] = 0;
m_aTimerText[0] = '\0';
} else {
*timerPtr = newTime;
int32 oldTimeSeconds = oldTime / 1000;
@ -123,13 +122,14 @@ void COnscreenTimerEntry::Process() {
}
}
bool COnscreenTimerEntry::ProcessForDisplay() {
bool
COnscreenTimerEntry::ProcessForDisplay()
{
m_bTimerProcessed = false;
m_bCounterProcessed = false;
if(m_nTimerOffset == 0 && m_nCounterOffset == 0) {
if(m_nTimerOffset == 0 && m_nCounterOffset == 0)
return false;
}
if(m_nTimerOffset != 0) {
m_bTimerProcessed = true;
@ -143,13 +143,17 @@ bool COnscreenTimerEntry::ProcessForDisplay() {
return true;
}
void COnscreenTimerEntry::ProcessForDisplayClock() {
void
COnscreenTimerEntry::ProcessForDisplayClock()
{
uint32 time = *CTheScripts::GetPointerToScriptVariable(m_nTimerOffset);
sprintf(m_bTimerBuffer, "%02d:%02d", time / 1000 / 60,
time / 1000 % 60);
}
void COnscreenTimerEntry::ProcessForDisplayCounter() {
void
COnscreenTimerEntry::ProcessForDisplayCounter()
{
uint32 counter = *CTheScripts::GetPointerToScriptVariable(m_nCounterOffset);
sprintf(m_bCounterBuffer, "%d", counter);
}

View File

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

View File

@ -13,10 +13,17 @@
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "soundlist.h"
#include "SaveBuf.h"
#ifdef FIX_BUGS
#include "Replay.h"
#endif
#ifdef COMPATIBLE_SAVES
#define PHONEINFO_SAVE_SIZE 0xA30
#else
#define PHONEINFO_SAVE_SIZE sizeof(CPhoneInfo)
#endif
CPhoneInfo gPhoneInfo;
bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up
@ -208,12 +215,29 @@ CPhoneInfo::IsMessageBeingDisplayed(int phoneId)
return pPhoneDisplayingMessages == &m_aPhones[phoneId];
}
#ifdef COMPATIBLE_SAVES
static inline void
LoadPhone(CPhone &phone, uint8 *&buf)
{
ReadSaveBuf(&phone.m_vecPos, buf);
SkipSaveBuf(buf, 6 * 4);
ReadSaveBuf<uint32>(&phone.m_repeatedMessagePickupStart, buf);
uint32 tmp;
ReadSaveBuf(&tmp, buf);
phone.m_pEntity = (CEntity*)(uintptr)tmp;
ReadSaveBuf<PhoneState>(&phone.m_nState, buf);
ReadSaveBuf<bool>(&phone.m_visibleToCam, buf);
SkipSaveBuf(buf, 3);
}
#endif
void
CPhoneInfo::Load(uint8 *buf, uint32 size)
{
INITSAVEBUF
int max = ReadSaveBuf<int32>(buf);
int scriptPhonesMax = ReadSaveBuf<int32>(buf);
int32 max, scriptPhonesMax;
ReadSaveBuf(&max, buf);
ReadSaveBuf(&scriptPhonesMax, buf);
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
m_nMax = Min(NUMPHONES, max);
@ -223,7 +247,13 @@ INITSAVEBUF
// We can do it without touching saves. We'll only load script phones, others are already loaded in Initialise
for (int i = 0; i < 50; i++) {
CPhone phoneToLoad = ReadSaveBuf<CPhone>(buf);
CPhone phoneToLoad;
#ifdef COMPATIBLE_SAVES
phoneToLoad.m_apMessages[0]=phoneToLoad.m_apMessages[1]=phoneToLoad.m_apMessages[2]=phoneToLoad.m_apMessages[3]=phoneToLoad.m_apMessages[4]=phoneToLoad.m_apMessages[5] = nil;
LoadPhone(phoneToLoad, buf);
#else
ReadSaveBuf(&phoneToLoad, buf);
#endif
if (ignoreOtherPhones)
continue;
@ -249,7 +279,11 @@ INITSAVEBUF
m_nScriptPhonesMax = scriptPhonesMax;
for (int i = 0; i < NUMPHONES; i++) {
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
#ifdef COMPATIBLE_SAVES
LoadPhone(m_aPhones[i], buf);
#else
ReadSaveBuf(&m_aPhones[i], buf);
#endif
// It's saved as building pool index in save file, convert it to true entity
if (m_aPhones[i].m_pEntity) {
m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
@ -373,7 +407,7 @@ CPhoneInfo::Initialise(void)
void
CPhoneInfo::Save(uint8 *buf, uint32 *size)
{
*size = sizeof(CPhoneInfo);
*size = PHONEINFO_SAVE_SIZE;
INITSAVEBUF
WriteSaveBuf(buf, m_nMax);
WriteSaveBuf(buf, m_nScriptPhonesMax);
@ -382,12 +416,24 @@ INITSAVEBUF
#else
for (int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
#endif
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, m_aPhones[phoneId].m_vecPos);
ZeroSaveBuf(buf, 6 * 4);
WriteSaveBuf(buf, m_aPhones[phoneId].m_repeatedMessagePickupStart);
// Convert entity pointer to building pool index while saving
int32 tmp = m_aPhones[phoneId].m_pEntity ? CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)m_aPhones[phoneId].m_pEntity) + 1 : 0;
WriteSaveBuf(buf, tmp);
WriteSaveBuf(buf, m_aPhones[phoneId].m_nState);
WriteSaveBuf(buf, m_aPhones[phoneId].m_visibleToCam);
ZeroSaveBuf(buf, 3);
#else
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
// Convert entity pointer to building pool index while saving
if (phone->m_pEntity) {
phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1);
}
#endif
}
VALIDATESAVEBUF(*size)
}

View File

@ -23,6 +23,7 @@
#ifdef FIX_BUGS
#include "Replay.h"
#endif
#include "SaveBuf.h"
#include "Script.h"
#include "Shadows.h"
#include "SpecialFX.h"
@ -31,6 +32,12 @@
#include "WaterLevel.h"
#include "World.h"
#ifdef COMPATIBLE_SAVES
#define PICKUPS_SAVE_SIZE 0x24C0
#else
#define PICKUPS_SAVE_SIZE sizeof(aPickUps)
#endif
CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages;
int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
@ -689,8 +696,7 @@ CPickups::DoPickUpEffects(CEntity *entity)
entity->bDoNotRender = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame;
if (!entity->bDoNotRender) {
float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
float modifiedSin = 0.3f * (s + 1.0f);
float modifiedSin = 0.3f * (Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)) + 1.0f);
int16 colorId;
@ -749,7 +755,20 @@ CPickups::DoPickUpEffects(CEntity *entity)
}
}
entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]);
float angle = (float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800);
float c = Cos(angle) * aWeaponScale[colorId];
float s = Sin(angle) * aWeaponScale[colorId];
// 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 = aWeaponScale[colorId];
}
}
@ -987,18 +1006,31 @@ CPickups::Load(uint8 *buf, uint32 size)
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
aPickUps[i] = ReadSaveBuf<CPickup>(buf);
#ifdef COMPATIBLE_SAVES
ReadSaveBuf(&aPickUps[i].m_eType, buf);
ReadSaveBuf(&aPickUps[i].m_bRemoved, buf);
ReadSaveBuf(&aPickUps[i].m_nQuantity, buf);
int32 tmp;
ReadSaveBuf(&tmp, buf);
aPickUps[i].m_pObject = aPickUps[i].m_eType != PICKUP_NONE && tmp != 0 ? CPools::GetObjectPool()->GetSlot(tmp - 1) : nil;
ReadSaveBuf(&aPickUps[i].m_nTimer, buf);
ReadSaveBuf(&aPickUps[i].m_eModelIndex, buf);
ReadSaveBuf(&aPickUps[i].m_nIndex, buf);
ReadSaveBuf(&aPickUps[i].m_vecPos, buf);
#else
ReadSaveBuf(&aPickUps[i], buf);
if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil)
aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((uintptr)aPickUps[i].m_pObject - 1);
#endif
}
CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
ReadSaveBuf<uint16>(buf);
ReadSaveBuf(&CollectedPickUpIndex, buf);
SkipSaveBuf(buf, 2);
NumMessages = 0;
for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++)
aPickUpsCollected[i] = ReadSaveBuf<int32>(buf);
ReadSaveBuf(&aPickUpsCollected[i], buf);
VALIDATESAVEBUF(size)
}
@ -1006,14 +1038,26 @@ VALIDATESAVEBUF(size)
void
CPickups::Save(uint8 *buf, uint32 *size)
{
*size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
*size = PICKUPS_SAVE_SIZE + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
#ifdef COMPATIBLE_SAVES
WriteSaveBuf(buf, aPickUps[i].m_eType);
WriteSaveBuf(buf, aPickUps[i].m_bRemoved);
WriteSaveBuf(buf, aPickUps[i].m_nQuantity);
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);
WriteSaveBuf(buf, aPickUps[i].m_nTimer);
WriteSaveBuf(buf, aPickUps[i].m_eModelIndex);
WriteSaveBuf(buf, aPickUps[i].m_nIndex);
WriteSaveBuf(buf, aPickUps[i].m_vecPos);
#else
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil)
buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pObject) + 1);
#endif
}
WriteSaveBuf(buf, CollectedPickUpIndex);

View File

@ -404,8 +404,8 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
CAnimBlendAssociation* main = RpAnimBlendClumpGetMainAssociation((RpClump*)ped->m_rwObject, &second, &blend_amount);
if (main){
state->animId = main->animId;
state->time = 255.0f / 4.0f * clamp(main->currentTime, 0.0f, 4.0f);
state->speed = 255.0f / 3.0f * clamp(main->speed, 0.0f, 3.0f);
state->time = 255.0f / 4.0f * Clamp(main->currentTime, 0.0f, 4.0f);
state->speed = 255.0f / 3.0f * Clamp(main->speed, 0.0f, 3.0f);
}else{
state->animId = 3;
state->time = 0;
@ -413,9 +413,9 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
}
if (second) {
state->secAnimId = second->animId;
state->secTime = 255.0f / 4.0f * clamp(second->currentTime, 0.0f, 4.0f);
state->secSpeed = 255.0f / 3.0f * clamp(second->speed, 0.0f, 3.0f);
state->blendAmount = 255.0f / 2.0f * clamp(blend_amount, 0.0f, 2.0f);
state->secTime = 255.0f / 4.0f * Clamp(second->currentTime, 0.0f, 4.0f);
state->secSpeed = 255.0f / 3.0f * Clamp(second->speed, 0.0f, 3.0f);
state->blendAmount = 255.0f / 2.0f * Clamp(blend_amount, 0.0f, 2.0f);
}else{
state->secAnimId = 0;
state->secTime = 0;
@ -425,9 +425,9 @@ void CReplay::StorePedAnimation(CPed *ped, CStoredAnimationState *state)
CAnimBlendAssociation* partial = RpAnimBlendClumpGetMainPartialAssociation((RpClump*)ped->m_rwObject);
if (partial) {
state->partAnimId = partial->animId;
state->partAnimTime = 255.0f / 4.0f * clamp(partial->currentTime, 0.0f, 4.0f);
state->partAnimSpeed = 255.0f / 3.0f * clamp(partial->speed, 0.0f, 3.0f);
state->partBlendAmount = 255.0f / 2.0f * clamp(partial->blendAmount, 0.0f, 2.0f);
state->partAnimTime = 255.0f / 4.0f * Clamp(partial->currentTime, 0.0f, 4.0f);
state->partAnimSpeed = 255.0f / 3.0f * Clamp(partial->speed, 0.0f, 3.0f);
state->partBlendAmount = 255.0f / 2.0f * Clamp(partial->blendAmount, 0.0f, 2.0f);
}else{
state->partAnimId = 0;
state->partAnimTime = 0;
@ -442,11 +442,11 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainAssociation_N((RpClump*)ped->m_rwObject, i);
if (assoc){
state->aAnimId[i] = assoc->animId;
state->aCurTime[i] = 255.0f / 4.0f * clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed[i] = 255.0f / 3.0f * clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount[i] = 255.0f / 2.0f * clamp(assoc->blendAmount, 0.0f, 2.0f);
state->aCurTime[i] = 255.0f / 4.0f * Clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed[i] = 255.0f / 3.0f * Clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount[i] = 255.0f / 2.0f * Clamp(assoc->blendAmount, 0.0f, 2.0f);
#ifdef FIX_REPLAY_BUGS
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);
#endif
state->aFlags[i] = assoc->flags;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
@ -468,11 +468,11 @@ void CReplay::StoreDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationState
CAnimBlendAssociation* assoc = RpAnimBlendClumpGetMainPartialAssociation_N((RpClump*)ped->m_rwObject, i);
if (assoc) {
state->aAnimId2[i] = assoc->animId;
state->aCurTime2[i] = 255.0f / 4.0f * clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed2[i] = 255.0f / 3.0f * clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount2[i] = 255.0f / 2.0f * clamp(assoc->blendAmount, 0.0f, 2.0f);
state->aCurTime2[i] = 255.0f / 4.0f * Clamp(assoc->currentTime, 0.0f, 4.0f);
state->aSpeed2[i] = 255.0f / 3.0f * Clamp(assoc->speed, 0.0f, 3.0f);
state->aBlendAmount2[i] = 255.0f / 2.0f * Clamp(assoc->blendAmount, 0.0f, 2.0f);
#ifdef FIX_REPLAY_BUGS
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);
#endif
state->aFlags2[i] = assoc->flags;
if (assoc->callbackType == CAnimBlendAssociation::CB_FINISH || assoc->callbackType == CAnimBlendAssociation::CB_DELETE) {
@ -1232,7 +1232,7 @@ void CReplay::RestoreStuffFromMem(void)
ped->SetModelIndex(mi);
ped->m_pVehicleAnim = nil;
ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped);
DMAudio.SetEntityStatus(ped->m_audioEntityId, true);
DMAudio.SetEntityStatus(ped->m_audioEntityId, TRUE);
CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false);
if (ped->m_wepModelID >= 0)
ped->AddWeaponModel(ped->m_wepModelID);
@ -1270,7 +1270,7 @@ void CReplay::RestoreStuffFromMem(void)
car->SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT, true);
}
vehicle->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, vehicle);
DMAudio.SetEntityStatus(vehicle->m_audioEntityId, true);
DMAudio.SetEntityStatus(vehicle->m_audioEntityId, TRUE);
CCarCtrl::UpdateCarCount(vehicle, false);
if ((mi == MI_AIRTRAIN || mi == MI_DEADDODO) && vehicle->m_rwObject){
CVehicleModelInfo* info = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi);

View File

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

View File

@ -51,11 +51,11 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
CEntity* pEntityToAttack = (CEntity*)FindPlayerVehicle();
if (!pEntityToAttack)
pEntityToAttack = (CEntity*)FindPlayerPed();
CColModel* pPoliceColModel = CModelInfo::GetModelInfo(MI_POLICE)->GetColModel();
CColModel* pPoliceColModel = CModelInfo::GetColModel(MI_POLICE);
float fRadius = pVehicle->GetBoundRadius() / pPoliceColModel->boundingSphere.radius;
for (int32 i = 0; i < 2; i++) {
const int32 roadBlockIndex = i + 2 * roadBlockType;
CVector posForZ = pVehicle->m_matrix * (fRadius * vecRoadBlockOffets[roadBlockIndex]);
CVector posForZ = pVehicle->GetMatrix() * (fRadius * vecRoadBlockOffets[roadBlockIndex]);
int32 modelInfoId = MI_COP;
eCopType copType = COP_STREET;
switch (pVehicle->GetModelIndex())
@ -80,9 +80,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
pCopPed->SetCurrentWeapon(WEAPONTYPE_COLT45);
CPedPlacement::FindZCoorForPed(&posForZ);
pCopPed->SetPosition(posForZ);
CVector vecSavedPos = pCopPed->GetPosition();
pCopPed->m_matrix.SetRotate(0.0f, 0.0f, -HALFPI);
pCopPed->m_matrix.GetPosition() += vecSavedPos;
pCopPed->SetOrientation(0.0f, 0.0f, -HALFPI);
pCopPed->m_bIsDisabledCop = true;
pCopPed->SetIdle();
pCopPed->bKindaStayInSamePlace = true;
@ -132,7 +130,7 @@ CRoadBlocks::GenerateRoadBlocks(void)
vehicleId = MI_ENFORCER;
if (!CStreaming::HasModelLoaded(vehicleId))
vehicleId = MI_POLICE;
CColModel *pVehicleColModel = CModelInfo::GetModelInfo(vehicleId)->GetColModel();
CColModel *pVehicleColModel = CModelInfo::GetColModel(vehicleId);
float fModelRadius = 2.0f * pVehicleColModel->boundingSphere.radius + 0.25f;
int16 radius = (int16)(fMapObjectRadius / fModelRadius);
if (radius >= 6)
@ -153,8 +151,8 @@ CRoadBlocks::GenerateRoadBlocks(void)
offsetMatrix.GetPosition() = CVector(0.0f, i * fModelRadius - fOffset, 0.6f);
else
offsetMatrix.GetPosition() = CVector(i * fModelRadius - fOffset, 0.0f, 0.6f);
CMatrix vehicleMatrix = mapObject->m_matrix * offsetMatrix;
float fModelRadius = CModelInfo::GetModelInfo(vehicleId)->GetColModel()->boundingSphere.radius - 0.25f;
CMatrix vehicleMatrix = mapObject->GetMatrix() * offsetMatrix;
float fModelRadius = CModelInfo::GetColModel(vehicleId)->boundingSphere.radius - 0.25f;
int16 colliding = 0;
CWorld::FindObjectsKindaColliding(vehicleMatrix.GetPosition(), fModelRadius, 0, &colliding, 2, nil, false, true, true, false, false);
if (!colliding) {
@ -162,10 +160,10 @@ CRoadBlocks::GenerateRoadBlocks(void)
pVehicle->SetStatus(STATUS_ABANDONED);
// pVehicle->GetHeightAboveRoad(); // called but return value is ignored?
vehicleMatrix.GetPosition().z += fModelRadius - 0.6f;
pVehicle->m_matrix = vehicleMatrix;
pVehicle->SetMatrix(vehicleMatrix);
pVehicle->PlaceOnRoadProperly();
pVehicle->SetIsStatic(false);
pVehicle->m_matrix.UpdateRW();
pVehicle->GetMatrix().UpdateRW();
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
pVehicle->bIsLocked = false;

File diff suppressed because it is too large Load Diff

View File

@ -347,9 +347,13 @@ public:
void LocateCharCommand(int32, uint32*);
void LocateCharCharCommand(int32, uint32*);
void LocateCharCarCommand(int32, uint32*);
#if GTA_VERSION > GTA3_PS2_160
void LocateCharObjectCommand(int32, uint32*);
#endif
void LocateCarCommand(int32, uint32*);
#if GTA_VERSION > GTA3_PS2_160
void LocateSniperBulletCommand(int32, uint32*);
#endif
void PlayerInAreaCheckCommand(int32, uint32*);
void PlayerInAngledAreaCheckCommand(int32, uint32*);
void CharInAreaCheckCommand(int32, uint32*);
@ -370,6 +374,13 @@ public:
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
int CollectParameterForDebug(char* buf, bool& var);
void GetStoredParameterForDebug(char* buf);
void LogOnStartProcessing();
void LogBeforeProcessingCommand(int32 command);
void LogAfterProcessingCommand(int32 command);
static char commandInfo[];
static uint32 storedIp;
#endif
float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
@ -576,6 +587,17 @@ public:
public:
static void SwitchToMission(int32 mission);
#endif
#ifdef USE_DEBUG_SCRIPT_LOADER
static int ScriptToLoad;
static int OpenScript();
#endif
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
static void LogAfterScriptInitializing();
static void LogBeforeScriptProcessing();
static void LogAfterScriptProcessing();
#endif
};
#ifdef MISSION_REPLAY
@ -587,9 +609,22 @@ extern int missionRetryScriptIndex;
extern bool doingMissionRetry;
uint32 AddExtraDeathDelay();
void RetryMission(int, int);
#endif
void RetryMission(int, int unk = 0);
#ifdef USE_DEBUG_SCRIPT_LOADER
extern int scriptToLoad;
#endif
enum {
MISSION_RETRY_TYPE_SUGGEST_TO_PLAYER = 0,
MISSION_RETRY_TYPE_1,
MISSION_RETRY_TYPE_BEGIN_RESTARTING
};
enum {
MISSION_RETRY_STAGE_NORMAL = 0,
MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE,
MISSION_RETRY_STAGE_START_PROCESSING,
MISSION_RETRY_STAGE_WAIT_FOR_DELAY,
MISSION_RETRY_STAGE_WAIT_FOR_MENU,
MISSION_RETRY_STAGE_WAIT_FOR_USER,
MISSION_RETRY_STAGE_START_RESTARTING,
MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART,
};
#endif

View File

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

View File

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

View File

@ -12,6 +12,7 @@
#include "Pools.h"
#include "Population.h"
#include "RpAnimBlend.h"
#include "SaveBuf.h"
#include "Shadows.h"
#include "SpecialFX.h"
#include "World.h"
@ -581,6 +582,7 @@ void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp)
}
}
#if GTA_VERSION > GTA3_PS2_160
void CRunningScript::LocateCharObjectCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug;
@ -658,6 +660,7 @@ void CRunningScript::LocateCharObjectCommand(int32 command, uint32* pIp)
CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
}
}
#endif
void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
{
@ -731,6 +734,7 @@ void CRunningScript::LocateCarCommand(int32 command, uint32* pIp)
}
}
#if GTA_VERSION > GTA3_PS2_160
void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp)
{
bool b3D, result, debug;
@ -769,6 +773,7 @@ void CRunningScript::LocateSniperBulletCommand(int32 command, uint32* pIp)
CTheScripts::DrawDebugSquare(X - dX, Y - dY, X + dX, Y + dY);
}
}
#endif
void CRunningScript::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
{
@ -948,10 +953,10 @@ void CRunningScript::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
initAngle -= TWOPI;
// it looks like the idea is to use a rectangle using the diagonal of the rectangle as
// the side of new rectangle, with "length" being the length of second side
float rotatedSupX = supX + side2length * sin(initAngle);
float rotatedSupY = supY - side2length * cos(initAngle);
float rotatedInfX = infX + side2length * sin(initAngle);
float rotatedInfY = infY - side2length * cos(initAngle);
float rotatedSupX = supX + side2length * Sin(initAngle);
float rotatedSupY = supY - side2length * Cos(initAngle);
float rotatedInfX = infX + side2length * Sin(initAngle);
float rotatedInfY = infY - side2length * Cos(initAngle);
float side1X = supX - infX;
float side1Y = supY - infY;
float side1Length = CVector2D(side1X, side1Y).Magnitude();
@ -1238,10 +1243,10 @@ void CRunningScript::DoDeatharrestCheck()
if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown())
return;
#ifdef MISSION_REPLAY
if (AllowMissionReplay != 0)
if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL)
return;
if (CanAllowMissionReplay())
AllowMissionReplay = 1;
AllowMissionReplay = MISSION_RETRY_STAGE_WAIT_FOR_SCRIPT_TO_TERMINATE;
#endif
script_assert(m_nStackPointer > 0);
while (m_nStackPointer > 1)
@ -2002,21 +2007,25 @@ void CTheScripts::LoadAllScripts(uint8* buf, uint32 size)
Init();
INITSAVEBUF
CheckSaveHeader(buf, 'S', 'C', 'R', '\0', size - SAVE_HEADER_SIZE);
uint32 varSpace = ReadSaveBuf<uint32>(buf);
uint32 varSpace, type, handle;
uint32 tmp;
ReadSaveBuf(&varSpace, buf);
for (uint32 i = 0; i < varSpace; i++)
ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE);
OnAMissionFlag = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&ScriptSpace[i], buf);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == SCRIPT_DATA_SIZE);
ReadSaveBuf(&OnAMissionFlag, buf);
for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) {
OnAMissionForContactFlag[i] = ReadSaveBuf<uint32>(buf);
BaseBriefIdForContact[i] = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&OnAMissionForContactFlag[i], buf);
ReadSaveBuf(&BaseBriefIdForContact[i], buf);
}
for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++)
CollectiveArray[i] = ReadSaveBuf<tCollectiveData>(buf);
NextFreeCollectiveIndex = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&CollectiveArray[i], buf);
ReadSaveBuf(&NextFreeCollectiveIndex, buf);
for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
uint32 handle = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&type, buf);
ReadSaveBuf(&handle, buf);
switch (type) {
case 0:
BuildingSwapArray[i].m_pBuilding = nil;
@ -2030,14 +2039,14 @@ INITSAVEBUF
default:
script_assert(false);
}
BuildingSwapArray[i].m_nNewModel = ReadSaveBuf<uint32>(buf);
BuildingSwapArray[i].m_nOldModel = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&BuildingSwapArray[i].m_nNewModel, buf);
ReadSaveBuf(&BuildingSwapArray[i].m_nOldModel, buf);
if (BuildingSwapArray[i].m_pBuilding)
BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nNewModel);
}
for (uint32 i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
uint32 handle = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&type, buf);
ReadSaveBuf(&handle, buf);
switch (type) {
case 0:
InvisibilitySettingArray[i] = nil;
@ -2060,14 +2069,20 @@ INITSAVEBUF
if (InvisibilitySettingArray[i])
InvisibilitySettingArray[i]->bIsVisible = false;
}
script_assert(ReadSaveBuf<bool>(buf) == bUsingAMultiScriptFile);
ReadSaveBuf<uint8>(buf);
ReadSaveBuf<uint16>(buf);
script_assert(ReadSaveBuf<uint32>(buf) == MainScriptSize);
script_assert(ReadSaveBuf<uint32>(buf) == LargestMissionScriptSize);
script_assert(ReadSaveBuf<uint16>(buf) == NumberOfMissionScripts);
ReadSaveBuf<uint16>(buf);
uint32 runningScripts = ReadSaveBuf<uint32>(buf);
bool tmpBool;
ReadSaveBuf(&tmpBool, buf);
script_assert(tmpBool == bUsingAMultiScriptFile);
SkipSaveBuf(buf, 3);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == MainScriptSize);
ReadSaveBuf(&tmp, buf);
script_assert(tmp == LargestMissionScriptSize);
uint16 tmp16;
ReadSaveBuf(&tmp16, buf);
script_assert(tmp16 == NumberOfMissionScripts);
SkipSaveBuf(buf, 2);
uint32 runningScripts;
ReadSaveBuf(&runningScripts, buf);
for (uint32 i = 0; i < runningScripts; i++)
StartNewScript(0)->Load(buf);
VALIDATESAVEBUF(size)
@ -2078,33 +2093,33 @@ VALIDATESAVEBUF(size)
void CRunningScript::Save(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
ZeroSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
WriteSaveBuf<char>(buf, m_abScriptName[i]);
WriteSaveBuf<uint32>(buf, m_nIp);
WriteSaveBuf(buf, m_abScriptName[i]);
WriteSaveBuf(buf, m_nIp);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
WriteSaveBuf<uint32>(buf, m_anStack[i]);
WriteSaveBuf<uint16>(buf, m_nStackPointer);
SkipSaveBuf(buf, 2);
WriteSaveBuf(buf, m_anStack[i]);
WriteSaveBuf(buf, m_nStackPointer);
ZeroSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
WriteSaveBuf<bool>(buf, m_bCondResult);
WriteSaveBuf<bool>(buf, m_bIsMissionScript);
WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
SkipSaveBuf(buf, 1);
WriteSaveBuf<uint32>(buf, m_nWakeTime);
WriteSaveBuf<uint16>(buf, m_nAndOrState);
WriteSaveBuf<bool>(buf, m_bNotFlag);
WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled);
WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted);
WriteSaveBuf<bool>(buf, m_bMissionFlag);
SkipSaveBuf(buf, 2);
WriteSaveBuf(buf, m_anLocalVariables[i]);
WriteSaveBuf(buf, m_bCondResult);
WriteSaveBuf(buf, m_bIsMissionScript);
WriteSaveBuf(buf, m_bSkipWakeTime);
ZeroSaveBuf(buf, 1);
WriteSaveBuf(buf, m_nWakeTime);
WriteSaveBuf(buf, m_nAndOrState);
WriteSaveBuf(buf, m_bNotFlag);
WriteSaveBuf(buf, m_bDeatharrestEnabled);
WriteSaveBuf(buf, m_bDeatharrestExecuted);
WriteSaveBuf(buf, m_bMissionFlag);
ZeroSaveBuf(buf, 2);
#else
WriteSaveBuf(buf, *this);
#endif
@ -2115,35 +2130,35 @@ void CRunningScript::Load(uint8*& buf)
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
m_abScriptName[i] = ReadSaveBuf<char>(buf);
m_nIp = ReadSaveBuf<uint32>(buf);
ReadSaveBuf(&m_abScriptName[i], buf);
ReadSaveBuf(&m_nIp, buf);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
m_anStack[i] = ReadSaveBuf<uint32>(buf);
m_nStackPointer = ReadSaveBuf<uint16>(buf);
ReadSaveBuf(&m_anStack[i], buf);
ReadSaveBuf(&m_nStackPointer, buf);
SkipSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
m_bCondResult = ReadSaveBuf<bool>(buf);
m_bIsMissionScript = ReadSaveBuf<bool>(buf);
m_bSkipWakeTime = ReadSaveBuf<bool>(buf);
ReadSaveBuf(&m_anLocalVariables[i], buf);
ReadSaveBuf(&m_bCondResult, buf);
ReadSaveBuf(&m_bIsMissionScript, buf);
ReadSaveBuf(&m_bSkipWakeTime, buf);
SkipSaveBuf(buf, 1);
m_nWakeTime = ReadSaveBuf<uint32>(buf);
m_nAndOrState = ReadSaveBuf<uint16>(buf);
m_bNotFlag = ReadSaveBuf<bool>(buf);
m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf);
m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf);
m_bMissionFlag = ReadSaveBuf<bool>(buf);
ReadSaveBuf(&m_nWakeTime, buf);
ReadSaveBuf(&m_nAndOrState, buf);
ReadSaveBuf(&m_bNotFlag, buf);
ReadSaveBuf(&m_bDeatharrestEnabled, buf);
ReadSaveBuf(&m_bDeatharrestExecuted, buf);
ReadSaveBuf(&m_bMissionFlag, buf);
SkipSaveBuf(buf, 2);
#else
CRunningScript* n = next;
CRunningScript* p = prev;
*this = ReadSaveBuf<CRunningScript>(buf);
ReadSaveBuf(this, buf);
next = n;
prev = p;
#endif

View File

@ -82,8 +82,8 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
CollectParameters(&m_nIp, 1);
#ifdef MISSION_REPLAY
AllowMissionReplay = 0;
SaveGameForPause(3);
AllowMissionReplay = MISSION_RETRY_STAGE_NORMAL;
SaveGameForPause(SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY);
#endif
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
@ -304,8 +304,12 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
#ifdef USE_DEBUG_SCRIPT_LOADER
int handle = CTheScripts::OpenScript();
#else
CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
#endif
CFileMgr::Seek(handle, offset, 0);
CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
CFileMgr::CloseFile(handle);
@ -1334,7 +1338,6 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CPed::nEnterCarRangeMultiplier = (float)ScriptParams[0];
#endif
return 0;
#endif
#if GTA_VERSION < GTA3_PC_11
case COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER:
CollectParameters(&m_nIp, 1);
@ -1344,6 +1347,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
CPed::nThreatReactionRangeMultiplier = (float)ScriptParams[0];
#endif
return 0;
#endif
#endif
default:
script_assert(0);

1441
src/control/ScriptDebug.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3482,7 +3482,7 @@ FindSplinePathPositionFloat(float *out, float *spline, uint32 time, uint32 &mark
}
}
float a = ((float)time - (float)MS(spline[marker-4])) / (float)MS(spline[marker] - spline[marker-4]);
a = clamp(a, 0.0f, 1.0f);
a = Clamp(a, 0.0f, 1.0f);
float b = 1.0f - a;
*out = b*b*b * spline[marker-3] +
3.0f*a*b*b * spline[marker-1] +
@ -3520,7 +3520,7 @@ FindSplinePathPositionVector(CVector *out, float *spline, uint32 time, uint32 &m
}
float a = ((float)time - (float)MS(spline[marker-10])) / (float)MS(spline[marker] - spline[marker-10]);
a = clamp(a, 0.0f, 1.0f);
a = Clamp(a, 0.0f, 1.0f);
float b = 1.0f - a;
out->x =
b*b*b * spline[marker-9] +
@ -4816,7 +4816,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
{1.3f, 1.0f, 0.4f, 10.0f, 15.0f, 0.5f, 1.0f, 1.0f, 0.85f, 0.2f, 0.075f, 0.05f, 0.8f, DEGTORAD(45.0f), DEGTORAD(89.0f)}, // cars
{1.1f, 1.0f, 0.1f, 10.0f, 11.0f, 0.5f, 1.0f, 1.0f, 0.85f, 0.2f, 0.075f, 0.05f, 0.75f, DEGTORAD(45.0f), DEGTORAD(89.0f)}, // bike
{1.1f, 1.0f, 0.2f, 10.0f, 15.0f, 0.05f, 0.05f, 0.0f, 0.9f, 0.05f, 0.01f, 0.05f, 1.0f, DEGTORAD(10.0f), DEGTORAD(70.0f)}, // heli (SA values)
{1.1f, 3.5f, 0.2f, 10.0f, 25.0f, 0.5f, 1.0f, 1.0f, 0.75f, 0.1f, 0.005f, 0.2f, 1.0f, DEGTORAD(89.0f), DEGTORAD(89.0f)}, // plane (SA values)
{1.1f, 1.0f, 0.2f, 10.0f, 15.0f, 0.5f, 1.0f, 1.0f, 0.75f, 0.1f, 0.005f, 0.2f, 1.0f, DEGTORAD(89.0f), DEGTORAD(89.0f)}, // plane (SA values)
{0.9f, 1.0f, 0.1f, 10.0f, 15.0f, 0.5f, 1.0f, 0.0f, 0.9f, 0.05f, 0.005f, 0.05f, 1.0f, -0.2f, DEGTORAD(70.0f)}, // boat
{1.1f, 1.0f, 0.2f, 10.0f, 5.0f, 0.5f, 1.0f, 1.0f, 0.75f, 0.1f, 0.005f, 0.2f, 1.0f, DEGTORAD(45.0f), DEGTORAD(89.0f)}, // rc cars
{1.1f, 1.0f, 0.2f, 10.0f, 5.0f, 0.5f, 1.0f, 1.0f, 0.75f, 0.1f, 0.005f, 0.2f, 1.0f, DEGTORAD(20.0f), DEGTORAD(70.0f)}, // rc heli/planes
@ -4899,7 +4899,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// 0.98f: CAR_FOV_FADE_MULT
FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV;
FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f);
FOV = Clamp(FOV, DefaultFOV, DefaultFOV + 30.0f);
}
// WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta)
@ -4933,9 +4933,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
AlphaSpeed = 0.0;
Distance = 1000.0;
Front.x = -(cos(Beta) * cos(Alpha));
Front.y = -(sin(Beta) * cos(Alpha));
Front.z = sin(Alpha);
Front.x = -(Cos(Beta) * Cos(Alpha));
Front.y = -(Sin(Beta) * Cos(Alpha));
Front.z = Sin(Alpha);
m_aTargetHistoryPosOne = TargetCoors - nextDistance * Front;
@ -5021,7 +5021,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
}
}
float targetAlpha = Asin(clamp(Front.z, -1.0f, 1.0f)) - zoomModeAlphaOffset;
float targetAlpha = Asin(Clamp(Front.z, -1.0f, 1.0f)) - zoomModeAlphaOffset;
if (targetAlpha <= maxAlphaAllowed) {
if (targetAlpha < -CARCAM_SET[camSetArrPos][14])
targetAlpha = -CARCAM_SET[camSetArrPos][14];
@ -5210,9 +5210,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
lastBeta = Beta;
Front.x = -(cos(Beta) * cos(Alpha));
Front.y = -(sin(Beta) * cos(Alpha));
Front.z = sin(Alpha);
Front.x = -(Cos(Beta) * Cos(Alpha));
Front.y = -(Sin(Beta) * Cos(Alpha));
Front.z = Sin(Alpha);
GetVectorsReadyForRW();
TheCamera.m_bCamDirectlyBehind = false;
TheCamera.m_bCamDirectlyInFront = false;
@ -5222,9 +5222,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
m_cvecTargetCoorsForFudgeInter = TargetCoors;
m_aTargetHistoryPosThree = m_aTargetHistoryPosOne;
float nextAlpha = alphaWithSpeedAccounted + zoomModeAlphaOffset;
float nextFrontX = -(cos(Beta) * cos(nextAlpha));
float nextFrontY = -(sin(Beta) * cos(nextAlpha));
float nextFrontZ = sin(nextAlpha);
float nextFrontX = -(Cos(Beta) * Cos(nextAlpha));
float nextFrontY = -(Sin(Beta) * Cos(nextAlpha));
float nextFrontZ = Sin(nextAlpha);
m_aTargetHistoryPosOne.x = TargetCoors.x - nextFrontX * nextDistance;
m_aTargetHistoryPosOne.y = TargetCoors.y - nextFrontY * nextDistance;

View File

@ -213,7 +213,7 @@ CCamera::Init(void)
m_iModeToGoTo = CCam::MODE_FOLLOWPED;
m_bJust_Switched = false;
m_bUseTransitionBeta = false;
m_matrix.SetScale(1.0f);
GetMatrix().SetScale(1.0f);
m_bTargetJustBeenOnTrain = false;
m_bInitialNoNodeStaticsSet = false;
m_uiLongestTimeInMill = 5000;
@ -661,7 +661,7 @@ CCamera::Process(void)
// Process Shake
float shakeStrength = m_fCamShakeForce - 0.28f*(CTimer::GetTimeInMilliseconds()-m_uiCamShakeStart)/1000.0f;
shakeStrength = clamp(shakeStrength, 0.0f, 2.0f);
shakeStrength = Clamp(shakeStrength, 0.0f, 2.0f);
int shakeRand = CGeneral::GetRandomNumber();
float shakeOffset = shakeStrength*0.1f;
GetMatrix().GetPosition().x += shakeOffset * ((shakeRand & 0xF) - 7);
@ -1877,7 +1877,7 @@ CCamera::CamShake(float strength, float x, float y, float z)
float curForce = mult*(m_fCamShakeForce - (CTimer::GetTimeInMilliseconds() - m_uiCamShakeStart)/1000.0f);
strength = mult*strength;
if(clamp(curForce, 0.0f, 2.0f) < strength){
if(Clamp(curForce, 0.0f, 2.0f) < strength){
m_fCamShakeForce = strength;
m_uiCamShakeStart = CTimer::GetTimeInMilliseconds();
}
@ -1888,7 +1888,7 @@ void
CamShakeNoPos(CCamera *cam, float strength)
{
float curForce = cam->m_fCamShakeForce - (CTimer::GetTimeInMilliseconds() - cam->m_uiCamShakeStart)/1000.0f;
if(clamp(curForce, 0.0f, 2.0f) < strength){
if(Clamp(curForce, 0.0f, 2.0f) < strength){
cam->m_fCamShakeForce = strength;
cam->m_uiCamShakeStart = CTimer::GetTimeInMilliseconds();
}
@ -3572,7 +3572,7 @@ CCamera::Find3rdPersonCamTargetVector(float dist, CVector pos, CVector &source,
float
CCamera::Find3rdPersonQuickAimPitch(void)
{
float clampedFrontZ = clamp(Cams[ActiveCam].Front.z, -1.0f, 1.0f);
float clampedFrontZ = Clamp(Cams[ActiveCam].Front.z, -1.0f, 1.0f);
float rot = Asin(clampedFrontZ);
@ -3592,7 +3592,7 @@ CCamera::SetRwCamera(RwCamera *cam)
void
CCamera::CalculateDerivedValues(void)
{
m_cameraMatrix = Invert(m_matrix);
m_cameraMatrix = Invert(GetMatrix());
float hfov = DEGTORAD(CDraw::GetScaledFOV()/2.0f);
float c = Cos(hfov);
@ -3650,7 +3650,7 @@ CCamera::IsPointVisible(const CVector &center, const CMatrix *mat)
}
bool
CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat)
CCamera::IsSphereVisible(const CVector &center, float radius, Const CMatrix *mat)
{
#ifdef GTA_PS2
CVuVector c;
@ -3675,16 +3675,18 @@ CCamera::IsSphereVisible(const CVector &center, float radius, const CMatrix *mat
bool
CCamera::IsSphereVisible(const CVector &center, float radius)
{
CMatrix mat = m_cameraMatrix;
#if GTA_VERSION < GTA3_PC_10 // not sure this condition is the right one
// Maybe this was a copy of the other function with m_cameraMatrix
return IsSphereVisible(center, radius, &m_cameraMatrix);
#else
// ...and on PC they decided to call the other one with a default matrix.
CMatrix mat(GetCameraMatrix()); // this matrix construction is stupid and gone in VC
return IsSphereVisible(center, radius, &mat);
#endif
}
bool
#ifdef GTA_PS2
CCamera::IsBoxVisible(CVuVector *box, const CMatrix *mat)
#else
CCamera::IsBoxVisible(CVector *box, const CMatrix *mat)
#endif
CCamera::IsBoxVisible(CVUVECTOR *box, const CMatrix *mat)
{
int i;
int frustumTests[6] = { 0 };

View File

@ -639,13 +639,9 @@ public:
CVector &GetGameCamPosition(void) { return m_vecGameCamPos; }
void CalculateDerivedValues(void);
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);
#ifdef GTA_PS2
bool IsBoxVisible(CVuVector *box, const CMatrix *mat);
#else
bool IsBoxVisible(CVector *box, const CMatrix *mat);
#endif
bool IsBoxVisible(CVUVECTOR *box, const CMatrix *mat);
};
VALIDATE_SIZE(CCamera, 0xE9D8);

View File

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

View File

@ -2644,6 +2644,14 @@ const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
#undef PS2_CROSS
#undef PS2_SQUARE
const char *NintendoSwitchButtons_noIcons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS("Y", "A", "B", "X", "L", "ZL", "LS", "R", "ZR", "RS", "BACK");
#ifdef BUTTON_ICONS
const char *NintendoSwitchButtons[][MAX_CONTROLLERACTIONS] =
CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
#endif
#undef CONTROLLER_BUTTONS
#undef VFB
@ -2664,6 +2672,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = CFont::ButtonsSlot != -1 ? PlayStationButtons : PlayStationButtons_noIcons;
break;
case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
Buttons = CFont::ButtonsSlot != -1 ? NintendoSwitchButtons : NintendoSwitchButtons_noIcons;
break;
default:
#endif
Buttons = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
@ -2679,6 +2690,9 @@ void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *
case CMenuManager::CONTROLLER_DUALSHOCK4:
Buttons = PlayStationButtons_noIcons;
break;
case CMenuManager::CONTROLLER_NINTENDO_SWITCH:
Buttons = NintendoSwitchButtons_noIcons;
break;
default:
Buttons = XboxButtons_noIcons;
break;

View File

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

View File

@ -670,6 +670,7 @@ char *DoubleSidedNames[] = {
"sbwy_tunl_cstm3",
"sbwy_tunl_cstm2",
"sbwy_tunl_cstm1",
"tenmnt6ad",
""
};
@ -1134,12 +1135,12 @@ CFileLoader::LoadMLO(const char *line)
char smth[8];
char name[24];
int modelIndex;
float someFloat;
float drawDist;
sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat);
sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &drawDist);
CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex);
minfo->SetModelName(name);
minfo->field_34 = someFloat;
minfo->drawDist = drawDist;
int instId = CModelInfo::GetMloInstanceStore().allocPtr;
minfo->firstInstance = instId;
minfo->lastInstance = instId;
@ -1462,7 +1463,7 @@ CFileLoader::Load2dEffect(const char *line)
&probability);
effect->attractor.type = flags;
#ifdef FIX_BUGS
effect->attractor.probability = clamp(probability, 0, 255);
effect->attractor.probability = Clamp(probability, 0, 255);
#else
effect->attractor.probability = probability;
#endif

View File

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

View File

@ -142,8 +142,12 @@ int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW;
#endif
#ifdef GAMEPAD_MENU
#ifdef __SWITCH__
int8 CMenuManager::m_PrefsControllerType = CONTROLLER_NINTENDO_SWITCH;
#else
int8 CMenuManager::m_PrefsControllerType = CONTROLLER_XBOXONE;
#endif
#endif
int32 CMenuManager::OS_Language = LANG_ENGLISH;
int8 CMenuManager::m_PrefsUseVibration;
@ -336,6 +340,7 @@ const char* MenuFilenames[][2] = {
CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); \
CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
// value must be between 0.0-1.0
#define ProcessSlider(value, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
do { \
lastActiveBarX = DisplaySlider(MENU_X_RIGHT_ALIGNED(MENUSLIDER_X + columnWidth), MENU_Y(bitAboveNextItemY), MENU_Y(smallestSliderBar), MENU_Y(usableLineHeight), MENU_X(MENUSLIDER_UNK), value); \
@ -446,7 +451,7 @@ CMenuManager::ThingsToDoBeforeGoingBack()
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
#ifdef CUSTOM_FRONTEND_OPTIONS
} else if (ScreenHasOption(m_nCurrScreen, "FEA_3DH")) {
} else if (ScreenHasOption(m_nCurrScreen, "FEA_RSS")) {
#else
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
#endif
@ -489,7 +494,7 @@ CMenuManager::ThingsToDoBeforeGoingBack()
option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue)
option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
option.m_CFOSelect->displayedValue = *(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
if (aScreens[m_nCurrScreen].returnPrevPageFunc) {
aScreens[m_nCurrScreen].returnPrevPageFunc();
@ -898,36 +903,50 @@ CMenuManager::CheckSliderMovement(int value)
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
m_PrefsBrightness += value * (512/16);
m_PrefsBrightness = clamp(m_PrefsBrightness, 0, 511);
m_PrefsBrightness += value * (512/MENUSLIDER_LOGICAL_BARS);
m_PrefsBrightness = Clamp(m_PrefsBrightness, 0, 511);
break;
case MENUACTION_DRAWDIST:
if(value > 0)
m_PrefsLOD += ((1.8f - 0.8f) / 16.0f);
m_PrefsLOD += ((1.8f - 0.8f) / MENUSLIDER_LOGICAL_BARS);
else
m_PrefsLOD -= ((1.8f - 0.8f) / 16.0f);
m_PrefsLOD = clamp(m_PrefsLOD, 0.8f, 1.8f);
m_PrefsLOD -= ((1.8f - 0.8f) / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = Clamp(m_PrefsLOD, 0.8f, 1.8f);
CRenderer::ms_lodDistScale = m_PrefsLOD;
break;
case MENUACTION_MUSICVOLUME:
m_PrefsMusicVolume += value * (128/16);
m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127);
m_PrefsMusicVolume += value * (128/MENUSLIDER_LOGICAL_BARS);
m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 127);
DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
break;
case MENUACTION_SFXVOLUME:
m_PrefsSfxVolume += value * (128/16);
m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 127);
m_PrefsSfxVolume += value * (128/MENUSLIDER_LOGICAL_BARS);
m_PrefsSfxVolume = Clamp(m_PrefsSfxVolume, 0, 127);
DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
break;
case MENUACTION_MOUSESENS:
TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // ???
TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
TheCamera.m_fMouseAccelHorzntl += value * 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
#else
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
#endif
break;
#ifdef CUSTOM_FRONTEND_OPTIONS
case MENUACTION_CFO_SLIDER:
{
CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
float oldValue = *(float*)option.m_CFOSlider->value;
*(float*)option.m_CFOSlider->value += value * ((option.m_CFOSlider->max - option.m_CFOSlider->min) / MENUSLIDER_LOGICAL_BARS);
*(float*)option.m_CFOSlider->value = Clamp(*(float*)option.m_CFOSlider->value, option.m_CFOSlider->min, option.m_CFOSlider->max);
if (*(float*)option.m_CFOSlider->value != oldValue && option.m_CFOSlider->changeFunc)
option.m_CFOSlider->changeFunc(oldValue, *(float*)option.m_CFOSlider->value);
break;
}
#endif
default:
return;
}
@ -950,12 +969,7 @@ CMenuManager::DisplayHelperText()
m_nHelperTextAlpha -= 2;
}
#else
static float fadeAlpha = 0.0f; // To keep it precisely
if (m_nHelperTextAlpha >= 255 && fadeAlpha < 250) fadeAlpha = m_nHelperTextAlpha;
// -2 per every 33 ms (1000.f/30.f - original frame limiter fps)
fadeAlpha -= (frameTime / 33.0f) * 2.0f;
m_nHelperTextAlpha = fadeAlpha;
m_nHelperTextAlpha -= 2 * CTimer::GetLogicalFramesPassed();
#endif
if (m_nHelperTextAlpha < 1)
ResetHelperText();
@ -1006,10 +1020,10 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
int lastActiveBarX = 0;
float curBarX = 0.0f;
float spacing = SCREEN_SCALE_X(10.0f);
for (int i = 0; i < 16; i++) {
curBarX = i * rectSize/16.0f + x;
for (int i = 0; i < MENUSLIDER_BARS; i++) {
curBarX = i * rectSize/MENUSLIDER_BARS + x;
if (i / 16.0f + 1 / 32.0f < progress) {
if (i / (float)MENUSLIDER_BARS + 1 / (MENUSLIDER_BARS * 2.f) < progress) {
color = CRGBA(SLIDERON_COLOR.r, SLIDERON_COLOR.g, SLIDERON_COLOR.b, FadeIn(255));
lastActiveBarX = curBarX;
} else
@ -1017,7 +1031,7 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
maxBarHeight = Max(mostLeftBarSize, mostRightBarSize);
float curBarFreeSpace = ((16 - i) * mostLeftBarSize + i * mostRightBarSize) / 16.0f;
float curBarFreeSpace = ((MENUSLIDER_BARS - i) * mostLeftBarSize + i * mostRightBarSize) / (float)MENUSLIDER_BARS;
float left = curBarX;
float top = y + maxBarHeight - curBarFreeSpace;
float right = spacing + curBarX;
@ -1600,10 +1614,10 @@ CMenuManager::Draw()
// If that was previously selected option, restore it to default value.
// if (m_nCurrOption != lastSelectedOpt && lastSelectedOpt == i)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
} else {
if (option.m_CFOSelect->displayedValue != *option.m_CFO->value)
if (option.m_CFOSelect->displayedValue != *(int8*)option.m_CFO->value)
SetHelperText(1); // Enter to apply
else if (m_nHelperTextMsgId == 1)
ResetHelperText(); // Applied
@ -1611,8 +1625,8 @@ CMenuManager::Draw()
}
// To whom manipulate option.m_CFO->value of select options externally (like RestoreDef functions)
if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
if (*(int8*)option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *(int8*)option.m_CFO->value;
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
option.m_CFOSelect->displayedValue = 0;
@ -1804,6 +1818,12 @@ CMenuManager::Draw()
case MENUACTION_MOUSESENS:
ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH);
break;
#ifdef CUSTOM_FRONTEND_OPTIONS
case MENUACTION_CFO_SLIDER:
CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i];
ProcessSlider((*(float*)option.m_CFOSlider->value - option.m_CFOSlider->min) / (option.m_CFOSlider->max - option.m_CFOSlider->min), HOVEROPTION_INCREASE_CFO_SLIDER, HOVEROPTION_DECREASE_CFO_SLIDER, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
break;
#endif
}
// Needed after the bug fix in Font.cpp
@ -2686,11 +2706,7 @@ CMenuManager::DrawFrontEndNormal()
static float fadeAlpha = 0.0f;
if (m_nMenuFadeAlpha < 255) {
if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
fadeAlpha += (frameTime) * 20.f / 33.f;
m_nMenuFadeAlpha = fadeAlpha;
m_nMenuFadeAlpha += 20 * CTimer::GetLogicalFramesPassed();
} else {
// TODO: what is this? waiting mouse?
if(field_518 == 4){
@ -2950,12 +2966,7 @@ CMenuManager::DrawFrontEndNormal()
// Famous transparent menu bug
#ifdef FIX_BUGS
static float fadeAlpha = 0.0f;
if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
// +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
fadeAlpha += (frameTime) * 20.f / 33.f;
m_nMenuFadeAlpha = fadeAlpha;
m_nMenuFadeAlpha += 20 * CTimer::GetLogicalFramesPassed();
#else
static uint32 LastFade = 0;
@ -2986,40 +2997,11 @@ CMenuManager::DrawFrontEndNormal()
#ifdef RED_DELETE_BACKGROUND
if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT || m_nCurrScreen == MENUPAGE_DELETE_SLOT_CONFIRM) {
CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(18.0f), MENU_Y(8.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), MENU_Y(8.0f),
SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f),
CRGBA(150, 0, 0, 140));
CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f),
SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f),
CRGBA(150, 0, 0, 140));
CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f),
SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f),
CRGBA(150, 0, 0, 140));
CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f),
SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f),
CRGBA(150, 0, 0, 140));
CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f),
SCREEN_STRETCH_X(18.0f), SCREEN_SCALE_Y(438.0f),
SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_Y(438.0f),
CRGBA(150, 0, 0, 140));
// yellow bar
CSprite2d::DrawRect(CRect(MENU_X(13.0f), SCREEN_STRETCH_FROM_BOTTOM(96.0f),
SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)),
CRGBA(235, 170, 50, 255));
CSprite2d::Draw2DPolygon(0.0f, 0.0f,
SCREEN_WIDTH, 0.0f,
0.0f, SCREEN_HEIGHT,
SCREEN_WIDTH, SCREEN_HEIGHT,
CRGBA(150, 0, 0, 80));
}
#endif
@ -3542,9 +3524,15 @@ CMenuManager::InitialiseChangedLanguageSettings()
{
if (m_bFrontEnd_ReloadObrTxtGxt) {
m_bFrontEnd_ReloadObrTxtGxt = false;
#ifdef FIX_BUGS
if (gGameState > GS_INIT_ONCE)
#endif
CTimer::Stop();
TheText.Unload();
TheText.Load();
#ifdef FIX_BUGS
if (gGameState > GS_INIT_ONCE)
#endif
CTimer::Update();
CGame::frenchGame = false;
CGame::germanGame = false;
@ -3661,7 +3649,9 @@ CMenuManager::LoadAllTextures()
#ifdef MENU_MAP
static bool menuOptionAdded = false;
for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) {
if (!menuOptionAdded && RwTextureRead(MapFilenames[i][0], MapFilenames[i][1])) {
RwTexture *firstTile;
if (!menuOptionAdded && (firstTile = RwTextureRead(MapFilenames[i][0], MapFilenames[i][1]))) {
RwTextureDestroy(firstTile);
FrontendOptionSetCursor(MENUPAGE_PAUSE_MENU, 2, false);
FrontendOptionAddBuiltinAction("FEG_MAP", MENUACTION_CHANGEMENU, MENUPAGE_MAP, SAVESLOT_NONE);
menuOptionAdded = true;
@ -3688,6 +3678,7 @@ const char* controllerTypesPaths[] = {
"MODELS/FRONTEND_DS4.TXD",
"MODELS/FRONTEND_X360.TXD",
"MODELS/FRONTEND_XONE.TXD",
"MODELS/FRONTEND_NSW.TXD",
};
void
@ -3700,6 +3691,9 @@ CMenuManager::LoadController(int8 type)
case CONTROLLER_DUALSHOCK4:
CFont::LoadButtons("MODELS/PS3BTNS.TXD");
break;
case CONTROLLER_NINTENDO_SWITCH:
CFont::LoadButtons("MODELS/NSWBTNS.TXD");
break;
default:
CFont::LoadButtons("MODELS/X360BTNS.TXD");
break;
@ -3826,9 +3820,6 @@ CMenuManager::LoadSettings()
if (LoadINISettings()) {
LoadINIControllerSettings();
}
// if no re3.ini, create it, or update it with new values
SaveINISettings();
SaveINIControllerSettings();
#endif
m_PrefsVsync = m_PrefsVsyncDisp;
@ -4189,14 +4180,14 @@ CMenuManager::Process(void)
if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) {
#ifdef MISSION_REPLAY
if (doingMissionRetry) {
RetryMission(2, 0);
RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
m_nCurrSaveSlot = SLOT_COUNT;
doingMissionRetry = false;
}
#endif
if (CheckSlotDataValid(m_nCurrSaveSlot)) {
#ifdef USE_DEBUG_SCRIPT_LOADER
scriptToLoad = 0;
CTheScripts::ScriptToLoad = 0;
#endif
#ifdef PC_PLAYER_CONTROLS
TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
@ -4325,29 +4316,16 @@ CMenuManager::ProcessButtonPresses(void)
#ifdef USE_DEBUG_SCRIPT_LOADER
if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_NEW_GAME_RELOAD) {
#ifdef RW_GL3
if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
scriptToLoad = 1;
if (CPad::GetPad(0)->GetChar('R')) {
CTheScripts::ScriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_D) == GLFW_PRESS) {
scriptToLoad = 2;
if (CPad::GetPad(0)->GetChar('D')) {
CTheScripts::ScriptToLoad = 2;
DoSettingsBeforeStartingAGame();
return;
}
#elif defined _WIN32
if (GetAsyncKeyState('R') & 0x8000) {
scriptToLoad = 1;
DoSettingsBeforeStartingAGame();
return;
}
if (GetAsyncKeyState('D') & 0x8000) {
scriptToLoad = 2;
DoSettingsBeforeStartingAGame();
return;
}
#endif
}
#endif
@ -4422,7 +4400,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = m_nHoverOption - HOVEROPTION_RADIO_0;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
} else if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM
&& aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action != MENUACTION_RESUME) {
@ -4436,7 +4414,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = HEAD_RADIO;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_1:
@ -4444,7 +4422,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = DOUBLE_CLEF;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_2:
@ -4452,7 +4430,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = JAH_RADIO;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_3:
@ -4460,7 +4438,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = RISE_FM;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_4:
@ -4468,7 +4446,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = LIPS_106;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_5:
@ -4476,7 +4454,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = GAME_FM;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_6:
@ -4484,7 +4462,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = MSX_FM;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_7:
@ -4492,7 +4470,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = FLASHBACK;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_8:
@ -4500,7 +4478,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = CHATTERBOX;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RADIO_9:
@ -4508,7 +4486,7 @@ CMenuManager::ProcessButtonPresses(void)
m_PrefsRadioStation = USERTRACK;
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
case HOVEROPTION_RANDOM_ITEM:
@ -4525,7 +4503,7 @@ CMenuManager::ProcessButtonPresses(void)
#ifndef TIDY_UP_PBP
switch (m_nHoverOption) {
case HOVEROPTION_INCREASE_BRIGHTNESS:
m_PrefsBrightness = m_PrefsBrightness + 32;
m_PrefsBrightness = m_PrefsBrightness + (512 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsBrightness < 0) {
m_PrefsBrightness = 0;
}
@ -4535,7 +4513,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_DECREASE_BRIGHTNESS:
m_PrefsBrightness = m_PrefsBrightness - 32;
m_PrefsBrightness = m_PrefsBrightness - (512 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsBrightness < 0) {
m_PrefsBrightness = 0;
}
@ -4545,25 +4523,25 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_INCREASE_DRAWDIST:
m_PrefsLOD = m_PrefsLOD + (1.0f / 16);
m_PrefsLOD = m_PrefsLOD + (1.0f / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = min(1.8f, m_PrefsLOD);
CRenderer::ms_lodDistScale = m_PrefsLOD;
SaveSettings();
break;
case HOVEROPTION_DECREASE_DRAWDIST:
m_PrefsLOD = m_PrefsLOD - (1.0f / 16);
m_PrefsLOD = m_PrefsLOD - (1.0f / MENUSLIDER_LOGICAL_BARS);
m_PrefsLOD = max(0.8f, m_PrefsLOD);
CRenderer::ms_lodDistScale = m_PrefsLOD;
SaveSettings();
break;
case HOVEROPTION_INCREASE_MUSICVOLUME:
m_PrefsMusicVolume = m_PrefsMusicVolume + 8;
m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127);
m_PrefsMusicVolume = m_PrefsMusicVolume + (128 / MENUSLIDER_LOGICAL_BARS);
m_PrefsMusicVolume = Clamp(m_PrefsMusicVolume, 0, 127);
DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
SaveSettings();
break;
case HOVEROPTION_DECREASE_MUSICVOLUME:
m_PrefsMusicVolume = m_PrefsMusicVolume - 8;
m_PrefsMusicVolume = m_PrefsMusicVolume - (128 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsMusicVolume < 0) {
m_PrefsMusicVolume = 0;
}
@ -4574,7 +4552,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_INCREASE_SFXVOLUME:
m_PrefsSFXVolume = m_PrefsSFXVolume + 8;
m_PrefsSFXVolume = m_PrefsSFXVolume + (128 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsSFXVolume < 0) {
m_PrefsSFXVolume = 0;
}
@ -4585,7 +4563,7 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_DECREASE_SFXVOLUME:
m_PrefsSFXVolume = m_PrefsSFXVolume - 8;
m_PrefsSFXVolume = m_PrefsSFXVolume - (128 / MENUSLIDER_LOGICAL_BARS);
if (m_PrefsSFXVolume < 0) {
m_PrefsSFXVolume = 0;
}
@ -4596,8 +4574,8 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_INCREASE_MOUSESENS:
TheCamera.m_fMouseAccelHorzntl += (1.0f / 3000);
TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
TheCamera.m_fMouseAccelHorzntl += 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
#else
@ -4606,8 +4584,8 @@ CMenuManager::ProcessButtonPresses(void)
SaveSettings();
break;
case HOVEROPTION_DECREASE_MOUSESENS:
TheCamera.m_fMouseAccelHorzntl -= (1.0f / 3000);
TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
TheCamera.m_fMouseAccelHorzntl -= 1.0f/200.0f/15.0f; // probably because diving it to 15 instead of 16(MENUSLIDER_LOGICAL_BARS) had more accurate steps
TheCamera.m_fMouseAccelHorzntl = Clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
#ifdef FIX_BUGS
TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
#else
@ -4623,6 +4601,9 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_INCREASE_MUSICVOLUME:
case HOVEROPTION_INCREASE_SFXVOLUME:
case HOVEROPTION_INCREASE_MOUSESENS:
#ifdef CUSTOM_FRONTEND_OPTIONS
case HOVEROPTION_INCREASE_CFO_SLIDER:
#endif
CheckSliderMovement(1);
break;
case HOVEROPTION_DECREASE_BRIGHTNESS:
@ -4630,6 +4611,9 @@ CMenuManager::ProcessButtonPresses(void)
case HOVEROPTION_DECREASE_MUSICVOLUME:
case HOVEROPTION_DECREASE_SFXVOLUME:
case HOVEROPTION_DECREASE_MOUSESENS:
#ifdef CUSTOM_FRONTEND_OPTIONS
case HOVEROPTION_DECREASE_CFO_SLIDER:
#endif
CheckSliderMovement(-1);
break;
}
@ -4660,7 +4644,11 @@ CMenuManager::ProcessButtonPresses(void)
|| CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp()
|| CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
if (option == MENUACTION_BRIGHTNESS || option == MENUACTION_DRAWDIST)
if (option == MENUACTION_BRIGHTNESS || option == MENUACTION_DRAWDIST
#ifdef CUSTOM_FRONTEND_OPTIONS
|| option == MENUACTION_CFO_SLIDER
#endif
)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
else if (option == MENUACTION_SFXVOLUME)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0);
@ -4731,7 +4719,7 @@ CMenuManager::ProcessButtonPresses(void)
curBottomBarOption = hoveredBottomBarOption;
ChangeScreen(bbNames[curBottomBarOption].screenId, 0, true, false);
if (bbNames[curBottomBarOption].screenId == MENUPAGE_SOUND_SETTINGS)
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
return;
} else if (bottomBarActive) {
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
@ -4739,7 +4727,7 @@ CMenuManager::ProcessButtonPresses(void)
bottomBarActive = false;
if (bbNames[curBottomBarOption].screenId == MENUPAGE_SOUND_SETTINGS)
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
return;
} else if (CPad::GetPad(0)->GetLeftJustDown() || CPad::GetPad(0)->GetAnaloguePadLeft() || CPad::GetPad(0)->GetDPadLeftJustDown()
@ -4823,7 +4811,12 @@ CMenuManager::ProcessButtonPresses(void)
} else if (option != MENUACTION_CHANGEMENU && option != MENUACTION_BRIGHTNESS && option != MENUACTION_DRAWDIST
&& option != MENUACTION_MUSICVOLUME && option != MENUACTION_SFXVOLUME
&& option != MENUACTION_CHECKSAVE && option != MENUACTION_UNK24
&& option != MENUACTION_MOUSESENS && option != MENUACTION_SCREENRES) {
&& option != MENUACTION_MOUSESENS && option != MENUACTION_SCREENRES
#ifdef CUSTOM_FRONTEND_OPTIONS
&& option != MENUACTION_CFO_SLIDER
#endif
)
{
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
}
@ -4890,7 +4883,7 @@ CMenuManager::ProcessButtonPresses(void)
}
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
#endif
break;
@ -5100,7 +5093,7 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.SetMusicMasterVolume(102);
DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
SaveSettings();
} else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
m_PrefsFrameLimiter = true;
@ -5186,7 +5179,7 @@ CMenuManager::ProcessButtonPresses(void)
break;
case MENUACTION_LOADRADIO:
ChangeScreen(MENUPAGE_SOUND_SETTINGS, 0, true, true);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
break;
#ifdef MISSION_REPLAY
@ -5198,7 +5191,7 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_UNK114:
doingMissionRetry = false;
RequestFrontEndShutDown();
RetryMission(2, 0);
RetryMission(MISSION_RETRY_TYPE_BEGIN_RESTARTING);
return;
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS
@ -5214,9 +5207,9 @@ CMenuManager::ProcessButtonPresses(void)
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
option.m_CFOSelect->displayedValue = 0;
}
int8 oldValue = *option.m_CFO->value;
int8 oldValue = *(int8*)option.m_CFO->value;
*option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
*(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
// if (option.m_CFOSelect->save)
@ -5381,7 +5374,7 @@ CMenuManager::ProcessButtonPresses(void)
}
SaveSettings();
DMAudio.SetRadioInCar(m_PrefsRadioStation);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, TRUE);
OutputDebugString("FRONTEND RADIO STATION CHANGED");
break;
#ifdef ASPECT_RATIO_SCALE
@ -5423,14 +5416,14 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_AUDIOHW:
if (m_nPrefsAudio3DProviderIndex != -1) {
m_nPrefsAudio3DProviderIndex += changeValueBy;
m_nPrefsAudio3DProviderIndex = clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1);
m_nPrefsAudio3DProviderIndex = Clamp(m_nPrefsAudio3DProviderIndex, 0, DMAudio.GetNum3DProvidersAvailable() - 1);
}
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_NAVIGATION, 0);
break;
case MENUACTION_SPEAKERCONF:
if (m_nPrefsAudio3DProviderIndex != -1) {
m_PrefsSpeakers -= changeValueBy;
m_PrefsSpeakers = clamp(m_PrefsSpeakers, 0, 2);
m_PrefsSpeakers = Clamp(m_PrefsSpeakers, 0, 2);
DMAudio.SetSpeakerConfig(m_PrefsSpeakers);
SaveSettings();
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
@ -5460,9 +5453,9 @@ CMenuManager::ProcessButtonPresses(void)
option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1;
}
if (!option.m_CFOSelect->onlyApplyOnEnter) {
int8 oldValue = *option.m_CFO->value;
int8 oldValue = *(int8*)option.m_CFO->value;
*option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
*(int8*)option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
// if (option.m_CFOSelect->save)
@ -5940,6 +5933,18 @@ CMenuManager::PrintController(void)
TEXT_L2R2_Y += 5.0f;
TEXT_SELECT_X += 3.0f;
break;
case CONTROLLER_NINTENDO_SWITCH:
TEXT_L1_Y += 5.0f;
TEXT_L1_Y_VEH = TEXT_L1_Y;
TEXT_R1_Y += 5.0f;
TEXT_TRIANGLE_Y += 3.0f;
TEXT_CIRCLE_Y += 3.0f;
TEXT_CROSS_Y += 3.0f;
TEXT_LSTICK_Y -= 23.0f;
TEXT_DPAD_Y += 25.0;
TEXT_RSTICK_Y += 1.0f;
TEXT_R3_Y += 1.0f;
break;
};
if (m_DisplayControllerOnFoot) {

View File

@ -25,6 +25,9 @@
#define MENUSLIDER_X 256.0f
#define MENUSLIDER_UNK 256.0f
#define MENUSLIDER_BARS 16
#define MENUSLIDER_LOGICAL_BARS MENUSLIDER_BARS
#define BIGTEXT_X_SCALE 0.75f // For FONT_HEADING
#define BIGTEXT_Y_SCALE 0.9f
#define MEDIUMTEXT_X_SCALE 0.55f // For FONT_HEADING
@ -256,6 +259,7 @@ enum eMenuScreen
enum eMenuAction
{
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_CFO_SLIDER = -3,
MENUACTION_CFO_SELECT = -2,
MENUACTION_CFO_DYNAMIC = -1,
#endif
@ -424,6 +428,10 @@ enum eCheckHover
HOVEROPTION_DECREASE_SFXVOLUME,
HOVEROPTION_INCREASE_MOUSESENS,
HOVEROPTION_DECREASE_MOUSESENS,
#ifdef CUSTOM_FRONTEND_OPTIONS
HOVEROPTION_INCREASE_CFO_SLIDER,
HOVEROPTION_DECREASE_CFO_SLIDER,
#endif
HOVEROPTION_NOT_HOVERING,
};
@ -493,7 +501,7 @@ struct CCustomScreenLayout {
struct CCFO
{
int8 *value;
void *value;
const char *saveCat;
const char *save;
};
@ -524,6 +532,24 @@ struct CCFOSelect : CCFO
}
};
// Value is float in here
struct CCFOSlider : CCFO
{
ChangeFuncFloat changeFunc;
float min;
float max;
CCFOSlider() {};
CCFOSlider(float* value, const char* saveCat, const char* save, float min, float max, ChangeFuncFloat changeFunc = nil){
this->value = value;
this->saveCat = saveCat;
this->save = save;
this->changeFunc = changeFunc;
this->min = min;
this->max = max;
}
};
struct CCFODynamic : CCFO
{
DrawFunc drawFunc;
@ -555,6 +581,7 @@ struct CMenuScreenCustom
CCFO *m_CFO; // for initializing
CCFOSelect *m_CFOSelect;
CCFODynamic *m_CFODynamic;
CCFOSlider *m_CFOSlider;
};
int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen
@ -733,6 +760,7 @@ public:
CONTROLLER_DUALSHOCK4,
CONTROLLER_XBOX360,
CONTROLLER_XBOXONE,
CONTROLLER_NINTENDO_SWITCH,
};
static int8 m_PrefsControllerType;

View File

@ -779,7 +779,7 @@ TriggerAudio_RadioStation(CMenuMultiChoicePicturedTriggered *widget)
if ( CMenuManager::m_PrefsRadioStation != widget->GetMenuSelection() )
{
CMenuManager::m_PrefsRadioStation = widget->GetMenuSelection();
DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, 1);
DMAudio.PlayFrontEndTrack(CMenuManager::m_PrefsRadioStation, TRUE);
DMAudio.SetRadioInCar(CMenuManager::m_PrefsRadioStation);
}
}
@ -792,12 +792,12 @@ TriggerAudio_StereoMono(CMenuMultiChoiceTriggered *widget)
{
if (widget->GetMenuSelection() == 1)
{
DMAudio.SetMonoMode(true);
DMAudio.SetMonoMode(TRUE);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MONO, 0);
}
else
{
DMAudio.SetMonoMode(false);
DMAudio.SetMonoMode(FALSE);
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_STEREO, 0);
}
}

View File

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

View File

@ -245,10 +245,16 @@ CGame::InitialiseRenderWare(void)
#ifdef LIBRW
#ifdef PS2_MATFX
rw::MatFX::modulateEnvMap = true;
rw::MatFX::envMapApplyLight = true;
rw::MatFX::envMapUseMatColor = true;
rw::MatFX::envMapFlipU = true;
#else
rw::MatFX::modulateEnvMap = false;
rw::MatFX::envMapApplyLight = false;
rw::MatFX::envMapUseMatColor = false;
rw::MatFX::envMapFlipU = false;
#endif
rw::RGBA envcol = { 128, 128, 128, 255 };
rw::MatFX::envMapColor = envcol;
#else
#ifdef PS2_MATFX
ReplaceMatFxCallback();
@ -403,7 +409,11 @@ bool CGame::Initialise(const char* datFile)
#endif
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#ifdef PED_CAR_DENSITY_SLIDERS
// Load density values from gta3.ini only if our re3.ini have them 1.f
if (CIniFile::PedNumberMultiplier == 1.f && CIniFile::CarNumberMultiplier == 1.f)
#endif
CIniFile::LoadIniFile();
#endif
currLevel = LEVEL_INDUSTRIAL;

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