summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFire-Head <Fire-Head@users.noreply.github.com>2020-04-23 10:24:03 +0200
committerFire-Head <Fire-Head@users.noreply.github.com>2020-04-23 10:24:03 +0200
commit75acd781909378ba0395b0c52acee464c8221e72 (patch)
tree7d23d2b6d59190f873aba4d176f3e076fd290b35
parentMerge pull request #483 from Fire-Head/master (diff)
downloadre3-75acd781909378ba0395b0c52acee464c8221e72.tar
re3-75acd781909378ba0395b0c52acee464c8221e72.tar.gz
re3-75acd781909378ba0395b0c52acee464c8221e72.tar.bz2
re3-75acd781909378ba0395b0c52acee464c8221e72.tar.lz
re3-75acd781909378ba0395b0c52acee464c8221e72.tar.xz
re3-75acd781909378ba0395b0c52acee464c8221e72.tar.zst
re3-75acd781909378ba0395b0c52acee464c8221e72.zip
-rw-r--r--gamefiles/TEXT/JAPANESE.gxt (renamed from gamefiles/JAPANESE.gxt)bin122022 -> 122022 bytes
-rw-r--r--gamefiles/TEXT/american.gxt (renamed from gamefiles/american.gxt)bin218578 -> 218578 bytes
-rw-r--r--gamefiles/TEXT/french.gxt (renamed from gamefiles/french.gxt)bin244494 -> 244494 bytes
-rw-r--r--gamefiles/TEXT/german.gxt (renamed from gamefiles/german.gxt)bin240448 -> 240448 bytes
-rw-r--r--gamefiles/TEXT/italian.gxt (renamed from gamefiles/italian.gxt)bin239912 -> 239912 bytes
-rw-r--r--gamefiles/TEXT/polish.gxt (renamed from gamefiles/polish.gxt)bin239930 -> 239930 bytes
-rw-r--r--gamefiles/TEXT/russian.gxt (renamed from gamefiles/russian.gxt)bin220398 -> 220398 bytes
-rw-r--r--gamefiles/TEXT/spanish.gxt (renamed from gamefiles/spanish.gxt)bin246088 -> 246088 bytes
-rw-r--r--gamefiles/data/PARTICLE.CFG363
-rw-r--r--gamefiles/data/main_d.scm (renamed from gamefiles/main_d.scm)bin620154 -> 620154 bytes
-rw-r--r--gamefiles/data/main_freeroam.scm (renamed from gamefiles/main_freeroam.scm)bin1618 -> 1618 bytes
-rw-r--r--gamefiles/models/fonts_j.txd (renamed from gamefiles/fonts_j.txd)bin1052072 -> 1052072 bytes
-rw-r--r--gamefiles/models/fonts_p.txd (renamed from gamefiles/fonts_p.txd)bin1379752 -> 1379752 bytes
-rw-r--r--gamefiles/models/fonts_r.txd (renamed from gamefiles/fonts_r.txd)bin1379752 -> 1379752 bytes
-rw-r--r--gamefiles/models/menu.txd (renamed from gamefiles/menu.txd)bin10244648 -> 10244648 bytes
-rw-r--r--src/audio/AudioManager.cpp8
-rw-r--r--src/audio/AudioManager.h2
-rw-r--r--src/audio/miles/sampman_mss.cpp2257
-rw-r--r--src/audio/miles/sampman_mss.h339
-rw-r--r--src/audio/openal/samp_oal.cpp1404
-rw-r--r--src/audio/openal/samp_oal.h340
-rw-r--r--src/audio/sampman.cpp2262
-rw-r--r--src/audio/sampman.h342
-rw-r--r--src/core/config.h5
-rw-r--r--src/core/re3.cpp1
-rw-r--r--src/objects/ParticleObject.cpp148
-rw-r--r--src/peds/Ped.cpp113
-rw-r--r--src/render/Particle.cpp42
-rw-r--r--src/render/Particle.h4
-rw-r--r--src/render/ParticleMgr.cpp3
-rw-r--r--src/render/ParticleMgr.h4
-rw-r--r--src/vehicles/Automobile.cpp86
-rw-r--r--src/vehicles/Boat.cpp55
33 files changed, 5139 insertions, 2639 deletions
diff --git a/gamefiles/JAPANESE.gxt b/gamefiles/TEXT/JAPANESE.gxt
index d4b54383..d4b54383 100644
--- a/gamefiles/JAPANESE.gxt
+++ b/gamefiles/TEXT/JAPANESE.gxt
Binary files differ
diff --git a/gamefiles/american.gxt b/gamefiles/TEXT/american.gxt
index eb56fa61..eb56fa61 100644
--- a/gamefiles/american.gxt
+++ b/gamefiles/TEXT/american.gxt
Binary files differ
diff --git a/gamefiles/french.gxt b/gamefiles/TEXT/french.gxt
index cb2874f9..cb2874f9 100644
--- a/gamefiles/french.gxt
+++ b/gamefiles/TEXT/french.gxt
Binary files differ
diff --git a/gamefiles/german.gxt b/gamefiles/TEXT/german.gxt
index d5a986cf..d5a986cf 100644
--- a/gamefiles/german.gxt
+++ b/gamefiles/TEXT/german.gxt
Binary files differ
diff --git a/gamefiles/italian.gxt b/gamefiles/TEXT/italian.gxt
index 95e2dd36..95e2dd36 100644
--- a/gamefiles/italian.gxt
+++ b/gamefiles/TEXT/italian.gxt
Binary files differ
diff --git a/gamefiles/polish.gxt b/gamefiles/TEXT/polish.gxt
index 1782ef87..1782ef87 100644
--- a/gamefiles/polish.gxt
+++ b/gamefiles/TEXT/polish.gxt
Binary files differ
diff --git a/gamefiles/russian.gxt b/gamefiles/TEXT/russian.gxt
index f403c5c4..f403c5c4 100644
--- a/gamefiles/russian.gxt
+++ b/gamefiles/TEXT/russian.gxt
Binary files differ
diff --git a/gamefiles/spanish.gxt b/gamefiles/TEXT/spanish.gxt
index 0fdccce3..0fdccce3 100644
--- a/gamefiles/spanish.gxt
+++ b/gamefiles/TEXT/spanish.gxt
Binary files differ
diff --git a/gamefiles/data/PARTICLE.CFG b/gamefiles/data/PARTICLE.CFG
new file mode 100644
index 00000000..8bb6d30b
--- /dev/null
+++ b/gamefiles/data/PARTICLE.CFG
@@ -0,0 +1,363 @@
+; Author: Alexander Roger
+; Date: 21/12/2000
+;
+; Author: Andrzej Madajczyk
+; Date: 26/02/2001
+; 14/03/2001 - Alpha (opacity) support added;
+; 10/05/2001 - Drag/Friction Decceleration changed to constants;
+; 28/08/2001 - Initial Color Variation added;
+;
+;
+;
+;
+; Note! Last line of the file MUST BE ";the end\n", otherwise you'll get parsing error(s) of the file;
+;
+;
+;
+;Particle Systems Configuration Data:: Format
+;
+;
+;A: Particle Type Name (max 20 chars)
+;
+;B/C/D: Render Colouring (r,g,b) (0-255)
+;
+;CV: Initial Color Variation (for r,g,b only, in %) (0-100);
+; (i.e. Color=(100,100,100) and CV=20, then v=random(-20,20), real_color=(100+v, 100+v, 100+v));
+;
+;
+;
+;B2/C2/D2: Fade Destination Color (r,g,b) (0-255)
+;
+;FT: Color Fade Time for (B,C,D)->(B2,C2,D2), (0 for none);
+;
+;
+;
+;
+;E: Default Initial Radius (float)
+;F: Expansion Rate (float)
+;
+;
+; Color "Fade-to-Black" options:
+;G: Initial Intensity (0-255)
+;H: Fade Time (time between fade steps in frames)
+;I: Fade Amount (-255 to 255) can get brighter or dimmer
+;
+; "Fade Alpha" options:
+;GA: Initial Intensity (0-255)
+;HA: Fade Time (time between fade steps in frames)
+;IA: Fade Amount
+;
+; "Z Rotation" options:
+;GZA: Initial Angle (0-1023)
+;HZA: Change Time (time between steps in frames)
+;IZA: Angle Change Amount
+;
+;GZR: Initial Z Radius
+;HZR: Change Time (time between steps in frames)
+;IZR: Z Radius Change Amount
+;
+;
+;J: Animation Speed (0=no animation)(time between steps msec)
+;K: Start Animation Frame ( 0 -> )
+;L: Final Animation Frame ( H -> )
+;
+;
+;M: Rotation Speed (0=None,i-deg/frame)
+;N: Gravitational Acceleration (0=none, float)
+;O: Drag/Friction Decceleration (int: 0=none, 50=0.50, 80=0.80, 90=0.90, 95=0.95, 96=0.96, 99=0.99)
+;
+;P: Default Life-Span of Particle (msec)
+;
+;Q: Position Random Error [position += (+/-)rand(a)]
+;R: Velocity Random Error [velocity += (+/-)rand(b)]
+;S: Expansion Rate Error [exp_rate += (+)rand(c)]
+;T: Rotation Rate Error [rot_speed = (+/-)rand(d)]
+;U: Life-Span Error Shape [shape distribution, e=0->all at default, e->Inf then shape->0] (max=255!!)
+;V: Trail Length Multiplier [length *= (float) multiplier] (only used if trail flag active)
+;
+;CR:Particle Create Range (in meters: 0=no check); if particles are created enough far away from camera, they are deleted (not added to particle system);
+;
+;
+;Z: Flags! Guide: 1=ZCHECK_FIRST, 2=ZCHECK_STEP, 4=DRAW_OPAQUE, 8=SCREEN_TRAIL,
+; 16=SPEED_TRAIL, 32=RAND_VERT_V, 64=CYCLE_ANIM, 128=DRAW_DARK, 256=VERT_TRAIL
+; 1024=DRAWTOP2D, 2048=CLIPOUT2D
+; 4096=ZCHECK_BUMP, 8192=ZCHECK_BUMP_FIRST
+;
+;
+;
+;default:
+;GUNFLASH 255 255 255 0 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0
+;
+;good idea for fire-smudge?
+;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0
+;
+;current:
+;GUNFLASH 255 255 255 0 1.0 0.0 255 0 32 100 0 3 0 0.0 1.0 400 0.0 0.0 0.0 0 0 1.0 0
+;
+;
+;SPARK_SMALL 255 255 128 0 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.5 40
+;
+;
+;
+;
+;
+;
+;
+; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
+;
+SPARK 255 128 64 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 300 0.0 0.07 0.0 0 0 1.0 20.0 48
+SPARK_SMALL 255 255 128 0 0 0 0 0 0.005 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 500 0.0 0.05 0.0 0 0 0.6 20.0 40
+;
+WHEEL_DIRT 8 24 8 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 30.0 4
+;
+;
+;WHEEL_WATER 24 24 24 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.002 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 0
+WHEEL_WATER 24 24 32 0 0 0 0 0 0.05 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.004 1 1000 0.15 0.015 0.0 0 0 1.0 20.0 1
+;
+;
+BLOOD 128 128 128 0 0 0 0 0 0.02 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.03 1 2000 0.3 0.05 0.0 0 0 1.0 50.0 5
+BLOOD_SMALL 255 32 32 0 0 0 0 0 0.007 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.05 0.05 0.0 0 0 1.0 50.0 53
+;BLOOD_SPLAT 128 128 128 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 200 0.3 0.0 0.0 0 0 1.0 400.0 36
+BLOOD_SPURT 255 32 32 0 0 0 0 0 0.008 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.005 1 2000 0.0 0.01 0.0 0 0 2.0 50.0 52
+DEBRIS 64 64 64 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 95 1000 0.2 0.0 0.0 0 0 1.0 50.0 4
+DEBRIS2 64 64 64 0 0 0 0 0 0.04 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 5 0.01 99 1000 0.03 0.04 0.0 0 0 1.0 50.0 38
+WATER 64 64 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 2000 0.0 0.0 0.0 0 0 1.0 100.0 0
+;
+;
+;FLAME 255 74 30 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 100 0.05 0.0 0.0 0 0 1.0 400.0 0
+;FLAME 255 74 30 0 0 255 0 400 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0
+FLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 200.0 0
+;
+;
+;
+;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.04 255 1 8 255 0 0 0 0 0 0.0 0 0.0 32 0 7 0 0.0 96 1000 0.1 0.0 0.0 0 0 1.0 400.0 0
+;
+;FIREBALL 255 74 30 0 0 0 0 0 0.1 0.05 255 0 6 255 0 0 0 0 0 0.0 0 0.0 1 0 7 0 -0.002 96 2000 0.1 0.02 0.02 3 0 1.0 200.0 0
+FIREBALL 255 74 30 0 0 0 0 0 0.1 0.02 255 0 6 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.003 96 2000 0.1 0.03 0.014 2.5 0 1.0 200.0 0
+;
+;
+;
+GUNFLASH 170 170 170 0 0 0 0 0 0.1 0.0 255 1 50 255 0 0 0 0 0 0.0 0 0.0 51 0 3 0 0.0 1 250 0.0 0.0 0.0 0 0 1.0 35.0 0
+GUNFLASH_NOANIM 128 128 128 0 0 0 0 0 0.1 0.0 255 1 128 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 25 0.0 0.0 0.0 0 0 1.0 35.0 0
+;
+GUNSMOKE 64 64 64 0 0 0 0 0 0.15 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 2 0 7 0 -0.002 95 1000 0.0 0.0 0.0 0 0 1.0 60.0 0
+GUNSMOKE2 255 255 255 0 0 0 0 0 0.05 0.02 255 0 0 255 0 8 0 0 0 0.0 0 0.0 0 0 3 4 -0.001 80 1400 0.05 0.05 0.01 3 0 1.0 60.0 4
+;
+;
+SMOKE 32 32 32 0 0 0 0 0 0.15 0.015 255 5 25 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.01 95 1000 0.05 0.05 0.01 3 0 1.0 150.0 0
+;SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 255 5 15 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 1000 0.05 0.05 0.01 3 0 1.0 400.0 0
+SMOKE_SLOWMOTION 32 32 32 0 0 0 0 0 0.15 0.015 128 5 11 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.003 95 3000 0.05 0.05 0.01 3 0 1.0 150.0 0
+;
+;
+;
+;GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.001 95 2000 0.05 0.05 0.01 3 0 1.0 400.0 0
+GARAGEPAINT_SPRAY 32 32 32 0 0 0 0 0 0.15 0.015 255 0 5 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 -0.0005 95 4000 0.05 0.05 0.01 3 0 1.0 100.0 0
+SHARD 255 255 255 0 0 0 0 0 0.03 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0
+SPLASH 64 64 128 0 0 0 0 0 0.1 0.007 255 1 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 100.0 0
+;BLOOD_SPLASH 24 64 0 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 96 300 0.0 0.0 0.0 0 0 1.0 100.0 0
+;
+;
+;CARFLAME 255 74 30 0 0 0 0 0 0.5 0.04 255 2 20 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 0.0 1 1000 0.4 0.0 0.0 0 0 1.0 400.0 64
+;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64
+;CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.001 1 2000 0.4 0.01 0.01 0 0 1.0 400.0 64
+;
+CARFLAME 255 74 30 0 0 0 0 0 0.8 -0.02 255 0 10 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 1 2000 0.02 0.01 0.01 0 0 1.0 100.0 0
+;
+;
+STEAM 64 64 64 0 0 0 0 0 0.5 0.05 255 1 16 255 0 0 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 85.0 0
+;
+;default:
+;STEAM2 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4
+STEAM2 255 255 255 0 0 0 0 0 0.5 0.015 255 0 0 192 0 1 0 0 10 0.5 1 0.02 32 0 4 0 -0.002 95 8000 0.01 0.03 0.0 0 0 1.0 85.0 4
+;
+;
+;STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 128 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 400.0 4
+STEAM_NY 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4
+STEAM_NY_SLOWMOTION 255 255 255 0 0 0 0 0 0.5 0.05 255 0 0 96 2 8 0 0 0 0.0 0 0.0 32 0 4 0 -0.0015 95 1400 0.01 0.03 0.0 0 0 1.0 85.0 4
+;
+;
+;ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 2 16 0 0 0 0.0 0 0.0 32 0 4 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 250.0 4
+ENGINE_STEAM 210 210 210 0 0 0 0 0 0.5 0.05 255 0 0 192 0 10 0 0 0 0.0 0 0.0 32 0 4 1 -0.005 95 4000 0.03 0.03 0.02 0 0 1.0 85.0 4
+;
+;
+;RAINDROP 32 32 32 0 0 0 0 0 0.6 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.025 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
+RAINDROP 64 64 64 0 0 0 0 0 0.4 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
+RAINDROP_SMALL 16 16 16 0 0 0 0 0 0.3 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 15.0 1
+RAIN_SPLASH 32 32 32 0 0 0 0 0 0.08 0.0 255 0 5 255 0 0 0 0 0 0.0 0 0.0 1 0 4 0 0.0 1 500 0.0 0.0 0.0 0 0 1.0 15.0 0
+RAIN_SPLASH_BIGGROW 128 128 128 0 0 0 0 0 0.5 0.06 255 0 2 255 0 0 0 0 0 0.0 0 0.0 2 1 4 0 0.0 1 5500 0.0 0.0 0.0 0 0 1.0 15.0 0
+RAIN_SPLASHUP 48 48 48 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 1 0 0.0 1 50 0.0 0.0 0.0 0 0 1.0 15.0 0
+;
+WATERSPRAY 64 64 64 0 0 0 0 0 0.2 0.0 255 0 25 255 0 0 0 0 0 0.0 0 0.0 3 0 2 0 0.002 1 800 0.05 0.0 0.01 0 0 1.0 20.0 0
+;
+;
+;
+;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.2 0.0 0.0 3 0 1.0 400.0 0
+;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 5 8 255 0 0 0 0 0 0.0 0 0.0 8 0 11 0 0.0 96 15000 0.8 0.0 0.0 3 0 1.0 400.0 0
+;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.2 0.0 0.0 0 0 1.0 400.0 0
+;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 1 4 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 0.0 96 7000 0.8 0.0 0.0 0 0 1.0 400.0 0
+;
+;EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 400.0 0
+;EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 1 0 11 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 400.0 0
+EXPLOSION_MEDIUM 80 80 80 0 0 0 0 0 0.6 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.2 0.0 0.0 0 0 1.0 200.0 0
+EXPLOSION_LARGE 80 80 80 0 0 0 0 0 1.1 0.04 255 0 3 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 6000 0.8 0.0 0.0 0 0 1.0 200.0 0
+EXPLOSION_MFAST 80 80 80 0 0 0 0 0 0.6 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.2 0.0 0.0 0 0 1.0 200.0 0
+EXPLOSION_LFAST 80 80 80 0 0 0 0 0 1.1 0.04 255 0 6 255 0 0 0 0 0 0.0 0 0.0 2 0 5 0 -0.001 96 3500 0.8 0.0 0.0 0 0 1.0 200.0 0
+;
+;
+;
+;
+;BOAT_SPLASH 32 64 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0
+;BOAT_THRUSTJET 24 32 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8
+;BOAT_SPLASH 16 32 32 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 2000 0.0 0.0 0.0 0 0 1.0 200.0 0
+;BOAT_THRUSTJET 8 24 24 0 0 0 0 0 0.5 0.1 255 0 0 255 0 0 0 0 0 0.0 0 0.0 250 0 4 0 0.01 50 1000 0.0 0.0 0.0 0 4 1.0 200.0 8
+;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 250.0 0
+;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.25 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.04 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4
+;CAR_SPLASH 64 64 64 0 0 0 0 0 2.0 0.35 255 0 0 200 0 8 0 0 0 0.0 0 0.0 0 0 0 0 0.05 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 4
+;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.25 255 0 0 180 0 5 0 0 0 0.0 0 0.0 2 1 3 0 0.05 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 12
+;
+;
+;CAR_SPLASH 64 64 64 0 0 0 0 0 1.0 0.15 255 0 0 180 0 2 0 0 0 0.0 0 0.0 2 0 3 0 0.02 1 2000 0.0 0.0 0.0 0 0 1.0 150.0 12
+;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.15 96 0 0 255 0 0 0 0 0 0.0 0 0.0 6 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288
+;CAR_SPLASH 48 48 64 0 0 0 0 0 1.0 0.05 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 2.0 150.0 288
+; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
+CAR_SPLASH 48 48 60 0 0 0 0 0 1.0 0.00 128 1 4 128 0 0 0 0 0 0.0 0 0.0 0 0 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 150.0 272
+;
+;
+;
+;BOAT_SPLASH 70 70 70 0 0 0 0 0 0.2 0.2 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0
+BOAT_SPLASH 64 64 64 0 0 0 0 0 0.2 0.2 255 0 2 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.01 1 1000 0.0 0.0 0.0 0 0 1.0 150.0 0
+;
+;
+;BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.8 0.1 255 0 0 120 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
+BOAT_THRUSTJET 90 90 90 0 0 0 0 0 1.4 0.06 255 0 0 96 0 1 0 0 0 0.0 0 0.0 0 1 4 0 0.01 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
+;
+;
+;BOAT_WAKE 255 255 255 0 0 0 0 0 2.0 0.2 255 0 0 128 0 1 0 0 0 0.0 0 0.0 0 0 0 0 0.03 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
+BOAT_WAKE 255 255 255 0 0 0 0 0 1.5 0.45 255 0 0 192 0 2 0 0 0 0.0 0 0.0 0 0 0 0 0.0 50 1600 0.8 0.4 0.02 0 4 1.0 150.0 4
+;
+;
+;
+;
+;
+; A B C D CV B2 C2 D2 FT E F G H I GA HA IA GZA HZA IZA GZR HZR IZR J K L M N O P Q R S T U V CR Z
+WATER_HYDRANT 64 64 64 0 0 0 0 0 0.8 0.01 255 1 16 255 1 16 0 0 0 0.0 0 0.0 0 0 2 0 0.007 99 500 0.02 0.08 0.0 0 4 1.0 85.0 16
+WATER_CANNON 64 64 128 0 0 0 0 0 0.03 0.03 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
+EXTINGUISH_STEAM 32 32 32 0 0 0 0 0 0.1 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
+;
+;
+;
+;PED_SPLASH 32 32 64 0 0 0 0 0 0.1 0.05 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
+PED_SPLASH 48 48 60 0 0 0 0 0 0.1 0.06 96 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 2 0 0.01 1 2000 0.5 0.04 0.0 0 0 1.4 50.0 256
+;
+;
+PEDFOOT_DUST 170 166 150 0 0 0 0 0 0.01 0.015 255 0 0 63 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0005 1 1000 0.0 0.0 0.0 0 0 1.0 6.0 4
+;
+HELI_DUST 17 15 9 0 0 0 0 0 0.2 0.1 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 1 1000 0.2 0.05 0.0 0 0 1.0 85.0 0
+HELI_ATTACK 255 255 128 0 0 0 0 0 0.01 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 500 0.0 0.0 0.0 0 0 0.5 85.0 10
+;
+;
+;ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 -0.005 95 2000 0.01 0.03 0.0 0 0 1.0 150.0 4
+;ENGINE_SMOKE2 8 8 8 0 0 0 0 0 1.0 0.2 128 2 4 63 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.001 1 1000 0.0 0.0 0.0 0 3 1.0 150.0 4
+ENGINE_SMOKE 16 16 16 0 0 0 0 0 0.5 0.04 255 0 0 52 0 2 10 0 80 0.0 0 0.0 0 0 5 2 -0.009 95 2000 0.11 0.03 0.01 1 0 1.0 85.0 4
+ENGINE_SMOKE2 9 9 9 80 0 0 0 0 1.0 0.06 128 0 1 140 0 5 10 0 80 0.0 0 0.0 0 0 0 2 0.002 1 1300 0.0 0.01 0.0 3 3 1.0 85.0 4
+;
+;
+CARFLAME_SMOKE 32 32 32 0 0 0 0 0 0.05 0.01 255 0 0 64 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.008 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4
+FIREBALL_SMOKE 32 32 32 0 0 0 0 0 0.05 0.03 255 0 0 128 0 2 0 0 0 0.0 0 0.0 0 0 0 0 -0.004 95 2000 0.01 0.03 0.01 0 0 1.0 85.0 4
+;
+PAINT_SMOKE 255 0 0 0 0 0 0 0 0.1 0.01 255 1 8 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 95 3000 0.0 0.005 0.0 0 0 1.0 85.0 0
+TREE_LEAVES 64 64 64 0 0 0 0 0 0.2 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 85.0 0
+;
+;
+;CARCOLLISION_DUST 224 224 224 0 0 0 0 0 0.15 0.04 255 0 0 127 1 8 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 80.0 4
+CARCOLLISION_DUST 76 76 76 0 0 0 0 0 0.10 0.02 255 0 0 160 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.0015 90 2000 0.02 0.02 0.0 0 0 1.0 30.0 4
+;
+;
+CAR_DEBRIS 32 32 32 0 0 0 0 0 0.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 50.0 4
+HELI_DEBRIS 32 32 32 0 0 0 0 0 1.5 0.0 224 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.065 90 1500 0.02 0.02 0.0 0 0 1.0 150.0 4
+;
+;
+;
+;EXHAUST_FUMES 80 80 80 0 0 0 0 0 0.03 0.03 255 0 0 122 0 4 0 0 0 0.0 0 0.0 2 0 4 0 -0.001 95 1500 0.01 0.03 0.0 0 0 1.0 50.0 4
+EXHAUST_FUMES 98 98 108 0 0 0 0 0 0.03 0.06 255 0 0 152 0 12 0 0 0 0.0 0 0.0 2 0 4 0 -0.002 96 1000 0.01 0.03 0.0 0 0 1.0 25.0 4
+;
+;
+;RUBBER 40 40 40 0 0 0 0 0 0.4 0.005 255 21 20 255 0 0 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 400.0 4
+RUBBER_SMOKE 255 255 255 0 0 0 0 0 0.4 0.005 255 0 0 127 1 8 0 0 0 0.0 0 0.0 3 0 4 0 -0.0005 1 1000 0.02 0.0 0.0 0 0 1.0 50.0 4
+;BURNINGRUBBER_SMOKE128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 192 1 6 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 4000 0.02 0.02 0.0 0 0 1.0 400.0 4
+BURNINGRUBBER_SMOKE 128 128 128 0 0 0 0 0 0.35 0.06 255 0 0 128 0 4 0 0 0 0.0 0 0.0 0 0 0 0 -0.002 90 2000 0.02 0.02 0.0 0 0 1.0 50.0 4
+;
+;
+BULLETHIT_SMOKE 192 192 192 0 0 0 0 0 0.15 0.03 70 0 2 255 1 10 0 0 0 0.0 0 0.0 0 0 0 0 -0.001 90 2000 0.04 0.02 0.0 0 0 1.0 150.0 0
+;
+;
+GUNSHELL_FIRST 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 0.0 12292
+GUNSHELL 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 12.0 4100
+GUNSHELL_BUMP1 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 1000 0.02 0.02 0.0 0 0 1.0 8.0 4100
+GUNSHELL_BUMP2 108 108 108 0 0 0 0 0 0.015 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 0 4 0 0.010 90 400 0.02 0.02 0.0 0 0 1.0 8.0 4100
+;
+;
+TEST 255 64 64 0 0 0 0 0 0.2 0.025 255 1 20 255 0 0 0 0 0 0.0 0 0.0 0 0 0 0 0.0 1 3000 0.0 0.0 0.0 0 0 1.0 400.0 128
+;
+;
+;Particles with flag DRAWTOP2D should be placed last and VR (Visibility Range) set to 0!
+;
+;BIRD_FRONT 8 8 8 0 0 0 0 0 0.05 0.0 255 0 0 255 2 1 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 10000 0.0 0.0 0.0 0 0 1.0 0.0 3140
+BIRD_FRONT 8 8 8 0 0 0 0 0 1.05 0.0 255 0 0 255 2 2 0 0 0 0.0 0 0.0 1 0 3 0 0.0 1 8000 0.0 0.0 0.0 0 0 1.0 0.0 68
+;
+RAINDROP_2D 32 32 32 0 0 0 0 0 0.5 0.0 255 0 0 255 0 0 0 0 0 0.0 0 0.0 0 1 0 0 0.0 1 1000 0.0 0.0 0.0 0 0 1.0 0.0 3072
+;
+;
+;
+;
+;
+;
+;
+;
+;
+;
+;
+;
+; below is just backup of above values:
+;
+;SPARK 255 128 64 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 300 0.0 0.07 0.0 0 0 1.0 48
+;SPARK_SMALL 255 255 128 0.005 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.05 0.0 0 0 0.6 40
+;BLOOD 128 128 128 0.02 0.0 255 0 0 0 0 0 0 0.03 1.0 2000 0.3 0.05 0.0 0 0 1.0 6
+;BLOOD_SMALL 255 32 32 0.007 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.05 0.05 0.0 0 0 1.0 54
+;BLOOD_SPLAT 128 128 128 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 200 0.3 0.0 0.0 0 0 1.0 36
+;BLOOD_SPURT 255 32 32 0.008 0.0 255 0 0 0 0 0 0 0.005 1.0 2000 0.0 0.01 0.0 0 0 2.0 52
+;DEBRIS 64 64 64 0.5 0.0 255 0 0 0 0 0 0 0.01 0.95 1000 0.2 0.0 0.0 0 0 1.0 4
+;DEBRIS2 64 64 64 0.04 0.0 255 0 0 0 0 0 5 0.01 0.99 1000 0.03 0.04 0.0 0 0 1.0 38
+;WATER 64 64 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 2000 0.0 0.0 0.0 0 0 1.0 0
+;FLAME 255 74 30 0.2 0.0 255 0 0 31 0 5 0 0.0 1.0 100 0.05 0.0 0.0 0 0 1.0 0
+;FIREBALL 255 74 30 0.1 0.04 255 0 8 31 0 8 0 0.0 0.96 1000 0.1 0.0 0.0 0 0 1.0 0
+;GUNFLASH 255 255 255 0.1 0.0 255 0 50 50 0 3 0 0.0 1.0 250 0.0 0.0 0.0 0 0 1.0 0
+;GUNFLASHSTATIC 255 255 255 0.1 0.0 255 0 128 0 0 0 0 0.0 1.0 25 0.0 0.0 0.0 0 0 1.0 0
+;SMOKE 32 32 32 0.15 0.015 255 4 25 31 0 5 0 -0.01 0.95 1000 0.05 0.05 0.01 3 0 1.0 0
+;SHARD 255 255 255 0.03 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0
+;SPLASH 64 64 128 0.1 0.007 255 0 10 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
+;BLOOD_SPLASH 24 64 0 0.1 0.0 255 0 0 0 0 0 0 0.0 0.96 300 0.0 0.0 0.0 0 0 1.0 0
+;RUBBER 40 40 40 0.4 0.005 255 1 25 31 0 5 0 0.0 1.0 1000 0.02 0.0 0.0 0 0 1.0 0
+;CARFLAME 255 74 30 0.5 0.04 255 1 20 31 0 5 0 0.0 1.0 1000 0.4 0.0 0.0 0 0 1.0 64
+;STEAM 64 64 64 0.5 0.05 255 0 16 31 0 5 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 0
+;RAINDROP 32 32 32 0.6 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1
+;RAIN_SPLASH 32 32 32 0.08 0.0 255 0 0 1 0 4 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
+;RAINDROP_SMALL 32 32 32 0.3 0.0 255 0 0 0 0 0 0 0.1 1.0 1000 0.0 0.0 0.0 0 0 1.0 1
+;EXPLOSION_MEDIUM 80 80 80 0.6 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.2 0.0 0.0 3 0 1.0 0
+;EXPLOSION_LARGE 80 80 80 1.1 0.04 255 4 8 7 0 11 0 0.0 0.96 30000 0.8 0.0 0.0 3 0 1.0 0
+;BOAT_SPLASH 32 64 32 0.2 0.2 255 0 0 0 0 0 0 0.01 1.0 2000 0.0 0.0 0.0 0 0 1.0 0
+;BOAT_THRUSTJET 24 32 24 0.5 0.1 255 0 0 250 0 5 0 0.01 0.5 1000 0.0 0.0 0.0 0 4 1.0 8
+;WATER_HYDRANT 64 64 128 0.4 0.01 255 1 2 20 0 5 0 0.007 0.99 500 0.02 0.05 0.0 0 4 1.0 256
+;WATER_CANNON 64 64 128 0.03 0.03 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
+;EXTINGUISH_STEAM 32 32 32 0.1 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
+;PED_SPLASH 32 32 64 0.1 0.05 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
+;HELI_DUST 17 15 9 0.2 0.1 255 0 8 0 0 0 0 -0.001 1.0 1000 0.2 0.05 0.0 0 0 1.0 0
+;HELI_ATTACK 255 255 128 0.01 0.0 255 0 0 0 0 0 0 0.0 1.0 500 0.0 0.0 0.0 0 0 0.5 10
+;ENGINE_SMOKE 16 16 16 0.5 0.04 255 0 0 0 0 0 0 -0.005 0.95 2000 0.01 0.03 0.0 0 0 1.0 4
+;ENGINE_SMOKE2 4 4 4 1.0 0.2 255 1 4 0 0 0 0 0.001 1.0 1000 0.0 0.0 0.0 0 3 1.0 4
+;PAINT_SMOKE 255 0 0 0.1 0.01 255 0 8 0 0 0 0 0.0 0.95 3000 0.0 0.005 0.0 0 0 1.0 0
+;TREE_LEAVES 64 64 64 0.2 0.0 255 0 0 0 0 0 0 0.0 1.0 1000 0.0 0.0 0.0 0 0 1.0 0
+;TEST 255 64 64 0.2 0.05 255 0 16 0 0 0 0 0.0 1.0 3000 0.0 0.0 0.0 0 0 1.0 128
+;
+;
+;the end
diff --git a/gamefiles/main_d.scm b/gamefiles/data/main_d.scm
index 7b46ca39..7b46ca39 100644
--- a/gamefiles/main_d.scm
+++ b/gamefiles/data/main_d.scm
Binary files differ
diff --git a/gamefiles/main_freeroam.scm b/gamefiles/data/main_freeroam.scm
index 021b5c25..021b5c25 100644
--- a/gamefiles/main_freeroam.scm
+++ b/gamefiles/data/main_freeroam.scm
Binary files differ
diff --git a/gamefiles/fonts_j.txd b/gamefiles/models/fonts_j.txd
index 437e13f9..437e13f9 100644
--- a/gamefiles/fonts_j.txd
+++ b/gamefiles/models/fonts_j.txd
Binary files differ
diff --git a/gamefiles/fonts_p.txd b/gamefiles/models/fonts_p.txd
index c05e402e..c05e402e 100644
--- a/gamefiles/fonts_p.txd
+++ b/gamefiles/models/fonts_p.txd
Binary files differ
diff --git a/gamefiles/fonts_r.txd b/gamefiles/models/fonts_r.txd
index 4b89e449..4b89e449 100644
--- a/gamefiles/fonts_r.txd
+++ b/gamefiles/models/fonts_r.txd
Binary files differ
diff --git a/gamefiles/menu.txd b/gamefiles/models/menu.txd
index f617bcf8..f617bcf8 100644
--- a/gamefiles/menu.txd
+++ b/gamefiles/models/menu.txd
Binary files differ
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index f836f1c4..02bf532c 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -9548,6 +9548,9 @@ cAudioManager::ResetTimers(uint32 time)
SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload();
+#ifdef OPENAL
+ SampleManager.Service();
+#endif
}
}
@@ -9603,6 +9606,9 @@ cAudioManager::ServiceSoundEffects()
ProcessMissionAudio();
AdjustSamplesVolume();
ProcessActiveQueues();
+#ifdef WITHMILES
+ SampleManager.Service();
+#endif
for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) {
cAudioScriptObject *object =
(cAudioScriptObject *)m_asAudioEntities[m_sAudioScriptObjectManager.m_anScriptObjectEntityIndices[i]]
@@ -9983,7 +9989,7 @@ cAudioManager::Terminate()
m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal = 0;
PreTerminateGameSpecificShutdown();
- for(uint32 i = 0; i < DIGITALCHANNELS; i++) {
+ for(uint32 i = 0; i < MAX_SAMPLEBANKS; i++) {
if(SampleManager.IsSampleBankLoaded(i)) SampleManager.UnloadSampleBank(i);
}
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 01fa055d..72d8ba41 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -581,6 +581,6 @@ public:
uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
};
-static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+//dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
extern cAudioManager AudioManager;
diff --git a/src/audio/miles/sampman_mss.cpp b/src/audio/miles/sampman_mss.cpp
new file mode 100644
index 00000000..f3a6ba80
--- /dev/null
+++ b/src/audio/miles/sampman_mss.cpp
@@ -0,0 +1,2257 @@
+#include <windows.h>
+#include <shobjidl.h>
+#include <shlguid.h>
+
+#include <time.h>
+
+#include "eax.h"
+#include "eax-util.h"
+#include "mss.h"
+
+#include "sampman_mss.h"
+#include "AudioManager.h"
+#include "MusicManager.h"
+#include "Frontend.h"
+#include "Timer.h"
+
+
+#pragma comment( lib, "mss32.lib" )
+
+cSampleManager SampleManager;
+int32 BankStartOffset[MAX_SAMPLEBANKS];
+///////////////////////////////////////////////////////////////
+
+char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
+char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
+
+FILE *fpSampleDescHandle;
+FILE *fpSampleDataHandle;
+bool bSampleBankLoaded [MAX_SAMPLEBANKS];
+int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
+int32 nSampleBankSize [MAX_SAMPLEBANKS];
+int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
+int32 _nSampleDataEndOffset;
+
+int32 nPedSlotSfx [MAX_PEDSFX];
+int32 nPedSlotSfxAddr[MAX_PEDSFX];
+uint8 nCurrentPedSlot;
+
+uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+
+uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
+
+///////////////////////////////////////////////////////////////
+struct tMP3Entry
+{
+ char aFilename[MAX_PATH];
+
+ uint32 nTrackLength;
+ uint32 nTrackStreamPos;
+
+ tMP3Entry *pNext;
+ char *pLinkPath;
+};
+
+uint32 nNumMP3s;
+tMP3Entry *_pMP3List;
+char _mp3DirectoryPath[MAX_PATH];
+HSTREAM mp3Stream [MAX_MP3STREAMS];
+int8 nStreamPan [MAX_MP3STREAMS];
+int8 nStreamVolume[MAX_MP3STREAMS];
+uint32 _CurMP3Index;
+int32 _CurMP3Pos;
+bool _bIsMp3Active;
+
+#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
+bool _bUseHDDAudio;
+char _aHDDPath[MAX_PATH];
+#endif
+///////////////////////////////////////////////////////////////
+
+
+bool _bSampmanInitialised = false;
+
+//
+// Miscellaneous globals / defines
+
+// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
+
+EAXLISTENERPROPERTIES StartEAX3 =
+ {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f };
+
+EAXLISTENERPROPERTIES FinishEAX3 =
+ {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f };
+
+EAXLISTENERPROPERTIES EAX3Params;
+
+S32 prevprovider=-1;
+S32 curprovider=-1;
+S32 usingEAX=0;
+S32 usingEAX3=0;
+HPROVIDER opened_provider=0;
+H3DSAMPLE opened_samples[MAXCHANNELS] = {0};
+HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0};
+HDIGDRIVER DIG;
+S32 speaker_type=0;
+
+U32 _maxSamples;
+float _fPrevEaxRatioDestination;
+bool _usingMilesFast2D;
+float _fEffectsLevel;
+
+
+struct
+{
+ HPROVIDER id;
+ char name[80];
+}providers[MAXPROVIDERS];
+
+typedef struct provider_stuff
+{
+ char* name;
+ HPROVIDER id;
+} provider_stuff;
+
+
+static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2)
+{
+ return( _stricmp(s1->name,s2->name) );
+}
+
+static void
+add_providers()
+{
+ provider_stuff pi[MAXPROVIDERS];
+ U32 n,i,j;
+
+ SampleManager.SetNum3DProvidersAvailable(0);
+
+ HPROENUM next = HPROENUM_FIRST;
+
+ n=0;
+ while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n<MAXPROVIDERS))
+ {
+ ++n;
+ }
+
+ qsort(pi,n,sizeof(pi[0]), (int(__cdecl*)(void const*, void const*))comp);
+
+ for(i=0;i<n;i++)
+ {
+ providers[i].id=pi[i].id;
+ strcpy(providers[i].name, pi[i].name);
+ SampleManager.Set3DProviderName(i, providers[i].name);
+ }
+
+ SampleManager.SetNum3DProvidersAvailable(n);
+
+ for(j=n;j<MAXPROVIDERS;j++)
+ SampleManager.Set3DProviderName(j, NULL);
+}
+
+static void
+release_existing()
+{
+ for ( U32 i = 0; i < _maxSamples; i++ )
+ {
+ if ( opened_samples[i] )
+ {
+ AIL_release_3D_sample_handle(opened_samples[i]);
+ opened_samples[i] = NULL;
+ }
+ }
+
+ if ( opened_provider )
+ {
+ AIL_close_3D_provider(opened_provider);
+ opened_provider = NULL;
+ }
+
+ _fPrevEaxRatioDestination = 0.0f;
+ _usingMilesFast2D = false;
+ _fEffectsLevel = 0.0f;
+}
+
+static bool
+set_new_provider(S32 index)
+{
+ DWORD result;
+
+ if ( curprovider == index )
+ return true;
+
+ //close the already opened provider
+ curprovider = index;
+
+ release_existing();
+
+ if ( curprovider != -1 )
+ {
+ if ( !strcmp(providers[index].name, "Dolby Surround") )
+ _maxSamples = MAXCHANNELS_SURROUND;
+ else
+ _maxSamples = MAXCHANNELS;
+
+ AIL_set_3D_provider_preference(providers[index].id, "Maximum supported samples", &_maxSamples);
+
+ //load the new provider
+ result = AIL_open_3D_provider(providers[index].id);
+
+ if (result != M3D_NOERR)
+ {
+ curprovider=-1;
+
+ OutputDebugStringA(AIL_last_error());
+
+ release_existing();
+
+ return false;
+ }
+ else
+ {
+ opened_provider=providers[index].id;
+
+ //see if we're running under an EAX compatible provider
+
+ if ( !strcmp(providers[index].name, "Creative Labs EAX 3 (TM)") )
+ {
+ usingEAX = 1;
+ usingEAX3 = 1;
+ }
+ else
+ {
+ usingEAX3 = 0;
+
+ result=AIL_3D_room_type(opened_provider);
+ usingEAX=(((S32)result)!=-1)?1:0; // will be something other than -1 on EAX
+ }
+
+ if ( usingEAX3 )
+ {
+ OutputDebugString("DOING SPECIAL EAX 3 STUFF!");
+ AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &FinishEAX3);
+ }
+ else if ( usingEAX )
+ {
+ AIL_set_3D_room_type(opened_provider, ENVIRONMENT_CAVE);
+
+ if ( !strcmp(providers[index].name, "Miles Fast 2D Positional Audio") )
+ _usingMilesFast2D = true;
+ }
+
+ AIL_3D_provider_attribute(opened_provider, "Maximum supported samples", &_maxSamples);
+
+ if ( _maxSamples > MAXCHANNELS )
+ _maxSamples = MAXCHANNELS;
+
+ SampleManager.SetSpeakerConfig(speaker_type);
+
+ //obtain a 3D sample handles
+ for ( U32 i = 0; i < _maxSamples; ++i )
+ {
+ opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider);
+ if ( opened_samples[i] != NULL )
+ AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f);
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::SetSpeakerConfig(int32 which)
+{
+ switch ( which )
+ {
+ case 1:
+ speaker_type=AIL_3D_2_SPEAKER;
+ break;
+
+ case 2:
+ speaker_type=AIL_3D_HEADPHONE;
+ break;
+
+ case 3:
+ speaker_type=AIL_3D_4_SPEAKER;
+ break;
+
+ default:
+ return;
+ break;
+ }
+
+ if (opened_provider)
+ AIL_set_3D_speaker_type(opened_provider, speaker_type);
+}
+
+uint32
+cSampleManager::GetMaximumSupportedChannels(void)
+{
+ if ( _maxSamples > MAXCHANNELS )
+ return MAXCHANNELS;
+
+ return _maxSamples;
+}
+
+int8
+cSampleManager::GetCurrent3DProviderIndex(void)
+{
+ return curprovider;
+}
+
+int8
+cSampleManager::SetCurrent3DProvider(uint8 nProvider)
+{
+ S32 savedprovider = curprovider;
+
+ if ( nProvider < m_nNumberOfProviders )
+ {
+ if ( set_new_provider(nProvider) )
+ return curprovider;
+ else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
+ return curprovider;
+ else
+ return -1;
+ }
+ else
+ return curprovider;
+}
+
+static bool
+_ResolveLink(char const *path, char *out)
+{
+ IShellLink* psl;
+ WIN32_FIND_DATA fd;
+ char filepath[MAX_PATH];
+
+ CoInitialize(NULL);
+
+ if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) ))
+ {
+ IPersistFile *ppf;
+
+ if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
+ {
+ WCHAR wpath[MAX_PATH];
+
+ MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH);
+
+ if (SUCCEEDED(ppf->Load(wpath, STGM_READ)))
+ {
+ /* Resolve the link */
+ if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH)))
+ {
+ strcpy(filepath, path);
+
+ if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY)))
+ {
+ OutputDebugString(fd.cFileName);
+
+ strcpy(out, filepath);
+ // FIX: Release the objects. Taken from SA.
+#ifdef FIX_BUGS
+ ppf->Release();
+ psl->Release();
+#endif
+ return true;
+ }
+ }
+ }
+
+ ppf->Release();
+ }
+ psl->Release();
+ }
+
+ return false;
+}
+
+static void
+_FindMP3s(void)
+{
+ tMP3Entry *pList;
+ bool bShortcut;
+ bool bInitFirstEntry;
+ HANDLE hFind;
+ char path[MAX_PATH];
+ char filepath[MAX_PATH*2];
+ S32 total_ms;
+ WIN32_FIND_DATA fd;
+
+
+ if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 )
+ {
+ GetLastError();
+ return;
+ }
+
+ OutputDebugString("Finding MP3s...");
+ strcpy(path, _mp3DirectoryPath);
+ strcat(path, "\\MP3\\");
+
+ strcpy(_mp3DirectoryPath, path);
+ OutputDebugString(_mp3DirectoryPath);
+
+ strcat(path, "*");
+
+ hFind = FindFirstFile(path, &fd);
+
+ if ( hFind == INVALID_HANDLE_VALUE )
+ {
+ GetLastError();
+ return;
+ }
+
+ strcpy(filepath, _mp3DirectoryPath);
+ strcat(filepath, fd.cFileName);
+
+ int32 filepathlen = strlen(filepath);
+
+ if ( filepathlen <= 0)
+ {
+ FindClose(hFind);
+ return;
+ }
+
+ FILE *f = fopen("MP3\\MP3Report.txt", "w");
+
+ if ( f )
+ {
+ fprintf(f, "MP3 Report File\n\n");
+ fprintf(f, "\"%s\"", fd.cFileName);
+ }
+
+
+ if ( filepathlen > 4 )
+ {
+ if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
+ {
+ if ( _ResolveLink(filepath, filepath) )
+ {
+ OutputDebugString("Resolving Link");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
+ }
+ else
+ {
+ if ( f ) fprintf(f, " - couldn't resolve shortcut");
+ }
+
+ bShortcut = true;
+ }
+ else
+ bShortcut = false;
+ }
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ OutputDebugString(fd.cFileName);
+
+ _pMP3List = new tMP3Entry;
+
+ if ( _pMP3List == NULL )
+ {
+ FindClose(hFind);
+
+ if ( f )
+ fclose(f);
+
+ return;
+ }
+
+ nNumMP3s = 1;
+
+ strcpy(_pMP3List->aFilename, fd.cFileName);
+
+ _pMP3List->nTrackLength = total_ms;
+
+ _pMP3List->pNext = NULL;
+
+ pList = _pMP3List;
+
+ if ( bShortcut )
+ {
+ _pMP3List->pLinkPath = new char[MAX_PATH*2];
+ strcpy(_pMP3List->pLinkPath, filepath);
+ }
+ else
+ {
+ _pMP3List->pLinkPath = NULL;
+ }
+
+ if ( f ) fprintf(f, " - OK\n");
+
+ bInitFirstEntry = false;
+ }
+ else
+ {
+ strcat(filepath, " - NOT A VALID MP3");
+
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
+
+ bInitFirstEntry = true;
+ }
+
+ while ( true )
+ {
+ if ( !FindNextFile(hFind, &fd) )
+ break;
+
+ if ( bInitFirstEntry )
+ {
+ strcpy(filepath, _mp3DirectoryPath);
+ strcat(filepath, fd.cFileName);
+
+ int32 filepathlen = strlen(filepath);
+
+ if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
+
+ if ( filepathlen > 0 )
+ {
+ if ( filepathlen > 4 )
+ {
+ if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
+ {
+ if ( _ResolveLink(filepath, filepath) )
+ {
+ OutputDebugString("Resolving Link");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
+ }
+ else
+ {
+ if ( f ) fprintf(f, " - couldn't resolve shortcut");
+ }
+
+ bShortcut = true;
+ }
+ else
+ {
+ bShortcut = false;
+
+ if ( filepathlen > MAX_PATH )
+ {
+ if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
+
+ continue;
+ }
+ }
+ }
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ OutputDebugString(fd.cFileName);
+
+ _pMP3List = new tMP3Entry;
+
+ if ( _pMP3List == NULL)
+ break;
+
+ nNumMP3s = 1;
+
+ strcpy(_pMP3List->aFilename, fd.cFileName);
+
+ _pMP3List->nTrackLength = total_ms;
+ _pMP3List->pNext = NULL;
+
+ if ( bShortcut )
+ {
+ _pMP3List->pLinkPath = new char [MAX_PATH*2];
+ strcpy(_pMP3List->pLinkPath, filepath);
+ }
+ else
+ {
+ _pMP3List->pLinkPath = NULL;
+ }
+
+ pList = _pMP3List;
+
+ if ( f ) fprintf(f, " - OK\n");
+
+ bInitFirstEntry = false;
+ }
+ else
+ {
+ strcat(filepath, " - NOT A VALID MP3");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
+ }
+ }
+ }
+ else
+ {
+ strcpy(filepath, _mp3DirectoryPath);
+ strcat(filepath, fd.cFileName);
+
+ int32 filepathlen = strlen(filepath);
+
+ if ( filepathlen > 0 )
+ {
+ if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
+
+ if ( filepathlen > 4 )
+ {
+ if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
+ {
+ if ( _ResolveLink(filepath, filepath) )
+ {
+ OutputDebugString("Resolving Link");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
+ }
+ else
+ {
+ if ( f ) fprintf(f, " - couldn't resolve shortcut");
+ }
+
+ bShortcut = true;
+ }
+ else
+ {
+ bShortcut = false;
+ }
+ }
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ pList->pNext = new tMP3Entry;
+
+ tMP3Entry *e = pList->pNext;
+
+ if ( e == NULL )
+ break;
+
+ pList = pList->pNext;
+
+ strcpy(e->aFilename, fd.cFileName);
+ e->nTrackLength = total_ms;
+ e->pNext = NULL;
+
+ if ( bShortcut )
+ {
+ e->pLinkPath = new char [MAX_PATH*2];
+ strcpy(e->pLinkPath, filepath);
+ }
+ else
+ {
+ e->pLinkPath = NULL;
+ }
+
+ nNumMP3s++;
+
+ OutputDebugString(fd.cFileName);
+
+ if ( f ) fprintf(f, " - OK\n");
+ }
+ else
+ {
+ strcat(filepath, " - NOT A VALID MP3");
+ OutputDebugString(filepath);
+
+ if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
+ }
+ }
+ }
+ }
+
+ if ( f )
+ {
+ fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
+ fclose(f);
+ }
+
+ FindClose(hFind);
+}
+
+static void
+_DeleteMP3Entries(void)
+{
+ tMP3Entry *e = _pMP3List;
+
+ while ( e != NULL )
+ {
+ tMP3Entry *next = e->pNext;
+
+ if ( next == NULL )
+ next = NULL;
+
+ if ( e->pLinkPath != NULL )
+ {
+#ifndef FIX_BUGS
+ delete e->pLinkPath; // BUG: should be delete []
+#else
+ delete[] e->pLinkPath;
+#endif
+ e->pLinkPath = NULL;
+ }
+
+ delete e;
+
+ if ( next )
+ e = next;
+ else
+ e = NULL;
+
+ nNumMP3s--;
+ }
+
+
+ if ( nNumMP3s != 0 )
+ {
+ OutputDebugString("Not all MP3 entries were deleted");
+ nNumMP3s = 0;
+ }
+
+ _pMP3List = NULL;
+}
+
+static tMP3Entry *
+_GetMP3EntryByIndex(uint32 idx)
+{
+ uint32 n = ( idx < nNumMP3s ) ? idx : 0;
+
+ if ( _pMP3List != NULL )
+ {
+ tMP3Entry *e = _pMP3List;
+
+ for ( uint32 i = 0; i < n; i++ )
+ e = e->pNext;
+
+ return e;
+
+ }
+
+ return NULL;
+}
+
+static inline bool
+_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry)
+{
+ _CurMP3Index = 0;
+
+ for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext )
+ {
+ if ( *pPosition >= (*pEntry)->nTrackStreamPos
+ && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos )
+ {
+ *pPosition -= (*pEntry)->nTrackStreamPos;
+ _CurMP3Pos = *pPosition;
+
+ return true;
+ }
+
+ _CurMP3Index++;
+ }
+
+ *pPosition = 0;
+ *pEntry = _pMP3List;
+ _CurMP3Pos = 0;
+ _CurMP3Index = 0;
+
+ return false;
+}
+
+bool
+cSampleManager::IsMP3RadioChannelAvailable(void)
+{
+ return nNumMP3s != 0;
+}
+
+void
+cSampleManager::ReleaseDigitalHandle(void)
+{
+ if ( DIG )
+ {
+ prevprovider = curprovider;
+ release_existing();
+ curprovider = -1;
+ AIL_digital_handle_release(DIG);
+ }
+}
+
+void
+cSampleManager::ReacquireDigitalHandle(void)
+{
+ if ( DIG )
+ {
+ AIL_digital_handle_reacquire(DIG);
+ if ( prevprovider != -1 )
+ set_new_provider(prevprovider);
+ }
+}
+
+bool
+cSampleManager::Initialise(void)
+{
+ TRACE("start");
+
+ if ( _bSampmanInitialised )
+ return true;
+
+ {
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ m_aSamples[i].nOffset = 0;
+ m_aSamples[i].nSize = 0;
+ m_aSamples[i].nFrequency = 22050;
+ m_aSamples[i].nLoopStart = 0;
+ m_aSamples[i].nLoopEnd = -1;
+ }
+
+ m_nEffectsVolume = MAX_VOLUME;
+ m_nMusicVolume = MAX_VOLUME;
+ m_nEffectsFadeVolume = MAX_VOLUME;
+ m_nMusicFadeVolume = MAX_VOLUME;
+
+ m_nMonoMode = 0;
+ }
+
+ // miles
+ TRACE("MILES");
+ {
+ curprovider = -1;
+ prevprovider = -1;
+
+ _usingMilesFast2D = false;
+ usingEAX=0;
+ usingEAX3=0;
+
+ _fEffectsLevel = 0.0f;
+
+ _maxSamples = 0;
+
+ opened_provider = NULL;
+ DIG = NULL;
+
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ opened_samples[i] = NULL;
+ }
+
+ // banks
+ TRACE("banks");
+ {
+ fpSampleDescHandle = NULL;
+ fpSampleDataHandle = NULL;
+
+ _nSampleDataEndOffset = 0;
+
+ for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
+ {
+ bSampleBankLoaded[i] = false;
+ nSampleBankDiscStartOffset[i] = 0;
+ nSampleBankSize[i] = 0;
+ nSampleBankMemoryStartAddress[i] = 0;
+ }
+ }
+
+ // pedsfx
+ TRACE("pedsfx");
+ {
+ for ( int32 i = 0; i < MAX_PEDSFX; i++ )
+ {
+ nPedSlotSfx[i] = NO_SAMPLE;
+ nPedSlotSfxAddr[i] = 0;
+ }
+
+ nCurrentPedSlot = 0;
+ }
+
+ // channel volume
+ TRACE("vol");
+ {
+ for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+ nChannelVolume[i] = 0;
+ }
+
+ TRACE("mss");
+ {
+ AIL_set_redist_directory( "mss" );
+
+ AIL_startup();
+
+ AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS);
+
+ DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0);
+ if ( DIG == NULL )
+ {
+ OutputDebugString(AIL_last_error());
+ Terminate();
+ return false;
+ }
+
+ add_providers();
+
+ if ( !InitialiseSampleBanks() )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]);
+ if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
+
+ }
+
+ TRACE("cdrom");
+
+ S32 tatalms;
+ char filepath[MAX_PATH];
+
+ {
+ m_bInitialised = false;
+
+ while (true)
+ {
+ int32 drive = 'C';
+
+ do
+ {
+ char latter[2];
+
+ latter[0] = drive;
+ latter[1] = '\0';
+
+ strcpy(m_szCDRomRootPath, latter);
+ strcat(m_szCDRomRootPath, ":\\");
+
+ if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM )
+ {
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[0]);
+
+ FILE *f = fopen(filepath, "rb");
+
+ if ( f )
+ {
+ fclose(f);
+
+ bool bFileNotFound = false;
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ {
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ nStreamLength[i] = tatalms;
+ }
+ else
+ {
+ bFileNotFound = true;
+ break;
+ }
+ }
+
+ if ( !bFileNotFound )
+ {
+ m_bInitialised = true;
+ break;
+ }
+ else
+ {
+ m_bInitialised = false;
+ continue;
+ }
+ }
+ }
+
+ } while ( ++drive <= 'Z' );
+
+ if ( !m_bInitialised )
+ {
+#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+ FrontEndMenuManager.WaitForUserCD();
+ if ( FrontEndMenuManager.m_bQuitGameNoCD )
+ {
+ Terminate();
+ return false;
+ }
+ continue;
+#else
+ m_bInitialised = true;
+#endif
+ }
+
+ break;
+ }
+ }
+
+#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
+ // hddaudio
+ /**
+ Option for user to play audio files directly from hard disk.
+ Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory.
+ Grand Theft Auto III still requires the presence of the PLAY disc when started.
+ This may give better performance on some machines (though worse on others).
+ **/
+ TRACE("hddaudio 1.1 patch");
+ {
+ int32 streamLength[TOTAL_STREAMED_SOUNDS];
+
+ bool bFileNotFound = false;
+ char rootpath[MAX_PATH];
+
+ strcpy(_aHDDPath, m_szCDRomRootPath);
+ rootpath[0] = '\0';
+
+ FILE *f = fopen(StreamedNameTable[0], "rb");
+
+ if ( f )
+ {
+ fclose(f);
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ {
+ strcpy(filepath, rootpath);
+ strcat(filepath, StreamedNameTable[i]);
+
+ mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( mp3Stream[0] )
+ {
+ AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
+
+ AIL_close_stream(mp3Stream[0]);
+ mp3Stream[0] = NULL;
+
+ streamLength[i] = tatalms;
+ }
+ else
+ {
+ bFileNotFound = true;
+ break;
+ }
+ }
+
+ }
+ else
+ bFileNotFound = true;
+
+ if ( !bFileNotFound )
+ {
+ strcpy(m_szCDRomRootPath, rootpath);
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ nStreamLength[i] = streamLength[i];
+
+ _bUseHDDAudio = true;
+ }
+ else
+ _bUseHDDAudio = false;
+ }
+#endif
+
+ TRACE("stream");
+ {
+ for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+ {
+ mp3Stream [i] = NULL;
+ nStreamPan [i] = 63;
+ nStreamVolume[i] = 100;
+ }
+ }
+
+ for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
+ {
+ opened_2dsamples[i] = AIL_allocate_sample_handle(DIG);
+ if ( opened_2dsamples[i] )
+ {
+ AIL_init_sample(opened_2dsamples[i]);
+ AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN);
+ }
+ }
+
+ TRACE("providerset");
+ {
+ _bSampmanInitialised = true;
+
+ U32 n = 0;
+
+ while ( n < m_nNumberOfProviders )
+ {
+ if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") )
+ {
+ set_new_provider(n);
+ break;
+ }
+ n++;
+ }
+
+ if ( n == m_nNumberOfProviders )
+ {
+ Terminate();
+ return false;
+ }
+ }
+
+ TRACE("bank");
+
+ LoadSampleBank(SAMPLEBANK_MAIN);
+
+ // mp3
+ TRACE("mp3");
+ {
+ nNumMP3s = 0;
+
+ _pMP3List = NULL;
+
+ _FindMP3s();
+
+ if ( nNumMP3s != 0 )
+ {
+ nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0;
+
+ for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext )
+ {
+ e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER];
+ nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength;
+ }
+
+ time_t t = time(NULL);
+ tm *localtm;
+ bool bUseRandomTable;
+
+ if ( t == -1 )
+ bUseRandomTable = true;
+ else
+ {
+ bUseRandomTable = false;
+ localtm = localtime(&t);
+ }
+
+ int32 randval;
+ if ( bUseRandomTable )
+ randval = AudioManager.GetRandomNumber(1);
+ else
+ randval = localtm->tm_sec * localtm->tm_min;
+
+ _CurMP3Index = randval % nNumMP3s;
+
+ tMP3Entry *randmp3 = _pMP3List;
+ for ( int32 i = randval % nNumMP3s; i > 0; --i)
+ randmp3 = randmp3->pNext;
+
+ if ( bUseRandomTable )
+ _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ else
+ {
+ if ( localtm->tm_sec > 0 )
+ {
+ int32 s = localtm->tm_sec;
+ _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
+ }
+ else
+ _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
+ }
+ }
+ else
+ _CurMP3Pos = 0;
+
+ _bIsMp3Active = false;
+ }
+
+ TRACE("end");
+
+ return true;
+}
+
+void
+cSampleManager::Terminate(void)
+{
+ for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+ {
+ if ( mp3Stream[i] )
+ {
+ AIL_pause_stream(mp3Stream[i], 1);
+ AIL_close_stream(mp3Stream[i]);
+ mp3Stream[i] = NULL;
+ }
+ }
+
+ for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
+ {
+ if ( opened_2dsamples[i] )
+ {
+ AIL_release_sample_handle(opened_2dsamples[i]);
+ opened_2dsamples[i] = NULL;
+ }
+ }
+
+ release_existing();
+
+ _DeleteMP3Entries();
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
+ {
+ AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
+ }
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
+ {
+ AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
+ }
+
+ if ( DIG )
+ {
+ AIL_close_digital_driver(DIG);
+ DIG = NULL;
+ }
+
+ AIL_shutdown();
+
+ _bSampmanInitialised = false;
+}
+
+bool
+cSampleManager::CheckForAnAudioFileOnCD(void)
+{
+#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+ char filepath[MAX_PATH];
+
+#if defined(GTA3_1_1_PATCH)
+ if (_bUseHDDAudio)
+ strcpy(filepath, _aHDDPath);
+ else
+ strcpy(filepath, m_szCDRomRootPath);
+#else
+ strcpy(filepath, m_szCDRomRootPath);
+#endif // #if defined(GTA3_1_1_PATCH)
+
+ strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
+
+ FILE *f = fopen(filepath, "rb");
+
+ if ( f )
+ {
+ fclose(f);
+
+ return true;
+ }
+
+ return false;
+
+#else
+ return true;
+#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+}
+
+char
+cSampleManager::GetCDAudioDriveLetter(void)
+{
+#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
+ if (_bUseHDDAudio)
+ {
+ if ( strlen(_aHDDPath) != 0 )
+ return _aHDDPath[0];
+ else
+ return '\0';
+ }
+ else
+ {
+ if ( strlen(m_szCDRomRootPath) != 0 )
+ return m_szCDRomRootPath[0];
+ else
+ return '\0';
+ }
+#else
+ if ( strlen(m_szCDRomRootPath) != 0 )
+ return m_szCDRomRootPath[0];
+ else
+ return '\0';
+#endif
+}
+
+void
+cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ?
+{
+ if ( _bSampmanInitialised )
+ {
+ for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+ {
+ if ( i < MAXCHANNELS )
+ {
+ if ( opened_samples[i] && GetChannelUsedFlag(i) )
+ {
+ if ( nChannelVolume[i] )
+ {
+ AIL_set_3D_sample_volume(opened_samples[i],
+ m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14);
+ }
+ }
+ }
+ else
+ {
+ if ( opened_2dsamples[i - MAXCHANNELS] )
+ {
+ if ( GetChannelUsedFlag(i - MAXCHANNELS) )
+ {
+ if ( nChannelVolume[i - MAXCHANNELS] )
+ {
+ AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS],
+ m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
+{
+ m_nEffectsVolume = nVolume;
+ UpdateEffectsVolume();
+}
+
+void
+cSampleManager::SetMusicMasterVolume(uint8 nVolume)
+{
+ m_nMusicVolume = nVolume;
+}
+
+void
+cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
+{
+ m_nEffectsFadeVolume = nVolume;
+ UpdateEffectsVolume();
+}
+
+void
+cSampleManager::SetMusicFadeVolume(uint8 nVolume)
+{
+ m_nMusicFadeVolume = nVolume;
+}
+
+bool
+cSampleManager::LoadSampleBank(uint8 nBank)
+{
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ if ( MusicManager.IsInitialised()
+ && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && nBank != SAMPLEBANK_MAIN )
+ {
+ return false;
+ }
+
+ if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] )
+ return false;
+
+ bSampleBankLoaded[nBank] = true;
+
+ return true;
+}
+
+void
+cSampleManager::UnloadSampleBank(uint8 nBank)
+{
+ bSampleBankLoaded[nBank] = false;
+}
+
+bool
+cSampleManager::IsSampleBankLoaded(uint8 nBank)
+{
+ return bSampleBankLoaded[nBank];
+}
+
+bool
+cSampleManager::IsPedCommentLoaded(uint32 nComment)
+{
+ uint8 slot;
+
+ for ( int32 i = 0; i < _TODOCONST(3); i++ )
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if ( nComment == nPedSlotSfx[slot] )
+ return true;
+ }
+
+ return false;
+}
+
+int32
+cSampleManager::_GetPedCommentSlot(uint32 nComment)
+{
+ uint8 slot;
+
+ for ( int32 i = 0; i < _TODOCONST(3); i++ )
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if ( nComment == nPedSlotSfx[slot] )
+ return slot;
+ }
+
+ return -1;
+}
+
+bool
+cSampleManager::LoadPedComment(uint32 nComment)
+{
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ // no talking peds during cutsenes or the game end
+ if ( MusicManager.IsInitialised() )
+ {
+ switch ( MusicManager.GetMusicMode() )
+ {
+ case MUSICMODE_CUTSCENE:
+ {
+ return false;
+
+ break;
+ }
+
+ case MUSICMODE_FRONTEND:
+ {
+ if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
+ return false;
+
+ break;
+ }
+ }
+ }
+
+ if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
+ return false;
+
+ nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot;
+ nPedSlotSfx [nCurrentPedSlot] = nComment;
+
+ if ( ++nCurrentPedSlot >= MAX_PEDSFX )
+ nCurrentPedSlot = 0;
+
+ return true;
+}
+
+int32
+cSampleManager::GetSampleBaseFrequency(uint32 nSample)
+{
+ return m_aSamples[nSample].nFrequency;
+}
+
+int32
+cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
+{
+ return m_aSamples[nSample].nLoopStart;
+}
+
+int32
+cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
+{
+ return m_aSamples[nSample].nLoopEnd;
+}
+
+uint32
+cSampleManager::GetSampleLength(uint32 nSample)
+{
+ return m_aSamples[nSample].nSize >> 1;
+}
+
+bool
+cSampleManager::UpdateReverb(void)
+{
+ if ( !usingEAX )
+ return false;
+
+ if ( AudioManager.GetFrameCounter() & 15 )
+ return false;
+
+ float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
+ float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
+ float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
+
+ float normy = norm(y, 5.0f, 40.0f);
+ float normx = norm(x, 5.0f, 40.0f);
+ float normz = norm(z, 5.0f, 40.0f);
+
+ float fRatio;
+
+ if ( normy == 0.0f )
+ {
+ if ( normx == 0.0f )
+ {
+ if ( normz == 0.0f )
+ fRatio = 0.3f;
+ else
+ fRatio = 0.5f;
+ }
+ else
+ {
+ fRatio = 0.3f;
+ }
+ }
+ else
+ {
+ if ( normx == 0.0f )
+ {
+ if ( normz == 0.0f )
+ fRatio = 0.3f;
+ else
+ fRatio = 0.5f;
+ }
+ else
+ {
+ if ( normz == 0.0f )
+ fRatio = 0.3f;
+ else
+ fRatio = (normy+normx+normz) / 3.0f;
+ }
+ }
+
+ fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
+
+ if ( fRatio == _fPrevEaxRatioDestination )
+ return false;
+
+ if ( usingEAX3 )
+ {
+ if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
+ {
+ AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params);
+ _fEffectsLevel = 1.0f - fRatio * 0.5f;
+ }
+ }
+ else
+ {
+ if ( _usingMilesFast2D )
+ _fEffectsLevel = (1.0f - fRatio) * 0.4f;
+ else
+ _fEffectsLevel = (1.0f - fRatio) * 0.7f;
+ }
+
+ _fPrevEaxRatioDestination = fRatio;
+
+ return true;
+}
+
+void
+cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( usingEAX )
+ {
+ if ( nReverbFlag != 0 )
+ {
+ if ( !b2d )
+ AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel);
+ }
+ else
+ {
+ if ( !b2d )
+ AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f);
+ }
+ }
+}
+
+bool
+cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ int32 addr;
+
+ if ( nSfx < SAMPLEBANK_MAX )
+ {
+ if ( !IsSampleBankLoaded(nBank) )
+ return false;
+
+ addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
+ }
+ else
+ {
+ if ( !IsPedCommentLoaded(nSfx) )
+ return false;
+
+ int32 slot = _GetPedCommentSlot(nSfx);
+
+ addr = nPedSlotSfxAddr[slot];
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ {
+ AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize);
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ AILSOUNDINFO info;
+
+ info.format = WAVE_FORMAT_PCM;
+ info.data_ptr = (void *)addr;
+ info.channels = 1;
+ info.data_len = m_aSamples[nSfx].nSize;
+ info.rate = m_aSamples[nSfx].nFrequency;
+ info.bits = 16;
+
+ if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 )
+ {
+ OutputDebugString(AIL_last_error());
+ return false;
+ }
+
+ return true;
+ }
+}
+
+void
+cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
+{
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14);
+
+}
+
+void
+cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
+{
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ);
+}
+
+void
+cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
+{
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin);
+}
+
+void
+cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
+{
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ nChannelVolume[nChannel] = vol;
+
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ {
+ AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS],
+ m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ }
+
+ break;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
+{
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+#ifndef FIX_BUGS
+ if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG
+#else
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+#endif
+ AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan);
+
+ break;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq);
+ }
+}
+
+void
+cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd);
+ }
+}
+
+void
+cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount);
+ }
+}
+
+bool
+cSampleManager::GetChannelUsedFlag(uint32 nChannel)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING;
+ else
+ return false;
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING;
+ else
+ return false;
+ }
+
+}
+
+void
+cSampleManager::StartChannel(uint32 nChannel)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ AIL_start_3D_sample(opened_samples[nChannel]);
+ }
+}
+
+void
+cSampleManager::StopChannel(uint32 nChannel)
+{
+ bool b2d = false;
+
+ switch ( nChannel )
+ {
+ case CHANNEL2D:
+ {
+ b2d = true;
+ break;
+ }
+ }
+
+ if ( b2d )
+ {
+ if ( opened_2dsamples[nChannel - MAXCHANNELS] )
+ AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
+ }
+ else
+ {
+ if ( opened_samples[nChannel] )
+ {
+ if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING )
+ AIL_end_3D_sample(opened_samples[nChannel]);
+ }
+ }
+}
+
+void
+cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ AIL_pause_stream(mp3Stream[nStream], 1);
+ AIL_close_stream(mp3Stream[nStream]);
+ }
+
+ char filepath[MAX_PATH];
+
+ strcpy(filepath, m_szCDRomRootPath);
+ strcat(filepath, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
+
+ if ( mp3Stream[nStream] )
+ {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_service_stream(mp3Stream[nStream], 1);
+ }
+ else
+ OutputDebugString(AIL_last_error());
+ }
+ }
+}
+
+void
+cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0);
+ }
+}
+
+void
+cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ AIL_start_stream(mp3Stream[nStream]);
+ }
+}
+
+bool
+cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+{
+ uint32 position = nPos;
+ char filename[MAX_PATH];
+
+ if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ AIL_pause_stream(mp3Stream[nStream], 1);
+ AIL_close_stream(mp3Stream[nStream]);
+ }
+
+ if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER )
+ {
+ uint32 i = 0;
+ do {
+ if(i != 0 || _bIsMp3Active) {
+ if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0;
+
+ _CurMP3Pos = 0;
+
+ tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
+
+ if(mp3) {
+ mp3 = _pMP3List;
+ if(mp3 == NULL) {
+ _bIsMp3Active = false;
+ nFile = 0;
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(
+ mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(
+ mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream],
+ 0);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ if(mp3->pLinkPath != NULL)
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, mp3->pLinkPath, 0);
+ else {
+ strcpy(filename, _mp3DirectoryPath);
+ strcat(filename, mp3->aFilename);
+
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
+ }
+
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(mp3Stream[nStream], 0);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+ return true;
+ }
+
+ _bIsMp3Active = false;
+ continue;
+ }
+ if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
+ position = 0;
+
+ tMP3Entry *e;
+ if ( !_GetMP3PosFromStreamPos(&position, &e) )
+ {
+ if ( e == NULL )
+ {
+ nFile = 0;
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+ mp3Stream[nStream] =
+ AIL_open_stream(DIG, filename, 0);
+ if(mp3Stream[nStream]) {
+ AIL_set_stream_loop_count(
+ mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(
+ mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ if ( e->pLinkPath != NULL )
+ mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0);
+ else
+ {
+ strcpy(filename, _mp3DirectoryPath);
+ strcat(filename, e->aFilename);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ }
+
+ if ( mp3Stream[nStream] )
+ {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+
+ _bIsMp3Active = true;
+
+ return true;
+ }
+
+ _bIsMp3Active = false;
+
+ } while(++i < nNumMP3s);
+
+ position = 0;
+ nFile = 0;
+ }
+
+ strcpy(filename, m_szCDRomRootPath);
+ strcat(filename, StreamedNameTable[nFile]);
+
+ mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
+ if ( mp3Stream[nStream] )
+ {
+ AIL_set_stream_loop_count(mp3Stream[nStream], 1);
+ AIL_set_stream_ms_position(mp3Stream[nStream], position);
+ AIL_pause_stream(mp3Stream[nStream], 0);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StopStreamedFile(uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ AIL_pause_stream(mp3Stream[nStream], 1);
+
+ AIL_close_stream(mp3Stream[nStream]);
+ mp3Stream[nStream] = NULL;
+
+ if ( nStream == 0 )
+ _bIsMp3Active = false;
+ }
+ }
+}
+
+int32
+cSampleManager::GetStreamedFilePosition(uint8 nStream)
+{
+ S32 currentms;
+
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ if ( _bIsMp3Active )
+ {
+ tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
+
+ if ( mp3 != NULL )
+ {
+ AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
+ return currentms + mp3->nTrackStreamPos;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
+ return currentms;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+{
+ uint8 vol = nVolume;
+
+ if ( m_bInitialised )
+ {
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nStreamVolume[nStream] = vol;
+ nStreamPan[nStream] = nPan;
+
+ if ( mp3Stream[nStream] )
+ {
+ if ( nEffectFlag )
+ AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+ else
+ AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14);
+
+ AIL_set_stream_pan(mp3Stream[nStream], nPan);
+ }
+ }
+}
+
+int32
+cSampleManager::GetStreamedFileLength(uint8 nStream)
+{
+ if ( m_bInitialised )
+ return nStreamLength[nStream];
+
+ return 0;
+}
+
+bool
+cSampleManager::IsStreamPlaying(uint8 nStream)
+{
+ if ( m_bInitialised )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING )
+ return true;
+ else
+ return false;
+ }
+ }
+
+ return false;
+}
+
+bool
+cSampleManager::InitialiseSampleBanks(void)
+{
+ int32 nBank = SAMPLEBANK_MAIN;
+
+ fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
+ if ( fpSampleDescHandle == NULL )
+ return false;
+
+ fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
+ if ( fpSampleDataHandle == NULL )
+ {
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ return false;
+ }
+
+ fseek(fpSampleDataHandle, 0, SEEK_END);
+ _nSampleDataEndOffset = ftell(fpSampleDataHandle);
+ rewind(fpSampleDataHandle);
+
+ fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
+
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+#ifdef FIX_BUGS
+ if (nBank >= MAX_SAMPLEBANKS) break;
+#endif
+ if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
+ {
+ nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
+ nBank++;
+ }
+ }
+
+ nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
+ nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
+
+ return true;
+}
diff --git a/src/audio/miles/sampman_mss.h b/src/audio/miles/sampman_mss.h
new file mode 100644
index 00000000..ebedfb63
--- /dev/null
+++ b/src/audio/miles/sampman_mss.h
@@ -0,0 +1,339 @@
+#pragma once
+#include "common.h"
+#include "AudioSamples.h"
+
+#define MAX_VOLUME 127
+
+struct tSample {
+ int32 nOffset;
+ uint32 nSize;
+ int32 nFrequency;
+ int32 nLoopStart;
+ int32 nLoopEnd;
+};
+
+enum
+{
+ SAMPLEBANK_MAIN,
+ SAMPLEBANK_PED,
+ MAX_SAMPLEBANKS,
+ SAMPLEBANK_INVALID
+};
+
+#define MAX_PEDSFX 7
+#define PED_BLOCKSIZE 79000
+
+#define MAXPROVIDERS 64
+
+#define MAXCHANNELS 28
+#define MAXCHANNELS_SURROUND 24
+#define MAX2DCHANNELS 1
+#define CHANNEL2D MAXCHANNELS
+
+#define MAX_MP3STREAMS 2
+
+#define DIGITALRATE 32000
+#define DIGITALBITS 16
+#define DIGITALCHANNELS 2
+
+#define MAX_DIGITAL_MIXER_CHANNELS 32
+
+class cSampleManager
+{
+ uint8 m_nEffectsVolume;
+ uint8 m_nMusicVolume;
+ uint8 m_nEffectsFadeVolume;
+ uint8 m_nMusicFadeVolume;
+ uint8 m_nMonoMode;
+ char unk;
+ char m_szCDRomRootPath[80];
+ bool m_bInitialised;
+ uint8 m_nNumberOfProviders;
+ char *m_aAudioProviders[MAXPROVIDERS];
+ tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+
+public:
+
+
+
+ cSampleManager(void) :
+ m_nNumberOfProviders(0)
+ { }
+
+ ~cSampleManager(void)
+ { }
+
+ void SetSpeakerConfig(int32 nConfig);
+ uint32 GetMaximumSupportedChannels(void);
+
+ uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
+ void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
+
+ char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
+ void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
+
+ int8 GetCurrent3DProviderIndex(void);
+ int8 SetCurrent3DProvider(uint8 which);
+
+ bool IsMP3RadioChannelAvailable(void);
+
+ void ReleaseDigitalHandle (void);
+ void ReacquireDigitalHandle(void);
+
+ bool Initialise(void);
+ void Terminate (void);
+
+ bool CheckForAnAudioFileOnCD(void);
+ char GetCDAudioDriveLetter (void);
+
+ void UpdateEffectsVolume(void);
+
+ void SetEffectsMasterVolume(uint8 nVolume);
+ void SetMusicMasterVolume (uint8 nVolume);
+ void SetEffectsFadeVolume (uint8 nVolume);
+ void SetMusicFadeVolume (uint8 nVolume);
+
+ bool LoadSampleBank (uint8 nBank);
+ void UnloadSampleBank (uint8 nBank);
+ bool IsSampleBankLoaded(uint8 nBank);
+
+ bool IsPedCommentLoaded(uint32 nComment);
+ bool LoadPedComment (uint32 nComment);
+
+ int32 _GetPedCommentSlot(uint32 nComment);
+
+ int32 GetSampleBaseFrequency (uint32 nSample);
+ int32 GetSampleLoopStartOffset(uint32 nSample);
+ int32 GetSampleLoopEndOffset (uint32 nSample);
+ uint32 GetSampleLength (uint32 nSample);
+
+ bool UpdateReverb(void);
+
+ void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
+ bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
+ void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
+ void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
+ void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
+ 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);
+ 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);
+ bool InitialiseSampleBanks(void);
+};
+
+extern cSampleManager SampleManager;
+extern int32 BankStartOffset[MAX_SAMPLEBANKS];
+
+static char StreamedNameTable[][25]=
+{
+ "AUDIO\\HEAD.WAV",
+ "AUDIO\\CLASS.WAV",
+ "AUDIO\\KJAH.WAV",
+ "AUDIO\\RISE.WAV",
+ "AUDIO\\LIPS.WAV",
+ "AUDIO\\GAME.WAV",
+ "AUDIO\\MSX.WAV",
+ "AUDIO\\FLASH.WAV",
+ "AUDIO\\CHAT.WAV",
+ "AUDIO\\HEAD.WAV",
+ "AUDIO\\POLICE.WAV",
+ "AUDIO\\CITY.WAV",
+ "AUDIO\\WATER.WAV",
+ "AUDIO\\COMOPEN.WAV",
+ "AUDIO\\SUBOPEN.WAV",
+ "AUDIO\\JB.MP3",
+ "AUDIO\\BET.MP3",
+ "AUDIO\\L1_LG.MP3",
+ "AUDIO\\L2_DSB.MP3",
+ "AUDIO\\L3_DM.MP3",
+ "AUDIO\\L4_PAP.MP3",
+ "AUDIO\\L5_TFB.MP3",
+ "AUDIO\\J0_DM2.MP3",
+ "AUDIO\\J1_LFL.MP3",
+ "AUDIO\\J2_KCL.MP3",
+ "AUDIO\\J3_VH.MP3",
+ "AUDIO\\J4_ETH.MP3",
+ "AUDIO\\J5_DST.MP3",
+ "AUDIO\\J6_TBJ.MP3",
+ "AUDIO\\T1_TOL.MP3",
+ "AUDIO\\T2_TPU.MP3",
+ "AUDIO\\T3_MAS.MP3",
+ "AUDIO\\T4_TAT.MP3",
+ "AUDIO\\T5_BF.MP3",
+ "AUDIO\\S0_MAS.MP3",
+ "AUDIO\\S1_PF.MP3",
+ "AUDIO\\S2_CTG.MP3",
+ "AUDIO\\S3_RTC.MP3",
+ "AUDIO\\S5_LRQ.MP3",
+ "AUDIO\\S4_BDBA.MP3",
+ "AUDIO\\S4_BDBB.MP3",
+ "AUDIO\\S2_CTG2.MP3",
+ "AUDIO\\S4_BDBD.MP3",
+ "AUDIO\\S5_LRQB.MP3",
+ "AUDIO\\S5_LRQC.MP3",
+ "AUDIO\\A1_SSO.WAV",
+ "AUDIO\\A2_PP.WAV",
+ "AUDIO\\A3_SS.WAV",
+ "AUDIO\\A4_PDR.WAV",
+ "AUDIO\\A5_K2FT.WAV",
+ "AUDIO\\K1_KBO.MP3",
+ "AUDIO\\K2_GIS.MP3",
+ "AUDIO\\K3_DS.MP3",
+ "AUDIO\\K4_SHI.MP3",
+ "AUDIO\\K5_SD.MP3",
+ "AUDIO\\R0_PDR2.MP3",
+ "AUDIO\\R1_SW.MP3",
+ "AUDIO\\R2_AP.MP3",
+ "AUDIO\\R3_ED.MP3",
+ "AUDIO\\R4_GF.MP3",
+ "AUDIO\\R5_PB.MP3",
+ "AUDIO\\R6_MM.MP3",
+ "AUDIO\\D1_STOG.MP3",
+ "AUDIO\\D2_KK.MP3",
+ "AUDIO\\D3_ADO.MP3",
+ "AUDIO\\D5_ES.MP3",
+ "AUDIO\\D7_MLD.MP3",
+ "AUDIO\\D4_GTA.MP3",
+ "AUDIO\\D4_GTA2.MP3",
+ "AUDIO\\D6_STS.MP3",
+ "AUDIO\\A6_BAIT.WAV",
+ "AUDIO\\A7_ETG.WAV",
+ "AUDIO\\A8_PS.WAV",
+ "AUDIO\\A9_ASD.WAV",
+ "AUDIO\\K4_SHI2.MP3",
+ "AUDIO\\C1_TEX.MP3",
+ "AUDIO\\EL_PH1.MP3",
+ "AUDIO\\EL_PH2.MP3",
+ "AUDIO\\EL_PH3.MP3",
+ "AUDIO\\EL_PH4.MP3",
+ "AUDIO\\YD_PH1.MP3",
+ "AUDIO\\YD_PH2.MP3",
+ "AUDIO\\YD_PH3.MP3",
+ "AUDIO\\YD_PH4.MP3",
+ "AUDIO\\HD_PH1.MP3",
+ "AUDIO\\HD_PH2.MP3",
+ "AUDIO\\HD_PH3.MP3",
+ "AUDIO\\HD_PH4.MP3",
+ "AUDIO\\HD_PH5.MP3",
+ "AUDIO\\MT_PH1.MP3",
+ "AUDIO\\MT_PH2.MP3",
+ "AUDIO\\MT_PH3.MP3",
+ "AUDIO\\MT_PH4.MP3",
+ "AUDIO\\MISCOM.WAV",
+ "AUDIO\\END.MP3",
+ "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"
+};
diff --git a/src/audio/openal/samp_oal.cpp b/src/audio/openal/samp_oal.cpp
new file mode 100644
index 00000000..e8213cd9
--- /dev/null
+++ b/src/audio/openal/samp_oal.cpp
@@ -0,0 +1,1404 @@
+#include <al.h>
+#include <alc.h>
+#include <mpg123_pre.h>
+//#include <mpg123.h>
+#include <time.h>
+#include <io.h>
+#include "samp_oal.h"
+#include "AudioManager.h"
+#include "MusicManager.h"
+#include "Frontend.h"
+#include "Timer.h"
+
+#pragma comment( lib, "libmpg123.lib" )
+#pragma comment( lib, "OpenAL32.lib" )
+
+cSampleManager SampleManager;
+int32 BankStartOffset[MAX_SAMPLEBANKS];
+
+
+///////////////////////////////////////////////////////////////
+class MP3Stream
+{
+public:
+ mpg123_handle *m_pMPG;
+ FILE *m_fpFile;
+ unsigned char *m_pBuf;
+ char m_aFilename[128];
+ size_t m_nBufSize;
+ size_t m_nLengthInBytes;
+ long m_nRate;
+ int m_nBitRate;
+ int m_nChannels;
+ int m_nEncoding;
+ int m_nLength;
+ int m_nBlockSize;
+ int m_nNumBlocks;
+ ALuint m_alSource;
+ ALuint m_alBuffers[5];
+ unsigned char *m_pBlocks;
+ bool m_bIsFree;
+ bool m_bIsOpened;
+ bool m_bIsPaused;
+ int m_nVolume;
+
+ void Initialize(void);
+ bool FillBuffer(ALuint alBuffer);
+ void Update(void);
+ void SetPos(uint32 nPos);
+ int32 FillBuffers();
+ MP3Stream(char *filename, ALuint source, ALuint *buffers);
+ ~MP3Stream() { Delete(); }
+ void Delete();
+
+};
+///////////////////////////////////////////////////////////////
+
+char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
+char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
+
+FILE *fpSampleDescHandle;
+FILE *fpSampleDataHandle;
+bool bSampleBankLoaded [MAX_SAMPLEBANKS];
+int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
+int32 nSampleBankSize [MAX_SAMPLEBANKS];
+int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
+int32 _nSampleDataEndOffset;
+
+int32 nPedSlotSfx [MAX_PEDSFX];
+int32 nPedSlotSfxAddr[MAX_PEDSFX];
+uint8 nCurrentPedSlot;
+
+
+
+uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
+
+///////////////////////////////////////////////////////////////
+ALuint alChannel[MAXCHANNELS+MAX2DCHANNELS];
+ALuint ALStreamSources[MAX_STREAMS];
+ALuint ALStreamBuffers[MAX_STREAMS][5];
+struct
+{
+ ALuint buffer;
+ ALuint timer;
+}ALBuffers[SAMPLEBANK_MAX];
+
+ALuint pedBuffers[MAX_PEDSFX];
+//bank0Buffers
+
+uint32 nNumMP3s;
+
+MP3Stream *mp3Stream[MAX_STREAMS];
+int8 nStreamPan [MAX_STREAMS];
+int8 nStreamVolume[MAX_STREAMS];
+
+float ChannelPitch[MAXCHANNELS+MAX2DCHANNELS];
+uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+uint32 ChannelSample[MAXCHANNELS+MAX2DCHANNELS];
+int32 currentChannelMaxFrontDistance[MAXCHANNELS+MAX2DCHANNELS];
+int32 currentChannelFrequency[MAXCHANNELS+MAX2DCHANNELS];
+int32 currentChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+
+
+cSampleManager::cSampleManager(void)
+{
+ ;
+}
+
+cSampleManager::~cSampleManager(void)
+{
+ ASSERT((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED] == NULL);
+ free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
+
+ if ( fpSampleDescHandle != NULL )
+ {
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+ }
+
+ if ( fpSampleDataHandle != NULL )
+ {
+ fclose(fpSampleDataHandle);
+ fpSampleDataHandle = NULL;
+ }
+}
+
+void cSampleManager::SetSpeakerConfig(int32 nConfig)
+{
+
+}
+
+uint32 cSampleManager::GetMaximumSupportedChannels(void)
+{
+ return 20;
+}
+
+uint32 cSampleManager::GetNum3DProvidersAvailable()
+{
+ return 1;
+}
+
+void cSampleManager::SetNum3DProvidersAvailable(uint32 num)
+{
+ ;
+}
+
+char *cSampleManager::Get3DProviderName(uint8 id)
+{
+ static char PROVIDER[256] = "OpenAL";
+ return PROVIDER;
+}
+
+void cSampleManager::Set3DProviderName(uint8 id, char *name)
+{
+ ;
+}
+
+int8 cSampleManager::GetCurrent3DProviderIndex(void)
+{
+ return 0;
+}
+
+int8 cSampleManager::SetCurrent3DProvider(uint8 which)
+{
+ return 0;
+}
+
+bool
+cSampleManager::IsMP3RadioChannelAvailable(void)
+{
+ return nNumMP3s != 0;
+}
+
+
+void cSampleManager::ReleaseDigitalHandle(void)
+{
+
+}
+
+void cSampleManager::ReacquireDigitalHandle(void)
+{
+
+}
+
+bool
+cSampleManager::Initialise(void)
+{
+ ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
+
+ m_pDevice = alcOpenDevice(NULL);
+ ASSERT(m_pDevice != NULL);
+
+ m_pContext = alcCreateContext(m_pDevice, attr);
+ ASSERT(m_pContext != NULL);
+
+ alcMakeContextCurrent(m_pContext);
+
+ mpg123_init();
+
+
+
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ m_aSamples[i].nOffset = 0;
+ m_aSamples[i].nSize = 0;
+ m_aSamples[i].nFrequency = MAX_FREQ;
+ m_aSamples[i].nLoopStart = 0;
+ m_aSamples[i].nLoopEnd = -1;
+ }
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ nStreamLength[i] = 3600000;
+
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ mp3Stream[i] = NULL;
+ nStreamVolume[i] = 100;
+ nStreamPan[i] = 63;
+ }
+
+ alGenSources(MAX_STREAMS, (ALuint *)ALStreamSources);
+ alGenBuffers(MAX_STREAMS*5, (ALuint *)ALStreamBuffers);
+
+ m_nMonoMode = 0;
+
+ m_nEffectsVolume = MAX_VOLUME;
+ m_nMusicVolume = MAX_VOLUME;
+ m_nEffectsFadeVolume = MAX_VOLUME;
+ m_nMusicFadeVolume = MAX_VOLUME;
+
+
+ memset(alChannel, 0, sizeof(alChannel));
+ memset(nChannelVolume, 0, sizeof(nChannelVolume));
+ memset(ChannelSample, 0, sizeof(ChannelSample));
+
+ for ( int32 i = 0; i < ARRAY_SIZE(ChannelPitch); i++ )
+ ChannelPitch[i] = 1.0f;
+
+
+ fpSampleDescHandle = NULL;
+ fpSampleDataHandle = NULL;
+
+ for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
+ {
+ bSampleBankLoaded[i] = false;
+ nSampleBankDiscStartOffset[i] = 0;
+ nSampleBankSize[i] = 0;
+ nSampleBankMemoryStartAddress[i] = 0;
+ }
+
+ alGenBuffers(MAX_PEDSFX, pedBuffers);
+
+ for ( int32 i = 0; i < MAX_PEDSFX; i++ )
+ {
+ nPedSlotSfx[i] = NO_SAMPLE;
+ nPedSlotSfxAddr[i] = 0;
+ }
+
+ nCurrentPedSlot = 0;
+
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ ALBuffers[i].buffer = 0;
+ ALBuffers[i].timer = 0;
+ }
+
+ alListenerf (AL_GAIN, 1.0f);
+ alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
+ ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
+ alListenerfv(AL_ORIENTATION, orientation);
+
+ if ( !InitialiseSampleBanks() )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
+
+ if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
+ {
+ Terminate();
+ return false;
+ }
+
+ nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
+ ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
+
+ alGenSources(MAXCHANNELS, alChannel);
+ for ( int32 i = 0; i < MAXCHANNELS; i++ )
+ {
+ if ( alChannel[i] )
+ alSourcei(alChannel[i], AL_SOURCE_RELATIVE, AL_TRUE);
+ }
+
+ alGenSources(MAX2DCHANNELS, &alChannel[CHANNEL2D]);
+ if ( alChannel[CHANNEL2D] )
+ {
+ alSourcei (alChannel[CHANNEL2D], AL_SOURCE_RELATIVE, AL_TRUE);
+ alSource3f(alChannel[CHANNEL2D], AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alSourcef (alChannel[CHANNEL2D], AL_GAIN, 1.0f);
+ }
+
+ LoadSampleBank(SAMPLEBANK_MAIN);
+
+ return true;
+}
+
+void
+cSampleManager::Terminate(void)
+{
+ mpg123_exit();
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(m_pContext);
+ alcCloseDevice(m_pDevice);
+}
+
+void
+cSampleManager::UpdateSoundBuffers(void)
+{
+ for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+ {
+ if ( ALBuffers[i].timer > 0 )
+ {
+ ALBuffers[i].timer -= ALuint(CTimer::GetTimeStep() * 20.0f);
+
+ if ( ALBuffers[i].timer <= 0 )
+ {
+ if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) )
+ {
+ alDeleteBuffers(1, &ALBuffers[i].buffer);
+
+ if ( alGetError() == AL_NO_ERROR )
+ ALBuffers[i].buffer = 0;
+ else
+ ALBuffers[i].buffer = 120000;
+ }
+ }
+ }
+ }
+}
+
+bool cSampleManager::CheckForAnAudioFileOnCD(void)
+{
+ return true;
+}
+
+char cSampleManager::GetCDAudioDriveLetter(void)
+{
+ return '\0';
+}
+
+void
+cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
+{
+ m_nEffectsVolume = nVolume;
+}
+
+void
+cSampleManager::SetMusicMasterVolume(uint8 nVolume)
+{
+ m_nMusicVolume = nVolume;
+}
+
+void
+cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
+{
+ m_nEffectsFadeVolume = nVolume;
+}
+
+void
+cSampleManager::SetMusicFadeVolume(uint8 nVolume)
+{
+ m_nMusicFadeVolume = nVolume;
+}
+
+void
+cSampleManager::SetMonoMode(uint8 nMode)
+{
+ m_nMonoMode = nMode;
+}
+
+bool
+cSampleManager::LoadSampleBank(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ if ( MusicManager.IsInitialised()
+ && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && nBank != SAMPLEBANK_MAIN )
+ {
+ return false;
+ }
+
+ if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] )
+ return false;
+
+ bSampleBankLoaded[nBank] = true;
+
+ return true;
+}
+
+void
+cSampleManager::UnloadSampleBank(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+
+ ; // NOIMP
+}
+
+bool
+cSampleManager::IsSampleBankLoaded(uint8 nBank)
+{
+ ASSERT( nBank < MAX_SAMPLEBANKS );
+ return true;
+}
+
+bool
+cSampleManager::IsPedCommentLoaded(uint32 nComment)
+{
+ ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+
+ uint8 slot;
+
+ for ( int32 i = 0; i < _TODOCONST(3); i++ )
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if ( nComment == nPedSlotSfx[slot] )
+ return true;
+ }
+
+ return false;
+}
+
+
+int32
+cSampleManager::_GetPedCommentSlot(uint32 nComment)
+{
+ uint8 slot;
+
+ for (int32 i = 0; i < _TODOCONST(3); i++)
+ {
+ slot = nCurrentPedSlot - i - 1;
+ if (nComment == nPedSlotSfx[slot])
+ return slot;
+ }
+
+ return -1;
+}
+
+bool
+cSampleManager::LoadPedComment(uint32 nComment)
+{
+ ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+
+ if ( CTimer::GetIsCodePaused() )
+ return false;
+
+ // no talking peds during cutsenes or the game end
+ if ( MusicManager.IsInitialised() )
+ {
+ switch ( MusicManager.GetMusicMode() )
+ {
+ case MUSICMODE_CUTSCENE:
+ {
+ return false;
+
+ break;
+ }
+
+ case MUSICMODE_FRONTEND:
+ {
+ if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
+ return false;
+
+ break;
+ }
+ }
+ }
+
+ if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
+ return false;
+
+ if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
+ return false;
+
+ nPedSlotSfx[nCurrentPedSlot] = nComment;
+
+ alBufferData(pedBuffers[nCurrentPedSlot],
+ AL_FORMAT_MONO16,
+ (void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot),
+ m_aSamples[nComment].nSize,
+ MAX_FREQ);
+
+ if ( ++nCurrentPedSlot >= MAX_PEDSFX )
+ nCurrentPedSlot = 0;
+
+ return true;
+}
+
+int32
+cSampleManager::GetBankContainingSound(uint32 offset)
+{
+ if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
+ return SAMPLEBANK_PED;
+
+ if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
+ return SAMPLEBANK_MAIN;
+
+ return SAMPLEBANK_INVALID;
+}
+
+int32
+cSampleManager::GetSampleBaseFrequency(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nFrequency;
+}
+
+int32
+cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nLoopStart;
+}
+
+int32
+cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nLoopEnd;
+}
+
+uint32
+cSampleManager::GetSampleLength(uint32 nSample)
+{
+ ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+ return m_aSamples[nSample].nSize >> 1;
+}
+
+bool cSampleManager::UpdateReverb(void)
+{
+ return false;
+}
+
+void
+cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
+{
+ ; // NOIMP
+}
+
+bool
+cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ ALuint buffer;
+
+ if ( nSfx < SAMPLEBANK_MAX )
+ {
+ int32 offset = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nOffset - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nOffset;
+ int32 size = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nLoopEnd - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nSize;
+
+ void *data = malloc(size);
+ ASSERT(data != NULL);
+
+ if ( fseek(fpSampleDataHandle, offset + nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+ {
+ free(data);
+ return false;
+ }
+
+ if ( fread(data, 1, size, fpSampleDataHandle) != size )
+ {
+ free(data);
+ return false;
+ }
+
+ ALuint buf;
+ alGenBuffers(1, &buf);
+ alBufferData(buf, AL_FORMAT_MONO16, data, size, MAX_FREQ);
+ free(data);
+
+ if ( !IsSampleBankLoaded(nBank) )
+ return false;
+
+ ALBuffers[nSfx].buffer = buf;
+ ALBuffers[nSfx].timer = 120000;
+
+ buffer = ALBuffers[nSfx].buffer;
+
+ ChannelSample[nChannel] = nSfx;
+ }
+ else
+ {
+ if ( !IsPedCommentLoaded(nSfx) )
+ return false;
+
+ int32 slot = _GetPedCommentSlot(nSfx);
+
+ buffer = pedBuffers[slot];
+ }
+
+ if ( buffer == 0 )
+ {
+ TRACE("No buffer to play id %d", nSfx);
+ return false;
+ }
+
+ if ( GetChannelUsedFlag(nChannel) )
+ {
+ TRACE("Stopping channel %d - really!!!", nChannel);
+ StopChannel(nChannel);
+ }
+
+ alSourcei(alChannel[nChannel], AL_BUFFER, 0);
+ currentChannelVolume [nChannel] = -1;
+ currentChannelFrequency [nChannel] = -1;
+ currentChannelMaxFrontDistance[nChannel] = -1;
+
+ if ( alChannel[nChannel] )
+ {
+ alSourcei(alChannel[nChannel], AL_BUFFER, buffer);
+ alSourcef(alChannel[nChannel], AL_PITCH, 1.0f);
+ ChannelPitch[nChannel] = 1.0f;
+ return true;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // reduce the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
+ if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_REV_10 >= ChannelSample[nChannel] ) // nice hack
+ channelVol >>= 1;
+
+ if ( alChannel[nChannel] )
+ {
+ if ( currentChannelVolume[nChannel] != channelVol )
+ {
+ ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
+ alSourcef(alChannel[nChannel], AL_GAIN, gain);
+ currentChannelVolume[nChannel] = channelVol;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ alSource3f(alChannel[nChannel], AL_POSITION, -fX, fY, fZ);
+ }
+}
+
+void
+cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ if ( float(currentChannelMaxFrontDistance[nChannel]) != fMax )
+ {
+ alSourcef(alChannel[nChannel], AL_MAX_DISTANCE, fMax);
+ alSourcef(alChannel[nChannel], AL_REFERENCE_DISTANCE, 5.0f);
+ alSourcef(alChannel[nChannel], AL_MAX_GAIN, 1.0f);
+ currentChannelMaxFrontDistance[nChannel] = int32(fMax);
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( nChannel == CHANNEL2D )
+ {
+ uint32 vol = nVolume;
+ if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+
+ nChannelVolume[nChannel] = vol;
+
+ // increase the volume for JB.MP3 and S4_BDBD.MP3
+ if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ {
+ nChannelVolume[nChannel] >>= 2;
+ }
+
+ uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
+ if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_IDLE_10 >= ChannelSample[nChannel] ) // nice hack
+ channelVol >>= 1;
+
+ if ( alChannel[nChannel] )
+ {
+ if ( currentChannelVolume[nChannel] != channelVol )
+ {
+ ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
+ alSourcef(alChannel[nChannel], AL_GAIN, gain);
+ currentChannelVolume[nChannel] = channelVol;
+ }
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+ ; // NOIMP
+}
+
+void
+cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ if ( currentChannelFrequency[nChannel] != nFreq )
+ {
+ ALfloat pitch = ALfloat(nFreq) / MAX_FREQ;
+ alSourcef(alChannel[nChannel], AL_PITCH, pitch);
+ currentChannelFrequency[nChannel] = nFreq;
+
+ if ( Abs(1.0f - pitch) < 0.01f )
+ ChannelPitch[nChannel] = 1.0f;
+ else
+ ChannelPitch[nChannel] = pitch;
+ }
+ }
+}
+
+void
+cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ ; // NOIMP
+}
+
+void
+cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( nLoopCount != 0 )
+ alSourcei(alChannel[nChannel], AL_LOOPING, AL_FALSE);
+ else
+ alSourcei(alChannel[nChannel], AL_LOOPING, AL_TRUE);
+}
+
+bool
+cSampleManager::GetChannelUsedFlag(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ ALint sourceState;
+ alGetSourcei(alChannel[nChannel], AL_SOURCE_STATE, &sourceState);
+ return sourceState == AL_PLAYING;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StartChannel(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ if ( ChannelSample[nChannel] > SAMPLEBANK_END ) // PED's Bank
+ {
+ if ( ChannelPitch[nChannel] != 1.0f )
+ ChannelPitch[nChannel] = 1.0f;
+ }
+
+ alSourcef (alChannel[nChannel], AL_PITCH, ChannelPitch[nChannel]);
+ alSourcePlay(alChannel[nChannel]);
+ }
+}
+
+void
+cSampleManager::StopChannel(uint32 nChannel)
+{
+ ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+
+ if ( alChannel[nChannel] )
+ {
+ alSourceStop(alChannel[nChannel]);
+
+ currentChannelVolume [nChannel] = -1;
+ currentChannelFrequency [nChannel] = -1;
+ currentChannelMaxFrontDistance[nChannel] = -1;
+ ChannelPitch [nChannel] = 1.0f;
+ }
+}
+
+void
+cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+{
+ char filename[256];
+
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ delete mp3Stream[nStream];
+ mp3Stream[nStream] = NULL;
+ }
+
+ strcpy(filename, StreamedNameTable[nFile]);
+
+ MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+ ASSERT(stream != NULL);
+
+ mp3Stream[nStream] = stream;
+
+ if ( stream->m_bIsOpened )
+ {
+ ;
+ }
+ else
+ {
+ delete stream;
+ mp3Stream[nStream] = NULL;
+ }
+ }
+}
+
+void
+cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ if ( nPauseFlag != 0 )
+ {
+ if ( !stream->m_bIsPaused )
+ {
+ alSourcePause(stream->m_alSource);
+ stream->m_bIsPaused = true;
+ }
+ }
+ else
+ {
+ if ( stream->m_bIsPaused )
+ {
+ alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(stream->m_alSource);
+ stream->m_bIsPaused = false;
+ }
+ }
+ }
+}
+
+void
+cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ stream->Initialize();
+ if ( stream->m_bIsOpened )
+ {
+ //NOTE: set pos here on mobile
+
+ if ( stream->FillBuffers() != 0 )
+ {
+ alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(stream->m_alSource);
+ stream->m_bIsFree = false;
+ }
+ }
+ }
+}
+
+bool
+cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+{
+ char filename[256];
+
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nFile < TOTAL_STREAMED_SOUNDS )
+ {
+ if ( mp3Stream[nStream] )
+ {
+ delete mp3Stream[nStream];
+ mp3Stream[nStream] = NULL;
+ }
+
+ strcpy(filename, StreamedNameTable[nFile]);
+
+ MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+ ASSERT(stream != NULL);
+
+ mp3Stream[nStream] = stream;
+
+ if ( stream->m_bIsOpened )
+ {
+ stream->Initialize();
+ nStreamLength[nFile] = stream->m_nLength;
+ //MusicManager.SetTrackInfoLength(nFile, stream->m_nLength);
+
+ if ( stream->m_bIsOpened )
+ {
+ if ( nPos != 0 )
+ {
+ stream->SetPos(nPos);
+ }
+
+ if ( stream->FillBuffers() != 0 )
+ {
+ alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(stream->m_alSource);
+ stream->m_bIsFree = false;
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ delete stream;
+ mp3Stream[nStream] = NULL;
+ }
+ }
+
+ return false;
+}
+
+void
+cSampleManager::StopStreamedFile(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ delete stream;
+ mp3Stream[nStream] = NULL;
+ }
+}
+
+int32
+cSampleManager::GetStreamedFilePosition(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ return (ftell(stream->m_fpFile) * 8) / stream->m_nBitRate;
+ }
+
+ return 0;
+}
+
+void
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ if ( nVolume > MAX_VOLUME )
+ nVolume = MAX_VOLUME;
+
+ if ( nPan > MAX_VOLUME )
+ nPan = MAX_VOLUME;
+
+ nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume;
+ nStreamPan [nStream] = nPan;
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream )
+ {
+ uint32 vol;
+ if ( nEffectFlag )
+ vol = m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14;
+ else
+ vol = m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14;
+
+ if ( stream->m_nVolume != vol )
+ {
+ if ( stream->m_bIsOpened )
+ {
+ ALuint source = stream->m_alSource;
+ if ( source )
+ {
+ ALfloat gain = ALfloat(vol) / MAX_VOLUME;
+ alSourcef(source, AL_GAIN, gain);
+ stream = mp3Stream[nStream];
+ }
+ }
+
+ stream->m_nVolume = vol;
+ }
+ }
+}
+
+int32
+cSampleManager::GetStreamedFileLength(uint8 nStream)
+{
+ ASSERT( nStream < TOTAL_STREAMED_SOUNDS );
+
+ return nStreamLength[nStream];
+}
+
+bool
+cSampleManager::IsStreamPlaying(uint8 nStream)
+{
+ ASSERT( nStream < MAX_STREAMS );
+
+ MP3Stream *stream = mp3Stream[nStream];
+
+ if ( stream && stream->m_bIsOpened && !stream->m_bIsPaused )
+ {
+ ALint sourceState;
+ alGetSourcei(stream->m_alSource, AL_SOURCE_STATE, &sourceState);
+ if ( !stream->m_bIsFree || sourceState == AL_PLAYING )
+ return true;
+ }
+
+ return false;
+}
+
+void
+cSampleManager::Service(void)
+{
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ if ( mp3Stream[i] )
+ mp3Stream[i]->Update();
+ }
+
+ UpdateSoundBuffers();
+}
+
+bool
+cSampleManager::InitialiseSampleBanks(void)
+{
+ int32 nBank = SAMPLEBANK_MAIN;
+
+ fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
+ if ( fpSampleDescHandle == NULL )
+ return false;
+
+ fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
+ if ( fpSampleDataHandle == NULL )
+ {
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ return false;
+ }
+
+ fseek(fpSampleDataHandle, 0, SEEK_END);
+ int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle);
+ rewind(fpSampleDataHandle);
+
+ fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
+
+ fclose(fpSampleDescHandle);
+ fpSampleDescHandle = NULL;
+
+ for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+ {
+ if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
+ {
+ nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
+ nBank++;
+ }
+ }
+
+ nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
+ nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
+
+ return true;
+}
+
+/*
+sub_1D8D40
+PreloadSoundBank(tSample *,uchar)
+CheckOpenALChannels(void)
+*/
+
+void MP3Stream::Initialize(void)
+{
+ if ( !m_bIsOpened )
+ return;
+
+ mpg123_format_none(m_pMPG);
+
+ mpg123_format(m_pMPG, 11000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+ mpg123_format(m_pMPG, 24000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+ mpg123_format(m_pMPG, 32000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+ mpg123_format(m_pMPG, 44100, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
+
+ if ( mpg123_open_feed(m_pMPG) != MPG123_OK )
+ return;
+
+ const uint32 CHUNK_SIZE = 1024*5;
+
+ if ( fread(m_pBuf, 1, CHUNK_SIZE, m_fpFile) != CHUNK_SIZE )
+ {
+ Delete();
+ return;
+ }
+
+ m_nBufSize -= CHUNK_SIZE;
+
+ mpg123_feed(m_pMPG, m_pBuf, CHUNK_SIZE);
+
+ if ( mpg123_getformat(m_pMPG, &m_nRate, &m_nChannels, &m_nEncoding) != MPG123_OK )
+ {
+ Delete();
+ return;
+ }
+
+ mpg123_frameinfo info;
+ if ( mpg123_info(m_pMPG, &info) != MPG123_OK )
+ {
+ Delete();
+ return;
+ }
+
+ m_nBitRate = info.bitrate;
+ m_nLength = 8 * m_nLengthInBytes / info.bitrate;
+ m_nBlockSize = mpg123_outblock(m_pMPG);
+ m_nNumBlocks = 5;
+ m_pBlocks = (unsigned char *)malloc(m_nNumBlocks * m_nBlockSize);
+}
+
+bool MP3Stream::FillBuffer(ALuint alBuffer)
+{
+ size_t done;
+
+ uint8 *pBlockBuff = (uint8 *)m_pBlocks;
+
+ bool fail = !(m_nBufSize > 1);
+
+ int err = mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done);
+ if ( alBuffer == 0 )
+ {
+ if ( err == MPG123_OK )
+ {
+ while ( mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done) == MPG123_OK )
+ ;
+ }
+
+ return true;
+ }
+
+ int32 blocks = 0;
+ for ( blocks = 0; blocks < m_nNumBlocks; blocks++ )
+ {
+ if ( err == MPG123_NEED_MORE )
+ {
+ if ( fail )
+ break;
+
+ size_t readSize = m_nBufSize;
+ if ( readSize > 0x4000 )
+ {
+ if ( fread(m_pBuf, 1, 0x4000, m_fpFile) != 0x4000 )
+ {
+ fail = true;
+ TRACE("MP3 ************* : MP3 read unsuccessful mid file, stopping queuing");
+ break;
+ }
+
+ m_nBufSize -= 0x4000;
+ mpg123_feed(m_pMPG, m_pBuf, 0x4000);
+ }
+ else
+ {
+ if ( fread(m_pBuf, 1, readSize, m_fpFile) != readSize )
+ {
+ fail = true;
+ break;
+ }
+
+ m_nBufSize -= readSize;
+ mpg123_feed(m_pMPG, m_pBuf, readSize);
+ }
+ }
+ else if ( err == MPG123_OK )
+ {
+ pBlockBuff += m_nBlockSize;
+ }
+ else
+ {
+ fail = true;
+ break;
+ }
+
+ err = mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done);
+ }
+
+ if ( blocks != 0 )
+ {
+ if ( m_nChannels == 1 )
+ alBufferData(alBuffer, AL_FORMAT_MONO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
+ else
+ alBufferData(alBuffer, AL_FORMAT_STEREO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
+ }
+
+ if ( fail && blocks < m_nNumBlocks )
+ m_bIsFree = true;
+
+ return blocks != 0;
+}
+
+void MP3Stream::Update(void)
+{
+ if ( !m_bIsOpened )
+ return;
+
+ if ( m_bIsFree )
+ return;
+
+ if ( !m_bIsPaused )
+ {
+ ALint sourceState;
+ ALint buffersProcessed = 0;
+
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
+
+ ALint looping = AL_FALSE;
+ alGetSourcei(m_alSource, AL_LOOPING, &looping);
+
+ if ( looping == AL_TRUE )
+ {
+ TRACE("stream set looping");
+ alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
+ }
+
+ while( buffersProcessed-- )
+ {
+ ALuint buffer;
+
+ alSourceUnqueueBuffers(m_alSource, 1, &buffer);
+
+ if ( !m_bIsFree && FillBuffer(buffer) )
+ alSourceQueueBuffers(m_alSource, 1, &buffer);
+ }
+
+ if ( sourceState != AL_PLAYING )
+ {
+ alSourcef(m_alSource, AL_PITCH, 1.0f);
+ alSourcePlay(m_alSource);
+ }
+ }
+}
+
+void MP3Stream::SetPos(uint32 nPos)
+{
+ uint32 pos = nPos;
+ if ( nPos > m_nLength )
+ pos %= m_nLength;
+
+ uint32 blockPos = m_nBitRate * pos / 8;
+ if ( blockPos > m_nLengthInBytes )
+ blockPos %= m_nLengthInBytes;
+
+ fseek(m_fpFile, blockPos, SEEK_SET);
+
+ size_t done;
+ while ( mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done) == MPG123_OK )
+ ;
+}
+
+int32 MP3Stream::FillBuffers()
+{
+ int32 i = 0;
+ for ( i = 0; i < ARRAY_SIZE(m_alBuffers); i++ )
+ {
+ if ( !FillBuffer(m_alBuffers[i]) )
+ break;
+ alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
+ }
+
+ return i;
+}
+
+MP3Stream::MP3Stream(char *filename, ALuint source, ALuint *buffers)
+{
+ strcpy(m_aFilename, filename);
+ memset(m_alBuffers, 0, sizeof(m_alBuffers));
+ m_alSource = source;
+ memcpy(m_alBuffers, buffers, sizeof(m_alBuffers));
+ m_nVolume = -1;
+ m_pBlocks = NULL;
+ m_pBuf = NULL;
+ m_pMPG = NULL;
+ m_bIsPaused = false;
+ m_bIsOpened = true;
+ m_bIsFree = true;
+ m_fpFile = fopen(m_aFilename, "rb");
+
+ if ( m_fpFile )
+ {
+ m_nBufSize = filelength(fileno(m_fpFile));
+ m_nLengthInBytes = m_nBufSize;
+ m_pMPG = mpg123_new(NULL, NULL);
+ m_pBuf = (unsigned char *)malloc(0x4000);
+ }
+ else
+ {
+ m_bIsOpened = false;
+ Delete();
+ }
+}
+
+void MP3Stream::Delete()
+{
+ if ( m_pMPG )
+ {
+ mpg123_delete(m_pMPG);
+ m_pMPG = NULL;
+ }
+
+ if ( m_fpFile )
+ {
+ fclose(m_fpFile);
+ m_fpFile = NULL;
+ }
+
+ if ( m_alSource )
+ {
+ ALint sourceState = AL_STOPPED;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_STOPPED )
+ alSourceStop(m_alSource);
+
+ ALint buffersQueued;
+ alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
+
+ ALuint value;
+ while (buffersQueued--)
+ alSourceUnqueueBuffers(m_alSource, 1, &value);
+
+ m_alSource = 0;
+ }
+
+ if ( m_pBlocks )
+ {
+ free(m_pBlocks);
+ m_pBlocks = NULL;
+ }
+
+ if ( m_pBuf )
+ {
+ free(m_pBuf);
+ m_pBuf = NULL;
+ }
+
+ m_bIsOpened = false;
+} \ No newline at end of file
diff --git a/src/audio/openal/samp_oal.h b/src/audio/openal/samp_oal.h
new file mode 100644
index 00000000..8bbdbcc9
--- /dev/null
+++ b/src/audio/openal/samp_oal.h
@@ -0,0 +1,340 @@
+#pragma once
+#include "common.h"
+#include "AudioSamples.h"
+
+#define MAX_VOLUME 127
+//#define MAX_FREQ 22050
+#define MAX_FREQ 32000
+
+struct tSample {
+ int32 nOffset;
+ uint32 nSize;
+ int32 nFrequency;
+ int32 nLoopStart;
+ int32 nLoopEnd;
+};
+
+enum
+{
+ SAMPLEBANK_MAIN,
+ SAMPLEBANK_PED,
+ MAX_SAMPLEBANKS,
+ SAMPLEBANK_INVALID
+};
+
+#define MAX_PEDSFX 7
+#define PED_BLOCKSIZE 79000
+
+
+//#define MAXCHANNELS 21 android
+#define MAXCHANNELS 28
+#define MAX2DCHANNELS 1
+#define CHANNEL2D MAXCHANNELS
+
+#define MAX_STREAMS 2
+
+struct ALCdevice_struct;
+struct ALCcontext_struct;
+typedef struct ALCdevice_struct ALCdevice;
+typedef struct ALCcontext_struct ALCcontext;
+
+class cSampleManager
+{
+ int field_0;
+ ALCdevice *m_pDevice;
+ ALCcontext *m_pContext;
+
+ uint8 m_nEffectsVolume;
+ uint8 m_nMusicVolume;
+ uint8 m_nEffectsFadeVolume;
+ uint8 m_nMusicFadeVolume;
+ uint8 m_nMonoMode;
+ char _pad0[3];
+ tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+
+public:
+
+
+
+ cSampleManager(void);
+ ~cSampleManager(void);
+
+ void SetSpeakerConfig(int32 nConfig);
+ uint32 GetMaximumSupportedChannels(void);
+
+ uint32 GetNum3DProvidersAvailable();
+ void SetNum3DProvidersAvailable(uint32 num);
+
+ char *Get3DProviderName(uint8 id);
+ void Set3DProviderName(uint8 id, char *name);
+
+ int8 GetCurrent3DProviderIndex(void);
+ int8 SetCurrent3DProvider(uint8 which);
+
+ bool IsMP3RadioChannelAvailable(void);
+
+ void ReleaseDigitalHandle (void);
+ void ReacquireDigitalHandle(void);
+
+ bool Initialise(void);
+ void Terminate (void);
+
+ void UpdateSoundBuffers(void);
+
+ bool CheckForAnAudioFileOnCD(void);
+ char GetCDAudioDriveLetter (void);
+
+ void UpdateEffectsVolume(void);
+
+ void SetEffectsMasterVolume(uint8 nVolume);
+ void SetMusicMasterVolume (uint8 nVolume);
+ void SetEffectsFadeVolume (uint8 nVolume);
+ void SetMusicFadeVolume (uint8 nVolume);
+ void SetMonoMode (uint8 nMode);
+
+ bool LoadSampleBank (uint8 nBank);
+ void UnloadSampleBank (uint8 nBank);
+ bool IsSampleBankLoaded(uint8 nBank);
+
+ bool IsPedCommentLoaded(uint32 nComment);
+ bool LoadPedComment (uint32 nComment);
+ int32 GetBankContainingSound(uint32 offset);
+
+ int32 _GetPedCommentSlot(uint32 nComment);
+
+ int32 GetSampleBaseFrequency (uint32 nSample);
+ int32 GetSampleLoopStartOffset(uint32 nSample);
+ int32 GetSampleLoopEndOffset (uint32 nSample);
+ uint32 GetSampleLength (uint32 nSample);
+
+ bool UpdateReverb(void);
+
+ void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
+ bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
+ void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
+ void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
+ void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
+ 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);
+ 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 Service(void);
+ bool InitialiseSampleBanks(void);
+};
+
+extern cSampleManager SampleManager;
+extern int32 BankStartOffset[MAX_SAMPLEBANKS];
+
+static char StreamedNameTable[][25]=
+{
+ "AUDIO\\HEAD.MP3",
+ "AUDIO\\CLASS.MP3",
+ "AUDIO\\KJAH.MP3",
+ "AUDIO\\RISE.MP3",
+ "AUDIO\\LIPS.MP3",
+ "AUDIO\\GAME.MP3",
+ "AUDIO\\MSX.MP3",
+ "AUDIO\\FLASH.MP3",
+ "AUDIO\\CHAT.MP3",
+ "AUDIO\\HEAD.MP3",
+ "AUDIO\\POLICE.MP3",
+ "AUDIO\\CITY.MP3",
+ "AUDIO\\WATER.MP3",
+ "AUDIO\\COMOPEN.MP3",
+ "AUDIO\\SUBOPEN.MP3",
+ "AUDIO\\JB.MP3",
+ "AUDIO\\BET.MP3",
+ "AUDIO\\L1_LG.MP3",
+ "AUDIO\\L2_DSB.MP3",
+ "AUDIO\\L3_DM.MP3",
+ "AUDIO\\L4_PAP.MP3",
+ "AUDIO\\L5_TFB.MP3",
+ "AUDIO\\J0_DM2.MP3",
+ "AUDIO\\J1_LFL.MP3",
+ "AUDIO\\J2_KCL.MP3",
+ "AUDIO\\J3_VH.MP3",
+ "AUDIO\\J4_ETH.MP3",
+ "AUDIO\\J5_DST.MP3",
+ "AUDIO\\J6_TBJ.MP3",
+ "AUDIO\\T1_TOL.MP3",
+ "AUDIO\\T2_TPU.MP3",
+ "AUDIO\\T3_MAS.MP3",
+ "AUDIO\\T4_TAT.MP3",
+ "AUDIO\\T5_BF.MP3",
+ "AUDIO\\S0_MAS.MP3",
+ "AUDIO\\S1_PF.MP3",
+ "AUDIO\\S2_CTG.MP3",
+ "AUDIO\\S3_RTC.MP3",
+ "AUDIO\\S5_LRQ.MP3",
+ "AUDIO\\S4_BDBA.MP3",
+ "AUDIO\\S4_BDBB.MP3",
+ "AUDIO\\S2_CTG2.MP3",
+ "AUDIO\\S4_BDBD.MP3",
+ "AUDIO\\S5_LRQB.MP3",
+ "AUDIO\\S5_LRQC.MP3",
+ "AUDIO\\A1_SSO.MP3",
+ "AUDIO\\A2_PP.MP3",
+ "AUDIO\\A3_SS.MP3",
+ "AUDIO\\A4_PDR.MP3",
+ "AUDIO\\A5_K2FT.MP3",
+ "AUDIO\\K1_KBO.MP3",
+ "AUDIO\\K2_GIS.MP3",
+ "AUDIO\\K3_DS.MP3",
+ "AUDIO\\K4_SHI.MP3",
+ "AUDIO\\K5_SD.MP3",
+ "AUDIO\\R0_PDR2.MP3",
+ "AUDIO\\R1_SW.MP3",
+ "AUDIO\\R2_AP.MP3",
+ "AUDIO\\R3_ED.MP3",
+ "AUDIO\\R4_GF.MP3",
+ "AUDIO\\R5_PB.MP3",
+ "AUDIO\\R6_MM.MP3",
+ "AUDIO\\D1_STOG.MP3",
+ "AUDIO\\D2_KK.MP3",
+ "AUDIO\\D3_ADO.MP3",
+ "AUDIO\\D5_ES.MP3",
+ "AUDIO\\D7_MLD.MP3",
+ "AUDIO\\D4_GTA.MP3",
+ "AUDIO\\D4_GTA2.MP3",
+ "AUDIO\\D6_STS.MP3",
+ "AUDIO\\A6_BAIT.MP3",
+ "AUDIO\\A7_ETG.MP3",
+ "AUDIO\\A8_PS.MP3",
+ "AUDIO\\A9_ASD.MP3",
+ "AUDIO\\K4_SHI2.MP3",
+ "AUDIO\\C1_TEX.MP3",
+ "AUDIO\\EL_PH1.MP3",
+ "AUDIO\\EL_PH2.MP3",
+ "AUDIO\\EL_PH3.MP3",
+ "AUDIO\\EL_PH4.MP3",
+ "AUDIO\\YD_PH1.MP3",
+ "AUDIO\\YD_PH2.MP3",
+ "AUDIO\\YD_PH3.MP3",
+ "AUDIO\\YD_PH4.MP3",
+ "AUDIO\\HD_PH1.MP3",
+ "AUDIO\\HD_PH2.MP3",
+ "AUDIO\\HD_PH3.MP3",
+ "AUDIO\\HD_PH4.MP3",
+ "AUDIO\\HD_PH5.MP3",
+ "AUDIO\\MT_PH1.MP3",
+ "AUDIO\\MT_PH2.MP3",
+ "AUDIO\\MT_PH3.MP3",
+ "AUDIO\\MT_PH4.MP3",
+ "AUDIO\\MISCOM.MP3",
+ "AUDIO\\END.MP3",
+ "AUDIO\\lib_a1.MP3",
+ "AUDIO\\lib_a2.MP3",
+ "AUDIO\\lib_a.MP3",
+ "AUDIO\\lib_b.MP3",
+ "AUDIO\\lib_c.MP3",
+ "AUDIO\\lib_d.MP3",
+ "AUDIO\\l2_a.MP3",
+ "AUDIO\\j4t_1.MP3",
+ "AUDIO\\j4t_2.MP3",
+ "AUDIO\\j4t_3.MP3",
+ "AUDIO\\j4t_4.MP3",
+ "AUDIO\\j4_a.MP3",
+ "AUDIO\\j4_b.MP3",
+ "AUDIO\\j4_c.MP3",
+ "AUDIO\\j4_d.MP3",
+ "AUDIO\\j4_e.MP3",
+ "AUDIO\\j4_f.MP3",
+ "AUDIO\\j6_1.MP3",
+ "AUDIO\\j6_a.MP3",
+ "AUDIO\\j6_b.MP3",
+ "AUDIO\\j6_c.MP3",
+ "AUDIO\\j6_d.MP3",
+ "AUDIO\\t4_a.MP3",
+ "AUDIO\\s1_a.MP3",
+ "AUDIO\\s1_a1.MP3",
+ "AUDIO\\s1_b.MP3",
+ "AUDIO\\s1_c.MP3",
+ "AUDIO\\s1_c1.MP3",
+ "AUDIO\\s1_d.MP3",
+ "AUDIO\\s1_e.MP3",
+ "AUDIO\\s1_f.MP3",
+ "AUDIO\\s1_g.MP3",
+ "AUDIO\\s1_h.MP3",
+ "AUDIO\\s1_i.MP3",
+ "AUDIO\\s1_j.MP3",
+ "AUDIO\\s1_k.MP3",
+ "AUDIO\\s1_l.MP3",
+ "AUDIO\\s3_a.MP3",
+ "AUDIO\\s3_b.MP3",
+ "AUDIO\\el3_a.MP3",
+ "AUDIO\\mf1_a.MP3",
+ "AUDIO\\mf2_a.MP3",
+ "AUDIO\\mf3_a.MP3",
+ "AUDIO\\mf3_b.MP3",
+ "AUDIO\\mf3_b1.MP3",
+ "AUDIO\\mf3_c.MP3",
+ "AUDIO\\mf4_a.MP3",
+ "AUDIO\\mf4_b.MP3",
+ "AUDIO\\mf4_c.MP3",
+ "AUDIO\\a1_a.MP3",
+ "AUDIO\\a3_a.MP3",
+ "AUDIO\\a5_a.MP3",
+ "AUDIO\\a4_a.MP3",
+ "AUDIO\\a4_b.MP3",
+ "AUDIO\\a4_c.MP3",
+ "AUDIO\\a4_d.MP3",
+ "AUDIO\\k1_a.MP3",
+ "AUDIO\\k3_a.MP3",
+ "AUDIO\\r1_a.MP3",
+ "AUDIO\\r2_a.MP3",
+ "AUDIO\\r2_b.MP3",
+ "AUDIO\\r2_c.MP3",
+ "AUDIO\\r2_d.MP3",
+ "AUDIO\\r2_e.MP3",
+ "AUDIO\\r2_f.MP3",
+ "AUDIO\\r2_g.MP3",
+ "AUDIO\\r2_h.MP3",
+ "AUDIO\\r5_a.MP3",
+ "AUDIO\\r6_a.MP3",
+ "AUDIO\\r6_a1.MP3",
+ "AUDIO\\r6_b.MP3",
+ "AUDIO\\lo2_a.MP3",
+ "AUDIO\\lo6_a.MP3",
+ "AUDIO\\yd2_a.MP3",
+ "AUDIO\\yd2_b.MP3",
+ "AUDIO\\yd2_c.MP3",
+ "AUDIO\\yd2_c1.MP3",
+ "AUDIO\\yd2_d.MP3",
+ "AUDIO\\yd2_e.MP3",
+ "AUDIO\\yd2_f.MP3",
+ "AUDIO\\yd2_g.MP3",
+ "AUDIO\\yd2_h.MP3",
+ "AUDIO\\yd2_ass.MP3",
+ "AUDIO\\yd2_ok.MP3",
+ "AUDIO\\h5_a.MP3",
+ "AUDIO\\h5_b.MP3",
+ "AUDIO\\h5_c.MP3",
+ "AUDIO\\ammu_a.MP3",
+ "AUDIO\\ammu_b.MP3",
+ "AUDIO\\ammu_c.MP3",
+ "AUDIO\\door_1.MP3",
+ "AUDIO\\door_2.MP3",
+ "AUDIO\\door_3.MP3",
+ "AUDIO\\door_4.MP3",
+ "AUDIO\\door_5.MP3",
+ "AUDIO\\door_6.MP3",
+ "AUDIO\\t3_a.MP3",
+ "AUDIO\\t3_b.MP3",
+ "AUDIO\\t3_c.MP3",
+ "AUDIO\\k1_b.MP3",
+ "AUDIO\\cat1.MP3"
+};
diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp
index a375b847..aa6b67dc 100644
--- a/src/audio/sampman.cpp
+++ b/src/audio/sampman.cpp
@@ -1,2257 +1,7 @@
-#include <windows.h>
-#include <shobjidl.h>
-#include <shlguid.h>
-
-#include <time.h>
-
-#include "eax.h"
-#include "eax-util.h"
-#include "mss.h"
-
-#include "sampman.h"
-#include "AudioManager.h"
-#include "MusicManager.h"
-#include "Frontend.h"
-#include "Timer.h"
-
-
-#pragma comment( lib, "mss32.lib" )
-
-cSampleManager SampleManager;
-int32 BankStartOffset[MAX_SAMPLEBANKS];
-///////////////////////////////////////////////////////////////
-
-char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
-char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
-
-FILE *fpSampleDescHandle;
-FILE *fpSampleDataHandle;
-bool bSampleBankLoaded [MAX_SAMPLEBANKS];
-int32 nSampleBankDiscStartOffset [MAX_SAMPLEBANKS];
-int32 nSampleBankSize [MAX_SAMPLEBANKS];
-int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
-int32 _nSampleDataEndOffset;
-
-int32 nPedSlotSfx [MAX_PEDSFX];
-int32 nPedSlotSfxAddr[MAX_PEDSFX];
-uint8 nCurrentPedSlot;
-
-uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
-
-uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
-
-///////////////////////////////////////////////////////////////
-struct tMP3Entry
-{
- char aFilename[MAX_PATH];
-
- uint32 nTrackLength;
- uint32 nTrackStreamPos;
-
- tMP3Entry *pNext;
- char *pLinkPath;
-};
-
-uint32 nNumMP3s;
-tMP3Entry *_pMP3List;
-char _mp3DirectoryPath[MAX_PATH];
-HSTREAM mp3Stream [MAX_MP3STREAMS];
-int8 nStreamPan [MAX_MP3STREAMS];
-int8 nStreamVolume[MAX_MP3STREAMS];
-uint32 _CurMP3Index;
-int32 _CurMP3Pos;
-bool _bIsMp3Active;
-
-#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
-bool _bUseHDDAudio;
-char _aHDDPath[MAX_PATH];
-#endif
-///////////////////////////////////////////////////////////////
-
-
-bool _bSampmanInitialised = false;
-
-//
-// Miscellaneous globals / defines
-
-// Env Size Diffus Room RoomHF RoomLF DecTm DcHF DcLF Refl RefDel Ref Pan Revb RevDel Rev Pan EchTm EchDp ModTm ModDp AirAbs HFRef LFRef RRlOff FLAGS
-
-EAXLISTENERPROPERTIES StartEAX3 =
- {26, 1.7f, 0.8f, -1000, -1000, -100, 4.42f, 0.14f, 1.00f, 429, 0.014f, 0.00f,0.00f,0.00f, 1023, 0.021f, 0.00f,0.00f,0.00f, 0.250f, 0.000f, 0.250f, 0.000f, -5.0f, 2727.1f, 250.0f, 0.00f, 0x3f };
-
-EAXLISTENERPROPERTIES FinishEAX3 =
- {26, 100.0f, 1.0f, 0, -1000, -2200, 20.0f, 1.39f, 1.00f, 1000, 0.069f, 0.00f,0.00f,0.00f, 400, 0.100f, 0.00f,0.00f,0.00f, 0.250f, 1.000f, 3.982f, 0.000f, -18.0f, 3530.8f, 417.9f, 6.70f, 0x3f };
-
-EAXLISTENERPROPERTIES EAX3Params;
-
-S32 prevprovider=-1;
-S32 curprovider=-1;
-S32 usingEAX=0;
-S32 usingEAX3=0;
-HPROVIDER opened_provider=0;
-H3DSAMPLE opened_samples[MAXCHANNELS] = {0};
-HSAMPLE opened_2dsamples[MAX2DCHANNELS] = {0};
-HDIGDRIVER DIG;
-S32 speaker_type=0;
-
-U32 _maxSamples;
-float _fPrevEaxRatioDestination;
-bool _usingMilesFast2D;
-float _fEffectsLevel;
-
-
-struct
-{
- HPROVIDER id;
- char name[80];
-}providers[MAXPROVIDERS];
-
-typedef struct provider_stuff
-{
- char* name;
- HPROVIDER id;
-} provider_stuff;
-
-
-static int __cdecl comp(const provider_stuff*s1,const provider_stuff*s2)
-{
- return( _stricmp(s1->name,s2->name) );
-}
-
-static void
-add_providers()
-{
- provider_stuff pi[MAXPROVIDERS];
- U32 n,i,j;
-
- SampleManager.SetNum3DProvidersAvailable(0);
-
- HPROENUM next = HPROENUM_FIRST;
-
- n=0;
- while (AIL_enumerate_3D_providers(&next, &pi[n].id, &pi[n].name) && (n<MAXPROVIDERS))
- {
- ++n;
- }
-
- qsort(pi,n,sizeof(pi[0]), (int(__cdecl*)(void const*, void const*))comp);
-
- for(i=0;i<n;i++)
- {
- providers[i].id=pi[i].id;
- strcpy(providers[i].name, pi[i].name);
- SampleManager.Set3DProviderName(i, providers[i].name);
- }
-
- SampleManager.SetNum3DProvidersAvailable(n);
-
- for(j=n;j<MAXPROVIDERS;j++)
- SampleManager.Set3DProviderName(j, NULL);
-}
-
-static void
-release_existing()
-{
- for ( U32 i = 0; i < _maxSamples; i++ )
- {
- if ( opened_samples[i] )
- {
- AIL_release_3D_sample_handle(opened_samples[i]);
- opened_samples[i] = NULL;
- }
- }
-
- if ( opened_provider )
- {
- AIL_close_3D_provider(opened_provider);
- opened_provider = NULL;
- }
-
- _fPrevEaxRatioDestination = 0.0f;
- _usingMilesFast2D = false;
- _fEffectsLevel = 0.0f;
-}
-
-static bool
-set_new_provider(S32 index)
-{
- DWORD result;
-
- if ( curprovider == index )
- return true;
-
- //close the already opened provider
- curprovider = index;
-
- release_existing();
-
- if ( curprovider != -1 )
- {
- if ( !strcmp(providers[index].name, "Dolby Surround") )
- _maxSamples = MAXCHANNELS_SURROUND;
- else
- _maxSamples = MAXCHANNELS;
-
- AIL_set_3D_provider_preference(providers[index].id, "Maximum supported samples", &_maxSamples);
-
- //load the new provider
- result = AIL_open_3D_provider(providers[index].id);
-
- if (result != M3D_NOERR)
- {
- curprovider=-1;
-
- OutputDebugStringA(AIL_last_error());
-
- release_existing();
-
- return false;
- }
- else
- {
- opened_provider=providers[index].id;
-
- //see if we're running under an EAX compatible provider
-
- if ( !strcmp(providers[index].name, "Creative Labs EAX 3 (TM)") )
- {
- usingEAX = 1;
- usingEAX3 = 1;
- }
- else
- {
- usingEAX3 = 0;
-
- result=AIL_3D_room_type(opened_provider);
- usingEAX=(((S32)result)!=-1)?1:0; // will be something other than -1 on EAX
- }
-
- if ( usingEAX3 )
- {
- OutputDebugString("DOING SPECIAL EAX 3 STUFF!");
- AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &FinishEAX3);
- }
- else if ( usingEAX )
- {
- AIL_set_3D_room_type(opened_provider, ENVIRONMENT_CAVE);
-
- if ( !strcmp(providers[index].name, "Miles Fast 2D Positional Audio") )
- _usingMilesFast2D = true;
- }
-
- AIL_3D_provider_attribute(opened_provider, "Maximum supported samples", &_maxSamples);
-
- if ( _maxSamples > MAXCHANNELS )
- _maxSamples = MAXCHANNELS;
-
- SampleManager.SetSpeakerConfig(speaker_type);
-
- //obtain a 3D sample handles
- for ( U32 i = 0; i < _maxSamples; ++i )
- {
- opened_samples[i] = AIL_allocate_3D_sample_handle(opened_provider);
- if ( opened_samples[i] != NULL )
- AIL_set_3D_sample_effects_level(opened_samples[i], 0.0f);
- }
-
- return true;
- }
- }
-
- return false;
-}
-
-void
-cSampleManager::SetSpeakerConfig(int32 which)
-{
- switch ( which )
- {
- case 1:
- speaker_type=AIL_3D_2_SPEAKER;
- break;
-
- case 2:
- speaker_type=AIL_3D_HEADPHONE;
- break;
-
- case 3:
- speaker_type=AIL_3D_4_SPEAKER;
- break;
-
- default:
- return;
- break;
- }
-
- if (opened_provider)
- AIL_set_3D_speaker_type(opened_provider, speaker_type);
-}
-
-uint32
-cSampleManager::GetMaximumSupportedChannels(void)
-{
- if ( _maxSamples > MAXCHANNELS )
- return MAXCHANNELS;
-
- return _maxSamples;
-}
-
-int8
-cSampleManager::GetCurrent3DProviderIndex(void)
-{
- return curprovider;
-}
-
-int8
-cSampleManager::SetCurrent3DProvider(uint8 nProvider)
-{
- S32 savedprovider = curprovider;
-
- if ( nProvider < m_nNumberOfProviders )
- {
- if ( set_new_provider(nProvider) )
- return curprovider;
- else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
- return curprovider;
- else
- return -1;
- }
- else
- return curprovider;
-}
-
-static bool
-_ResolveLink(char const *path, char *out)
-{
- IShellLink* psl;
- WIN32_FIND_DATA fd;
- char filepath[MAX_PATH];
-
- CoInitialize(NULL);
-
- if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl ) ))
- {
- IPersistFile *ppf;
-
- if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
- {
- WCHAR wpath[MAX_PATH];
-
- MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH);
-
- if (SUCCEEDED(ppf->Load(wpath, STGM_READ)))
- {
- /* Resolve the link */
- if (SUCCEEDED(psl->Resolve(NULL, SLR_ANY_MATCH|SLR_NO_UI|SLR_NOSEARCH)))
- {
- strcpy(filepath, path);
-
- if (SUCCEEDED(psl->GetPath(filepath, MAX_PATH, &fd, SLGP_UNCPRIORITY)))
- {
- OutputDebugString(fd.cFileName);
-
- strcpy(out, filepath);
- // FIX: Release the objects. Taken from SA.
-#ifdef FIX_BUGS
- ppf->Release();
- psl->Release();
-#endif
- return true;
- }
- }
- }
-
- ppf->Release();
- }
- psl->Release();
- }
-
- return false;
-}
-
-static void
-_FindMP3s(void)
-{
- tMP3Entry *pList;
- bool bShortcut;
- bool bInitFirstEntry;
- HANDLE hFind;
- char path[MAX_PATH];
- char filepath[MAX_PATH*2];
- S32 total_ms;
- WIN32_FIND_DATA fd;
-
-
- if ( GetCurrentDirectory(MAX_PATH, _mp3DirectoryPath) == 0 )
- {
- GetLastError();
- return;
- }
-
- OutputDebugString("Finding MP3s...");
- strcpy(path, _mp3DirectoryPath);
- strcat(path, "\\MP3\\");
-
- strcpy(_mp3DirectoryPath, path);
- OutputDebugString(_mp3DirectoryPath);
-
- strcat(path, "*");
-
- hFind = FindFirstFile(path, &fd);
-
- if ( hFind == INVALID_HANDLE_VALUE )
- {
- GetLastError();
- return;
- }
-
- strcpy(filepath, _mp3DirectoryPath);
- strcat(filepath, fd.cFileName);
-
- int32 filepathlen = strlen(filepath);
-
- if ( filepathlen <= 0)
- {
- FindClose(hFind);
- return;
- }
-
- FILE *f = fopen("MP3\\MP3Report.txt", "w");
-
- if ( f )
- {
- fprintf(f, "MP3 Report File\n\n");
- fprintf(f, "\"%s\"", fd.cFileName);
- }
-
-
- if ( filepathlen > 4 )
- {
- if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
- {
- if ( _ResolveLink(filepath, filepath) )
- {
- OutputDebugString("Resolving Link");
- OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f ) fprintf(f, " - couldn't resolve shortcut");
- }
-
- bShortcut = true;
- }
- else
- bShortcut = false;
- }
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- OutputDebugString(fd.cFileName);
-
- _pMP3List = new tMP3Entry;
-
- if ( _pMP3List == NULL )
- {
- FindClose(hFind);
-
- if ( f )
- fclose(f);
-
- return;
- }
-
- nNumMP3s = 1;
-
- strcpy(_pMP3List->aFilename, fd.cFileName);
-
- _pMP3List->nTrackLength = total_ms;
-
- _pMP3List->pNext = NULL;
-
- pList = _pMP3List;
-
- if ( bShortcut )
- {
- _pMP3List->pLinkPath = new char[MAX_PATH*2];
- strcpy(_pMP3List->pLinkPath, filepath);
- }
- else
- {
- _pMP3List->pLinkPath = NULL;
- }
-
- if ( f ) fprintf(f, " - OK\n");
-
- bInitFirstEntry = false;
- }
- else
- {
- strcat(filepath, " - NOT A VALID MP3");
-
- OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
-
- bInitFirstEntry = true;
- }
-
- while ( true )
- {
- if ( !FindNextFile(hFind, &fd) )
- break;
-
- if ( bInitFirstEntry )
- {
- strcpy(filepath, _mp3DirectoryPath);
- strcat(filepath, fd.cFileName);
-
- int32 filepathlen = strlen(filepath);
-
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
- if ( filepathlen > 0 )
- {
- if ( filepathlen > 4 )
- {
- if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
- {
- if ( _ResolveLink(filepath, filepath) )
- {
- OutputDebugString("Resolving Link");
- OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f ) fprintf(f, " - couldn't resolve shortcut");
- }
-
- bShortcut = true;
- }
- else
- {
- bShortcut = false;
-
- if ( filepathlen > MAX_PATH )
- {
- if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
-
- continue;
- }
- }
- }
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- OutputDebugString(fd.cFileName);
-
- _pMP3List = new tMP3Entry;
-
- if ( _pMP3List == NULL)
- break;
-
- nNumMP3s = 1;
-
- strcpy(_pMP3List->aFilename, fd.cFileName);
-
- _pMP3List->nTrackLength = total_ms;
- _pMP3List->pNext = NULL;
-
- if ( bShortcut )
- {
- _pMP3List->pLinkPath = new char [MAX_PATH*2];
- strcpy(_pMP3List->pLinkPath, filepath);
- }
- else
- {
- _pMP3List->pLinkPath = NULL;
- }
-
- pList = _pMP3List;
-
- if ( f ) fprintf(f, " - OK\n");
-
- bInitFirstEntry = false;
- }
- else
- {
- strcat(filepath, " - NOT A VALID MP3");
- OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
- }
- }
- }
- else
- {
- strcpy(filepath, _mp3DirectoryPath);
- strcat(filepath, fd.cFileName);
-
- int32 filepathlen = strlen(filepath);
-
- if ( filepathlen > 0 )
- {
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
- if ( filepathlen > 4 )
- {
- if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
- {
- if ( _ResolveLink(filepath, filepath) )
- {
- OutputDebugString("Resolving Link");
- OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - shortcut to \"%s\"", filepath);
- }
- else
- {
- if ( f ) fprintf(f, " - couldn't resolve shortcut");
- }
-
- bShortcut = true;
- }
- else
- {
- bShortcut = false;
- }
- }
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &total_ms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- pList->pNext = new tMP3Entry;
-
- tMP3Entry *e = pList->pNext;
-
- if ( e == NULL )
- break;
-
- pList = pList->pNext;
-
- strcpy(e->aFilename, fd.cFileName);
- e->nTrackLength = total_ms;
- e->pNext = NULL;
-
- if ( bShortcut )
- {
- e->pLinkPath = new char [MAX_PATH*2];
- strcpy(e->pLinkPath, filepath);
- }
- else
- {
- e->pLinkPath = NULL;
- }
-
- nNumMP3s++;
-
- OutputDebugString(fd.cFileName);
-
- if ( f ) fprintf(f, " - OK\n");
- }
- else
- {
- strcat(filepath, " - NOT A VALID MP3");
- OutputDebugString(filepath);
-
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
- }
- }
- }
- }
-
- if ( f )
- {
- fprintf(f, "\nTOTAL SUPPORTED MP3s: %d\n", nNumMP3s);
- fclose(f);
- }
-
- FindClose(hFind);
-}
-
-static void
-_DeleteMP3Entries(void)
-{
- tMP3Entry *e = _pMP3List;
-
- while ( e != NULL )
- {
- tMP3Entry *next = e->pNext;
-
- if ( next == NULL )
- next = NULL;
-
- if ( e->pLinkPath != NULL )
- {
-#ifndef FIX_BUGS
- delete e->pLinkPath; // BUG: should be delete []
+#pragma once
+#include "common.h"
+#ifndef OPENAL
+#include "miles\sampman_mss.cpp"
#else
- delete[] e->pLinkPath;
-#endif
- e->pLinkPath = NULL;
- }
-
- delete e;
-
- if ( next )
- e = next;
- else
- e = NULL;
-
- nNumMP3s--;
- }
-
-
- if ( nNumMP3s != 0 )
- {
- OutputDebugString("Not all MP3 entries were deleted");
- nNumMP3s = 0;
- }
-
- _pMP3List = NULL;
-}
-
-static tMP3Entry *
-_GetMP3EntryByIndex(uint32 idx)
-{
- uint32 n = ( idx < nNumMP3s ) ? idx : 0;
-
- if ( _pMP3List != NULL )
- {
- tMP3Entry *e = _pMP3List;
-
- for ( uint32 i = 0; i < n; i++ )
- e = e->pNext;
-
- return e;
-
- }
-
- return NULL;
-}
-
-static inline bool
-_GetMP3PosFromStreamPos(uint32 *pPosition, tMP3Entry **pEntry)
-{
- _CurMP3Index = 0;
-
- for ( *pEntry = _pMP3List; *pEntry != NULL; *pEntry = (*pEntry)->pNext )
- {
- if ( *pPosition >= (*pEntry)->nTrackStreamPos
- && *pPosition < (*pEntry)->nTrackLength + (*pEntry)->nTrackStreamPos )
- {
- *pPosition -= (*pEntry)->nTrackStreamPos;
- _CurMP3Pos = *pPosition;
-
- return true;
- }
-
- _CurMP3Index++;
- }
-
- *pPosition = 0;
- *pEntry = _pMP3List;
- _CurMP3Pos = 0;
- _CurMP3Index = 0;
-
- return false;
-}
-
-bool
-cSampleManager::IsMP3RadioChannelAvailable(void)
-{
- return nNumMP3s != 0;
-}
-
-void
-cSampleManager::ReleaseDigitalHandle(void)
-{
- if ( DIG )
- {
- prevprovider = curprovider;
- release_existing();
- curprovider = -1;
- AIL_digital_handle_release(DIG);
- }
-}
-
-void
-cSampleManager::ReacquireDigitalHandle(void)
-{
- if ( DIG )
- {
- AIL_digital_handle_reacquire(DIG);
- if ( prevprovider != -1 )
- set_new_provider(prevprovider);
- }
-}
-
-bool
-cSampleManager::Initialise(void)
-{
- TRACE("start");
-
- if ( _bSampmanInitialised )
- return true;
-
- {
- for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
- {
- m_aSamples[i].nOffset = 0;
- m_aSamples[i].nSize = 0;
- m_aSamples[i].nFrequency = 22050;
- m_aSamples[i].nLoopStart = 0;
- m_aSamples[i].nLoopEnd = -1;
- }
-
- m_nEffectsVolume = MAX_VOLUME;
- m_nMusicVolume = MAX_VOLUME;
- m_nEffectsFadeVolume = MAX_VOLUME;
- m_nMusicFadeVolume = MAX_VOLUME;
-
- m_nMonoMode = 0;
- }
-
- // miles
- TRACE("MILES");
- {
- curprovider = -1;
- prevprovider = -1;
-
- _usingMilesFast2D = false;
- usingEAX=0;
- usingEAX3=0;
-
- _fEffectsLevel = 0.0f;
-
- _maxSamples = 0;
-
- opened_provider = NULL;
- DIG = NULL;
-
- for ( int32 i = 0; i < MAXCHANNELS; i++ )
- opened_samples[i] = NULL;
- }
-
- // banks
- TRACE("banks");
- {
- fpSampleDescHandle = NULL;
- fpSampleDataHandle = NULL;
-
- _nSampleDataEndOffset = 0;
-
- for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
- {
- bSampleBankLoaded[i] = false;
- nSampleBankDiscStartOffset[i] = 0;
- nSampleBankSize[i] = 0;
- nSampleBankMemoryStartAddress[i] = 0;
- }
- }
-
- // pedsfx
- TRACE("pedsfx");
- {
- for ( int32 i = 0; i < MAX_PEDSFX; i++ )
- {
- nPedSlotSfx[i] = NO_SAMPLE;
- nPedSlotSfxAddr[i] = 0;
- }
-
- nCurrentPedSlot = 0;
- }
-
- // channel volume
- TRACE("vol");
- {
- for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
- nChannelVolume[i] = 0;
- }
-
- TRACE("mss");
- {
- AIL_set_redist_directory( "mss" );
-
- AIL_startup();
-
- AIL_set_preference(DIG_MIXER_CHANNELS, MAX_DIGITAL_MIXER_CHANNELS);
-
- DIG = AIL_open_digital_driver(DIGITALRATE, DIGITALBITS, DIGITALCHANNELS, 0);
- if ( DIG == NULL )
- {
- OutputDebugString(AIL_last_error());
- Terminate();
- return false;
- }
-
- add_providers();
-
- if ( !InitialiseSampleBanks() )
- {
- Terminate();
- return false;
- }
-
- nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)AIL_mem_alloc_lock(nSampleBankSize[SAMPLEBANK_MAIN]);
- if ( !nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] )
- {
- Terminate();
- return false;
- }
-
- nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)AIL_mem_alloc_lock(PED_BLOCKSIZE*MAX_PEDSFX);
-
- }
-
- TRACE("cdrom");
-
- S32 tatalms;
- char filepath[MAX_PATH];
-
- {
- m_bInitialised = false;
-
- while (true)
- {
- int32 drive = 'C';
-
- do
- {
- char latter[2];
-
- latter[0] = drive;
- latter[1] = '\0';
-
- strcpy(m_szCDRomRootPath, latter);
- strcat(m_szCDRomRootPath, ":\\");
-
- if ( GetDriveType(m_szCDRomRootPath) == DRIVE_CDROM )
- {
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[0]);
-
- FILE *f = fopen(filepath, "rb");
-
- if ( f )
- {
- fclose(f);
-
- bool bFileNotFound = false;
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[i]);
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
-
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- nStreamLength[i] = tatalms;
- }
- else
- {
- bFileNotFound = true;
- break;
- }
- }
-
- if ( !bFileNotFound )
- {
- m_bInitialised = true;
- break;
- }
- else
- {
- m_bInitialised = false;
- continue;
- }
- }
- }
-
- } while ( ++drive <= 'Z' );
-
- if ( !m_bInitialised )
- {
-#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
- FrontEndMenuManager.WaitForUserCD();
- if ( FrontEndMenuManager.m_bQuitGameNoCD )
- {
- Terminate();
- return false;
- }
- continue;
-#else
- m_bInitialised = true;
-#endif
- }
-
- break;
- }
- }
-
-#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
- // hddaudio
- /**
- Option for user to play audio files directly from hard disk.
- Copy the contents of the PLAY discs Audio directory into your installed Grand Theft Auto III Audio directory.
- Grand Theft Auto III still requires the presence of the PLAY disc when started.
- This may give better performance on some machines (though worse on others).
- **/
- TRACE("hddaudio 1.1 patch");
- {
- int32 streamLength[TOTAL_STREAMED_SOUNDS];
-
- bool bFileNotFound = false;
- char rootpath[MAX_PATH];
-
- strcpy(_aHDDPath, m_szCDRomRootPath);
- rootpath[0] = '\0';
-
- FILE *f = fopen(StreamedNameTable[0], "rb");
-
- if ( f )
- {
- fclose(f);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
- strcpy(filepath, rootpath);
- strcat(filepath, StreamedNameTable[i]);
-
- mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
-
- if ( mp3Stream[0] )
- {
- AIL_stream_ms_position(mp3Stream[0], &tatalms, NULL);
-
- AIL_close_stream(mp3Stream[0]);
- mp3Stream[0] = NULL;
-
- streamLength[i] = tatalms;
- }
- else
- {
- bFileNotFound = true;
- break;
- }
- }
-
- }
- else
- bFileNotFound = true;
-
- if ( !bFileNotFound )
- {
- strcpy(m_szCDRomRootPath, rootpath);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- nStreamLength[i] = streamLength[i];
-
- _bUseHDDAudio = true;
- }
- else
- _bUseHDDAudio = false;
- }
-#endif
-
- TRACE("stream");
- {
- for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
- {
- mp3Stream [i] = NULL;
- nStreamPan [i] = 63;
- nStreamVolume[i] = 100;
- }
- }
-
- for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
- {
- opened_2dsamples[i] = AIL_allocate_sample_handle(DIG);
- if ( opened_2dsamples[i] )
- {
- AIL_init_sample(opened_2dsamples[i]);
- AIL_set_sample_type(opened_2dsamples[i], DIG_F_MONO_16, DIG_PCM_SIGN);
- }
- }
-
- TRACE("providerset");
- {
- _bSampmanInitialised = true;
-
- U32 n = 0;
-
- while ( n < m_nNumberOfProviders )
- {
- if ( !strcmp(providers[n].name, "Miles Fast 2D Positional Audio") )
- {
- set_new_provider(n);
- break;
- }
- n++;
- }
-
- if ( n == m_nNumberOfProviders )
- {
- Terminate();
- return false;
- }
- }
-
- TRACE("bank");
-
- LoadSampleBank(SAMPLEBANK_MAIN);
-
- // mp3
- TRACE("mp3");
- {
- nNumMP3s = 0;
-
- _pMP3List = NULL;
-
- _FindMP3s();
-
- if ( nNumMP3s != 0 )
- {
- nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] = 0;
-
- for ( tMP3Entry *e = _pMP3List; e != NULL; e = e->pNext )
- {
- e->nTrackStreamPos = nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER];
- nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] += e->nTrackLength;
- }
-
- time_t t = time(NULL);
- tm *localtm;
- bool bUseRandomTable;
-
- if ( t == -1 )
- bUseRandomTable = true;
- else
- {
- bUseRandomTable = false;
- localtm = localtime(&t);
- }
-
- int32 randval;
- if ( bUseRandomTable )
- randval = AudioManager.GetRandomNumber(1);
- else
- randval = localtm->tm_sec * localtm->tm_min;
-
- _CurMP3Index = randval % nNumMP3s;
-
- tMP3Entry *randmp3 = _pMP3List;
- for ( int32 i = randval % nNumMP3s; i > 0; --i)
- randmp3 = randmp3->pNext;
-
- if ( bUseRandomTable )
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
- else
- {
- if ( localtm->tm_sec > 0 )
- {
- int32 s = localtm->tm_sec;
- _CurMP3Pos = s*s*s*s*s*s*s*s % randmp3->nTrackLength;
- }
- else
- _CurMP3Pos = AudioManager.GetRandomNumber(0) % randmp3->nTrackLength;
- }
- }
- else
- _CurMP3Pos = 0;
-
- _bIsMp3Active = false;
- }
-
- TRACE("end");
-
- return true;
-}
-
-void
-cSampleManager::Terminate(void)
-{
- for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
- {
- if ( mp3Stream[i] )
- {
- AIL_pause_stream(mp3Stream[i], 1);
- AIL_close_stream(mp3Stream[i]);
- mp3Stream[i] = NULL;
- }
- }
-
- for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
- {
- if ( opened_2dsamples[i] )
- {
- AIL_release_sample_handle(opened_2dsamples[i]);
- opened_2dsamples[i] = NULL;
- }
- }
-
- release_existing();
-
- _DeleteMP3Entries();
-
- if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
- {
- AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
- nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
- }
-
- if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
- {
- AIL_mem_free_lock((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
- nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
- }
-
- if ( DIG )
- {
- AIL_close_digital_driver(DIG);
- DIG = NULL;
- }
-
- AIL_shutdown();
-
- _bSampmanInitialised = false;
-}
-
-bool
-cSampleManager::CheckForAnAudioFileOnCD(void)
-{
-#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
- char filepath[MAX_PATH];
-
-#if defined(GTA3_1_1_PATCH)
- if (_bUseHDDAudio)
- strcpy(filepath, _aHDDPath);
- else
- strcpy(filepath, m_szCDRomRootPath);
-#else
- strcpy(filepath, m_szCDRomRootPath);
-#endif // #if defined(GTA3_1_1_PATCH)
-
- strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
-
- FILE *f = fopen(filepath, "rb");
-
- if ( f )
- {
- fclose(f);
-
- return true;
- }
-
- return false;
-
-#else
- return true;
-#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
-}
-
-char
-cSampleManager::GetCDAudioDriveLetter(void)
-{
-#if defined(GTA3_1_1_PATCH) || defined(GTA3_STEAM_PATCH) || defined(NO_CDCHECK)
- if (_bUseHDDAudio)
- {
- if ( strlen(_aHDDPath) != 0 )
- return _aHDDPath[0];
- else
- return '\0';
- }
- else
- {
- if ( strlen(m_szCDRomRootPath) != 0 )
- return m_szCDRomRootPath[0];
- else
- return '\0';
- }
-#else
- if ( strlen(m_szCDRomRootPath) != 0 )
- return m_szCDRomRootPath[0];
- else
- return '\0';
-#endif
-}
-
-void
-cSampleManager::UpdateEffectsVolume(void) //[Y], cSampleManager::UpdateSoundBuffers ?
-{
- if ( _bSampmanInitialised )
- {
- for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
- {
- if ( i < MAXCHANNELS )
- {
- if ( opened_samples[i] && GetChannelUsedFlag(i) )
- {
- if ( nChannelVolume[i] )
- {
- AIL_set_3D_sample_volume(opened_samples[i],
- m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14);
- }
- }
- }
- else
- {
- if ( opened_2dsamples[i - MAXCHANNELS] )
- {
- if ( GetChannelUsedFlag(i - MAXCHANNELS) )
- {
- if ( nChannelVolume[i - MAXCHANNELS] )
- {
- AIL_set_sample_volume(opened_2dsamples[i - MAXCHANNELS],
- m_nEffectsFadeVolume * nChannelVolume[i - MAXCHANNELS] * m_nEffectsVolume >> 14);
- }
- }
- }
- }
- }
- }
-}
-
-void
-cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
-{
- m_nEffectsVolume = nVolume;
- UpdateEffectsVolume();
-}
-
-void
-cSampleManager::SetMusicMasterVolume(uint8 nVolume)
-{
- m_nMusicVolume = nVolume;
-}
-
-void
-cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
-{
- m_nEffectsFadeVolume = nVolume;
- UpdateEffectsVolume();
-}
-
-void
-cSampleManager::SetMusicFadeVolume(uint8 nVolume)
-{
- m_nMusicFadeVolume = nVolume;
-}
-
-bool
-cSampleManager::LoadSampleBank(uint8 nBank)
-{
- if ( CTimer::GetIsCodePaused() )
- return false;
-
- if ( MusicManager.IsInitialised()
- && MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && nBank != SAMPLEBANK_MAIN )
- {
- return false;
- }
-
- if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
- return false;
-
- if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank],fpSampleDataHandle) != nSampleBankSize[nBank] )
- return false;
-
- bSampleBankLoaded[nBank] = true;
-
- return true;
-}
-
-void
-cSampleManager::UnloadSampleBank(uint8 nBank)
-{
- bSampleBankLoaded[nBank] = false;
-}
-
-bool
-cSampleManager::IsSampleBankLoaded(uint8 nBank)
-{
- return bSampleBankLoaded[nBank];
-}
-
-bool
-cSampleManager::IsPedCommentLoaded(uint32 nComment)
-{
- uint8 slot;
-
- for ( int32 i = 0; i < _TODOCONST(3); i++ )
- {
- slot = nCurrentPedSlot - i - 1;
- if ( nComment == nPedSlotSfx[slot] )
- return true;
- }
-
- return false;
-}
-
-int32
-cSampleManager::_GetPedCommentSlot(uint32 nComment)
-{
- uint8 slot;
-
- for ( int32 i = 0; i < _TODOCONST(3); i++ )
- {
- slot = nCurrentPedSlot - i - 1;
- if ( nComment == nPedSlotSfx[slot] )
- return slot;
- }
-
- return -1;
-}
-
-bool
-cSampleManager::LoadPedComment(uint32 nComment)
-{
- if ( CTimer::GetIsCodePaused() )
- return false;
-
- // no talking peds during cutsenes or the game end
- if ( MusicManager.IsInitialised() )
- {
- switch ( MusicManager.GetMusicMode() )
- {
- case MUSICMODE_CUTSCENE:
- {
- return false;
-
- break;
- }
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return false;
-
- break;
- }
- }
- }
-
- if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
- return false;
-
- if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
- return false;
-
- nPedSlotSfxAddr[nCurrentPedSlot] = nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot;
- nPedSlotSfx [nCurrentPedSlot] = nComment;
-
- if ( ++nCurrentPedSlot >= MAX_PEDSFX )
- nCurrentPedSlot = 0;
-
- return true;
-}
-
-int32
-cSampleManager::GetSampleBaseFrequency(uint32 nSample)
-{
- return m_aSamples[nSample].nFrequency;
-}
-
-int32
-cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
-{
- return m_aSamples[nSample].nLoopStart;
-}
-
-int32
-cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
-{
- return m_aSamples[nSample].nLoopEnd;
-}
-
-uint32
-cSampleManager::GetSampleLength(uint32 nSample)
-{
- return m_aSamples[nSample].nSize >> 1;
-}
-
-bool
-cSampleManager::UpdateReverb(void)
-{
- if ( !usingEAX )
- return false;
-
- if ( AudioManager.GetFrameCounter() & 15 )
- return false;
-
- float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
- float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
- float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
-
- float normy = norm(y, 5.0f, 40.0f);
- float normx = norm(x, 5.0f, 40.0f);
- float normz = norm(z, 5.0f, 40.0f);
-
- float fRatio;
-
- if ( normy == 0.0f )
- {
- if ( normx == 0.0f )
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = 0.5f;
- }
- else
- {
- fRatio = 0.3f;
- }
- }
- else
- {
- if ( normx == 0.0f )
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = 0.5f;
- }
- else
- {
- if ( normz == 0.0f )
- fRatio = 0.3f;
- else
- fRatio = (normy+normx+normz) / 3.0f;
- }
- }
-
- fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
-
- if ( fRatio == _fPrevEaxRatioDestination )
- return false;
-
- if ( usingEAX3 )
- {
- if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
- {
- AIL_set_3D_provider_preference(opened_provider, "EAX all parameters", &EAX3Params);
- _fEffectsLevel = 1.0f - fRatio * 0.5f;
- }
- }
- else
- {
- if ( _usingMilesFast2D )
- _fEffectsLevel = (1.0f - fRatio) * 0.4f;
- else
- _fEffectsLevel = (1.0f - fRatio) * 0.7f;
- }
-
- _fPrevEaxRatioDestination = fRatio;
-
- return true;
-}
-
-void
-cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( usingEAX )
- {
- if ( nReverbFlag != 0 )
- {
- if ( !b2d )
- AIL_set_3D_sample_effects_level(opened_samples[nChannel], _fEffectsLevel);
- }
- else
- {
- if ( !b2d )
- AIL_set_3D_sample_effects_level(opened_samples[nChannel], 0.0f);
- }
- }
-}
-
-bool
-cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- int32 addr;
-
- if ( nSfx < SAMPLEBANK_MAX )
- {
- if ( !IsSampleBankLoaded(nBank) )
- return false;
-
- addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
- }
- else
- {
- if ( !IsPedCommentLoaded(nSfx) )
- return false;
-
- int32 slot = _GetPedCommentSlot(nSfx);
-
- addr = nPedSlotSfxAddr[slot];
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- {
- AIL_set_sample_address(opened_2dsamples[nChannel - MAXCHANNELS], (void *)addr, m_aSamples[nSfx].nSize);
- return true;
- }
- else
- return false;
- }
- else
- {
- AILSOUNDINFO info;
-
- info.format = WAVE_FORMAT_PCM;
- info.data_ptr = (void *)addr;
- info.channels = 1;
- info.data_len = m_aSamples[nSfx].nSize;
- info.rate = m_aSamples[nSfx].nFrequency;
- info.bits = 16;
-
- if ( AIL_set_3D_sample_info(opened_samples[nChannel], &info) == 0 )
- {
- OutputDebugString(AIL_last_error());
- return false;
- }
-
- return true;
- }
-}
-
-void
-cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
-{
- uint32 vol = nVolume;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- nChannelVolume[nChannel] = vol;
-
- // increase the volume for JB.MP3 and S4_BDBD.MP3
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] >>= 2;
- }
-
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_volume(opened_samples[nChannel], m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14);
-
-}
-
-void
-cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
-{
- if ( opened_samples[nChannel] )
- AIL_set_3D_position(opened_samples[nChannel], -fX, fY, fZ);
-}
-
-void
-cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
-{
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_distances(opened_samples[nChannel], fMax, fMin);
-}
-
-void
-cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
-{
- uint32 vol = nVolume;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- nChannelVolume[nChannel] = vol;
-
- // increase the volume for JB.MP3 and S4_BDBD.MP3
- if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
- {
- nChannelVolume[nChannel] >>= 2;
- }
-
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- {
- AIL_set_sample_volume(opened_2dsamples[nChannel - MAXCHANNELS],
- m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
- }
-
- break;
- }
- }
-}
-
-void
-cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
-{
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
-#ifndef FIX_BUGS
- if ( opened_samples[nChannel - MAXCHANNELS] ) // BUG
-#else
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
-#endif
- AIL_set_sample_pan(opened_2dsamples[nChannel - MAXCHANNELS], nPan);
-
- break;
- }
- }
-}
-
-void
-cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_set_sample_playback_rate(opened_2dsamples[nChannel - MAXCHANNELS], nFreq);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_playback_rate(opened_samples[nChannel], nFreq);
- }
-}
-
-void
-cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_set_sample_loop_block(opened_2dsamples[nChannel - MAXCHANNELS], nLoopStart, nLoopEnd);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_loop_block(opened_samples[nChannel], nLoopStart, nLoopEnd);
- }
-}
-
-void
-cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_set_sample_loop_count(opened_2dsamples[nChannel - MAXCHANNELS], nLoopCount);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_set_3D_sample_loop_count(opened_samples[nChannel], nLoopCount);
- }
-}
-
-bool
-cSampleManager::GetChannelUsedFlag(uint32 nChannel)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- return AIL_sample_status(opened_2dsamples[nChannel - MAXCHANNELS]) == SMP_PLAYING;
- else
- return false;
- }
- else
- {
- if ( opened_samples[nChannel] )
- return AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING;
- else
- return false;
- }
-
-}
-
-void
-cSampleManager::StartChannel(uint32 nChannel)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_start_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
- }
- else
- {
- if ( opened_samples[nChannel] )
- AIL_start_3D_sample(opened_samples[nChannel]);
- }
-}
-
-void
-cSampleManager::StopChannel(uint32 nChannel)
-{
- bool b2d = false;
-
- switch ( nChannel )
- {
- case CHANNEL2D:
- {
- b2d = true;
- break;
- }
- }
-
- if ( b2d )
- {
- if ( opened_2dsamples[nChannel - MAXCHANNELS] )
- AIL_end_sample(opened_2dsamples[nChannel - MAXCHANNELS]);
- }
- else
- {
- if ( opened_samples[nChannel] )
- {
- if ( AIL_3D_sample_status(opened_samples[nChannel]) == SMP_PLAYING )
- AIL_end_3D_sample(opened_samples[nChannel]);
- }
- }
-}
-
-void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( nFile < TOTAL_STREAMED_SOUNDS )
- {
- if ( mp3Stream[nStream] )
- {
- AIL_pause_stream(mp3Stream[nStream], 1);
- AIL_close_stream(mp3Stream[nStream]);
- }
-
- char filepath[MAX_PATH];
-
- strcpy(filepath, m_szCDRomRootPath);
- strcat(filepath, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filepath, 0);
-
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_service_stream(mp3Stream[nStream], 1);
- }
- else
- OutputDebugString(AIL_last_error());
- }
- }
-}
-
-void
-cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- AIL_pause_stream(mp3Stream[nStream], nPauseFlag != 0);
- }
-}
-
-void
-cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- AIL_start_stream(mp3Stream[nStream]);
- }
-}
-
-bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
-{
- uint32 position = nPos;
- char filename[MAX_PATH];
-
- if ( m_bInitialised && nFile < TOTAL_STREAMED_SOUNDS )
- {
- if ( mp3Stream[nStream] )
- {
- AIL_pause_stream(mp3Stream[nStream], 1);
- AIL_close_stream(mp3Stream[nStream]);
- }
-
- if ( nFile == STREAMED_SOUND_RADIO_MP3_PLAYER )
- {
- uint32 i = 0;
- do {
- if(i != 0 || _bIsMp3Active) {
- if(++_CurMP3Index >= nNumMP3s) _CurMP3Index = 0;
-
- _CurMP3Pos = 0;
-
- tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
-
- if(mp3) {
- mp3 = _pMP3List;
- if(mp3 == NULL) {
- _bIsMp3Active = false;
- nFile = 0;
- strcpy(filename, m_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] =
- AIL_open_stream(DIG, filename, 0);
- if(mp3Stream[nStream]) {
- AIL_set_stream_loop_count(
- mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(
- mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream],
- 0);
- return true;
- }
-
- return false;
- }
- }
-
- if(mp3->pLinkPath != NULL)
- mp3Stream[nStream] =
- AIL_open_stream(DIG, mp3->pLinkPath, 0);
- else {
- strcpy(filename, _mp3DirectoryPath);
- strcat(filename, mp3->aFilename);
-
- mp3Stream[nStream] =
- AIL_open_stream(DIG, filename, 0);
- }
-
- if(mp3Stream[nStream]) {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], 0);
- AIL_pause_stream(mp3Stream[nStream], 0);
- return true;
- }
-
- _bIsMp3Active = false;
- continue;
- }
- if ( nPos > nStreamLength[STREAMED_SOUND_RADIO_MP3_PLAYER] )
- position = 0;
-
- tMP3Entry *e;
- if ( !_GetMP3PosFromStreamPos(&position, &e) )
- {
- if ( e == NULL )
- {
- nFile = 0;
- strcpy(filename, m_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
- mp3Stream[nStream] =
- AIL_open_stream(DIG, filename, 0);
- if(mp3Stream[nStream]) {
- AIL_set_stream_loop_count(
- mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(
- mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream], 0);
- return true;
- }
-
- return false;
- }
- }
-
- if ( e->pLinkPath != NULL )
- mp3Stream[nStream] = AIL_open_stream(DIG, e->pLinkPath, 0);
- else
- {
- strcpy(filename, _mp3DirectoryPath);
- strcat(filename, e->aFilename);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
- }
-
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream], 0);
-
- _bIsMp3Active = true;
-
- return true;
- }
-
- _bIsMp3Active = false;
-
- } while(++i < nNumMP3s);
-
- position = 0;
- nFile = 0;
- }
-
- strcpy(filename, m_szCDRomRootPath);
- strcat(filename, StreamedNameTable[nFile]);
-
- mp3Stream[nStream] = AIL_open_stream(DIG, filename, 0);
- if ( mp3Stream[nStream] )
- {
- AIL_set_stream_loop_count(mp3Stream[nStream], 1);
- AIL_set_stream_ms_position(mp3Stream[nStream], position);
- AIL_pause_stream(mp3Stream[nStream], 0);
- return true;
- }
- }
-
- return false;
-}
-
-void
-cSampleManager::StopStreamedFile(uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- {
- AIL_pause_stream(mp3Stream[nStream], 1);
-
- AIL_close_stream(mp3Stream[nStream]);
- mp3Stream[nStream] = NULL;
-
- if ( nStream == 0 )
- _bIsMp3Active = false;
- }
- }
-}
-
-int32
-cSampleManager::GetStreamedFilePosition(uint8 nStream)
-{
- S32 currentms;
-
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- {
- if ( _bIsMp3Active )
- {
- tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
-
- if ( mp3 != NULL )
- {
- AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
- return currentms + mp3->nTrackStreamPos;
- }
- else
- return 0;
- }
- else
- {
- AIL_stream_ms_position(mp3Stream[nStream], NULL, &currentms);
- return currentms;
- }
- }
- }
-
- return 0;
-}
-
-void
-cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
-{
- uint8 vol = nVolume;
-
- if ( m_bInitialised )
- {
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
- if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-
- nStreamVolume[nStream] = vol;
- nStreamPan[nStream] = nPan;
-
- if ( mp3Stream[nStream] )
- {
- if ( nEffectFlag )
- AIL_set_stream_volume(mp3Stream[nStream], m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
- else
- AIL_set_stream_volume(mp3Stream[nStream], m_nMusicFadeVolume*vol*m_nMusicVolume >> 14);
-
- AIL_set_stream_pan(mp3Stream[nStream], nPan);
- }
- }
-}
-
-int32
-cSampleManager::GetStreamedFileLength(uint8 nStream)
-{
- if ( m_bInitialised )
- return nStreamLength[nStream];
-
- return 0;
-}
-
-bool
-cSampleManager::IsStreamPlaying(uint8 nStream)
-{
- if ( m_bInitialised )
- {
- if ( mp3Stream[nStream] )
- {
- if ( AIL_stream_status(mp3Stream[nStream]) == SMP_PLAYING )
- return true;
- else
- return false;
- }
- }
-
- return false;
-}
-
-bool
-cSampleManager::InitialiseSampleBanks(void)
-{
- int32 nBank = SAMPLEBANK_MAIN;
-
- fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
- if ( fpSampleDescHandle == NULL )
- return false;
-
- fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
- if ( fpSampleDataHandle == NULL )
- {
- fclose(fpSampleDescHandle);
- fpSampleDescHandle = NULL;
-
- return false;
- }
-
- fseek(fpSampleDataHandle, 0, SEEK_END);
- _nSampleDataEndOffset = ftell(fpSampleDataHandle);
- rewind(fpSampleDataHandle);
-
- fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
-
- fclose(fpSampleDescHandle);
- fpSampleDescHandle = NULL;
-
- for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
- {
-#ifdef FIX_BUGS
- if (nBank >= MAX_SAMPLEBANKS) break;
-#endif
- if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
- {
- nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
- nBank++;
- }
- }
-
- nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
- nSampleBankSize[SAMPLEBANK_PED] = _nSampleDataEndOffset - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
-
- return true;
-}
+#include "openal\samp_oal.cpp"
+#endif \ No newline at end of file
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index ebedfb63..f454d236 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -1,339 +1,7 @@
#pragma once
#include "common.h"
-#include "AudioSamples.h"
-
-#define MAX_VOLUME 127
-
-struct tSample {
- int32 nOffset;
- uint32 nSize;
- int32 nFrequency;
- int32 nLoopStart;
- int32 nLoopEnd;
-};
-
-enum
-{
- SAMPLEBANK_MAIN,
- SAMPLEBANK_PED,
- MAX_SAMPLEBANKS,
- SAMPLEBANK_INVALID
-};
-
-#define MAX_PEDSFX 7
-#define PED_BLOCKSIZE 79000
-
-#define MAXPROVIDERS 64
-
-#define MAXCHANNELS 28
-#define MAXCHANNELS_SURROUND 24
-#define MAX2DCHANNELS 1
-#define CHANNEL2D MAXCHANNELS
-
-#define MAX_MP3STREAMS 2
-
-#define DIGITALRATE 32000
-#define DIGITALBITS 16
-#define DIGITALCHANNELS 2
-
-#define MAX_DIGITAL_MIXER_CHANNELS 32
-
-class cSampleManager
-{
- uint8 m_nEffectsVolume;
- uint8 m_nMusicVolume;
- uint8 m_nEffectsFadeVolume;
- uint8 m_nMusicFadeVolume;
- uint8 m_nMonoMode;
- char unk;
- char m_szCDRomRootPath[80];
- bool m_bInitialised;
- uint8 m_nNumberOfProviders;
- char *m_aAudioProviders[MAXPROVIDERS];
- tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
-
-public:
-
-
-
- cSampleManager(void) :
- m_nNumberOfProviders(0)
- { }
-
- ~cSampleManager(void)
- { }
-
- void SetSpeakerConfig(int32 nConfig);
- uint32 GetMaximumSupportedChannels(void);
-
- uint32 GetNum3DProvidersAvailable() { return m_nNumberOfProviders; }
- void SetNum3DProvidersAvailable(uint32 num) { m_nNumberOfProviders = num; }
-
- char *Get3DProviderName(uint8 id) { return m_aAudioProviders[id]; }
- void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
-
- int8 GetCurrent3DProviderIndex(void);
- int8 SetCurrent3DProvider(uint8 which);
-
- bool IsMP3RadioChannelAvailable(void);
-
- void ReleaseDigitalHandle (void);
- void ReacquireDigitalHandle(void);
-
- bool Initialise(void);
- void Terminate (void);
-
- bool CheckForAnAudioFileOnCD(void);
- char GetCDAudioDriveLetter (void);
-
- void UpdateEffectsVolume(void);
-
- void SetEffectsMasterVolume(uint8 nVolume);
- void SetMusicMasterVolume (uint8 nVolume);
- void SetEffectsFadeVolume (uint8 nVolume);
- void SetMusicFadeVolume (uint8 nVolume);
-
- bool LoadSampleBank (uint8 nBank);
- void UnloadSampleBank (uint8 nBank);
- bool IsSampleBankLoaded(uint8 nBank);
-
- bool IsPedCommentLoaded(uint32 nComment);
- bool LoadPedComment (uint32 nComment);
-
- int32 _GetPedCommentSlot(uint32 nComment);
-
- int32 GetSampleBaseFrequency (uint32 nSample);
- int32 GetSampleLoopStartOffset(uint32 nSample);
- int32 GetSampleLoopEndOffset (uint32 nSample);
- uint32 GetSampleLength (uint32 nSample);
-
- bool UpdateReverb(void);
-
- void SetChannelReverbFlag (uint32 nChannel, uint8 nReverbFlag);
- bool InitialiseChannel (uint32 nChannel, uint32 nSfx, uint8 nBank);
- void SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
- void SetChannel3DPosition (uint32 nChannel, float fX, float fY, float fZ);
- void SetChannel3DDistances (uint32 nChannel, float fMax, float fMin);
- 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);
- 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);
- bool InitialiseSampleBanks(void);
-};
-
-extern cSampleManager SampleManager;
-extern int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-static char StreamedNameTable[][25]=
-{
- "AUDIO\\HEAD.WAV",
- "AUDIO\\CLASS.WAV",
- "AUDIO\\KJAH.WAV",
- "AUDIO\\RISE.WAV",
- "AUDIO\\LIPS.WAV",
- "AUDIO\\GAME.WAV",
- "AUDIO\\MSX.WAV",
- "AUDIO\\FLASH.WAV",
- "AUDIO\\CHAT.WAV",
- "AUDIO\\HEAD.WAV",
- "AUDIO\\POLICE.WAV",
- "AUDIO\\CITY.WAV",
- "AUDIO\\WATER.WAV",
- "AUDIO\\COMOPEN.WAV",
- "AUDIO\\SUBOPEN.WAV",
- "AUDIO\\JB.MP3",
- "AUDIO\\BET.MP3",
- "AUDIO\\L1_LG.MP3",
- "AUDIO\\L2_DSB.MP3",
- "AUDIO\\L3_DM.MP3",
- "AUDIO\\L4_PAP.MP3",
- "AUDIO\\L5_TFB.MP3",
- "AUDIO\\J0_DM2.MP3",
- "AUDIO\\J1_LFL.MP3",
- "AUDIO\\J2_KCL.MP3",
- "AUDIO\\J3_VH.MP3",
- "AUDIO\\J4_ETH.MP3",
- "AUDIO\\J5_DST.MP3",
- "AUDIO\\J6_TBJ.MP3",
- "AUDIO\\T1_TOL.MP3",
- "AUDIO\\T2_TPU.MP3",
- "AUDIO\\T3_MAS.MP3",
- "AUDIO\\T4_TAT.MP3",
- "AUDIO\\T5_BF.MP3",
- "AUDIO\\S0_MAS.MP3",
- "AUDIO\\S1_PF.MP3",
- "AUDIO\\S2_CTG.MP3",
- "AUDIO\\S3_RTC.MP3",
- "AUDIO\\S5_LRQ.MP3",
- "AUDIO\\S4_BDBA.MP3",
- "AUDIO\\S4_BDBB.MP3",
- "AUDIO\\S2_CTG2.MP3",
- "AUDIO\\S4_BDBD.MP3",
- "AUDIO\\S5_LRQB.MP3",
- "AUDIO\\S5_LRQC.MP3",
- "AUDIO\\A1_SSO.WAV",
- "AUDIO\\A2_PP.WAV",
- "AUDIO\\A3_SS.WAV",
- "AUDIO\\A4_PDR.WAV",
- "AUDIO\\A5_K2FT.WAV",
- "AUDIO\\K1_KBO.MP3",
- "AUDIO\\K2_GIS.MP3",
- "AUDIO\\K3_DS.MP3",
- "AUDIO\\K4_SHI.MP3",
- "AUDIO\\K5_SD.MP3",
- "AUDIO\\R0_PDR2.MP3",
- "AUDIO\\R1_SW.MP3",
- "AUDIO\\R2_AP.MP3",
- "AUDIO\\R3_ED.MP3",
- "AUDIO\\R4_GF.MP3",
- "AUDIO\\R5_PB.MP3",
- "AUDIO\\R6_MM.MP3",
- "AUDIO\\D1_STOG.MP3",
- "AUDIO\\D2_KK.MP3",
- "AUDIO\\D3_ADO.MP3",
- "AUDIO\\D5_ES.MP3",
- "AUDIO\\D7_MLD.MP3",
- "AUDIO\\D4_GTA.MP3",
- "AUDIO\\D4_GTA2.MP3",
- "AUDIO\\D6_STS.MP3",
- "AUDIO\\A6_BAIT.WAV",
- "AUDIO\\A7_ETG.WAV",
- "AUDIO\\A8_PS.WAV",
- "AUDIO\\A9_ASD.WAV",
- "AUDIO\\K4_SHI2.MP3",
- "AUDIO\\C1_TEX.MP3",
- "AUDIO\\EL_PH1.MP3",
- "AUDIO\\EL_PH2.MP3",
- "AUDIO\\EL_PH3.MP3",
- "AUDIO\\EL_PH4.MP3",
- "AUDIO\\YD_PH1.MP3",
- "AUDIO\\YD_PH2.MP3",
- "AUDIO\\YD_PH3.MP3",
- "AUDIO\\YD_PH4.MP3",
- "AUDIO\\HD_PH1.MP3",
- "AUDIO\\HD_PH2.MP3",
- "AUDIO\\HD_PH3.MP3",
- "AUDIO\\HD_PH4.MP3",
- "AUDIO\\HD_PH5.MP3",
- "AUDIO\\MT_PH1.MP3",
- "AUDIO\\MT_PH2.MP3",
- "AUDIO\\MT_PH3.MP3",
- "AUDIO\\MT_PH4.MP3",
- "AUDIO\\MISCOM.WAV",
- "AUDIO\\END.MP3",
- "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"
-};
+#ifndef OPENAL
+#include "miles\sampman_mss.h"
+#else
+#include "openal\samp_oal.h"
+#endif \ No newline at end of file
diff --git a/src/core/config.h b/src/core/config.h
index b5022b9f..c52a708d 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -193,6 +193,11 @@ enum Config {
#define DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
//#define USE_TXD_CDIMAGE // generate and load textures from txd.img
//#define USE_TEXTURE_POOL
+//#define OPENAL
+
+// Particle
+//#define PC_PARTICLE
+//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// Pad
#define XINPUT
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index e5f42696..3c2bc31f 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -372,7 +372,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
#ifdef TOGGLEABLE_BETA_FEATURES
- DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", (int8*)&CPed::bMakePedsRunToPhonesToReportCrimes, nil);
#endif
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index fe448966..932a0b8a 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -169,7 +169,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_STEAM_NY;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 8;
break;
}
@@ -187,7 +191,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_STEAM_NY;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 8;
break;
}
@@ -205,7 +213,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_STEAM_NY;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 8;
pobj->m_Color = CRGBA(16, 16, 16, 255);
break;
@@ -228,7 +240,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_CAR_SPLASH;
pobj->m_nNumEffectCycles = 0;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 1;
+#else
+ pobj->m_nSkipFrames = 3;
+#endif
pobj->m_nCreationChance = 0;
break;
}
@@ -236,7 +252,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
case POBJECT_SPLASHES_AROUND:
{
pobj->m_ParticleType = PARTICLE_SPLASH;
+#ifdef PC_PARTICLE
pobj->m_nNumEffectCycles = 15;
+#else
+ pobj->m_nNumEffectCycles = 30;
+#endif
pobj->m_nSkipFrames = 2;
pobj->m_nCreationChance = 0;
break;
@@ -246,7 +266,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_FLAME;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 2;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 2;
pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
break;
@@ -256,7 +280,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_FLAME;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 2;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 4;
pobj->m_vecTarget = CVector(0.0f, 0.0f, 0.0f);
break;
@@ -286,7 +314,11 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
{
pobj->m_ParticleType = PARTICLE_EXPLOSION_MEDIUM;
pobj->m_nNumEffectCycles = 1;
+#ifdef PC_PARTICLE
pobj->m_nSkipFrames = 3;
+#else
+ pobj->m_nSkipFrames = 1;
+#endif
pobj->m_nCreationChance = 2;
pobj->m_fRandVal = 0.01f;
break;
@@ -598,6 +630,7 @@ void CParticleObject::UpdateClose(void)
case POBJECT_PED_WATER_SPLASH:
{
+#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -699,12 +732,69 @@ void CParticleObject::UpdateClose(void)
CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL,
CGeneral::GetRandomNumberInRange(0.4f, 1.0f), this->m_Color);
}
+#else
+ CVector pos;
+ CVector vel;
+
+ for ( int32 i = -2; i < 2; i++ )
+ {
+ pos = this->GetPosition();
+ pos += CVector(-0.75f, 0.5f * float(i), 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += -1.5 * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+
+ pos = this->GetPosition();
+ pos += CVector(0.75f, 0.5f * float(i), 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), -0.75, 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += -1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), 0.75, 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += 1.5f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+ }
+
+ for ( int32 i = 0; i < 4; i++ )
+ {
+ pos = this->GetPosition();
+
+ pos.x += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
+ pos.y += CGeneral::GetRandomNumberInRange(-1.5f, 1.5f);
+ pos.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+
+ vel = this->m_vecTarget;
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, pos, vel, NULL, 0.8f, this->m_Color);
+ }
+#endif
break;
}
case POBJECT_CAR_WATER_SPLASH:
{
+#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -799,7 +889,65 @@ void CParticleObject::UpdateClose(void)
splashvel.z += CGeneral::GetRandomNumberInRange(0.26f, 0.53f);
CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, NULL, 0.0f, this->m_Color);
}
+#else
+ CVector pos;
+ CVector vel;
+
+ for ( int32 i = -3; i < 4; i++ )
+ {
+ pos = this->GetPosition();
+ pos += CVector(-1.5f, 0.5f * float(i), 0.0f);
+
+
+ vel = this->m_vecTarget;
+ vel.x += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(1.5f, 0.5f * float(i), 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), -1.5f, 0.0f);
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += -3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+
+
+ pos = this->GetPosition();
+ pos += CVector(0.5f * float(i), 1.5f, 0.0f);
+
+
+ vel = this->m_vecTarget;
+ vel.x += float(i) * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.y += 3.0f * CGeneral::GetRandomNumberInRange(0.001f, 0.006f);
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+ }
+
+ for ( int32 i = 0; i < 8; i++ )
+ {
+ pos = this->GetPosition();
+ pos.x += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
+ pos.y += CGeneral::GetRandomNumberInRange(-3.0f, 3.0f);
+
+ vel = this->m_vecTarget;
+ vel.z += CGeneral::GetRandomNumberInRange(0.03f, 0.06f);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, vel, NULL, 0.0f, this->m_Color);
+ }
+#endif
break;
}
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 1f15aa6c..f4cdff70 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -2019,7 +2019,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
}
static void
-particleProduceFootDust(CPed *ped, CVector *pos, float size, int times)
+particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
{
switch (ped->m_nSurfaceTouched)
{
@@ -2028,7 +2028,7 @@ particleProduceFootDust(CPed *ped, CVector *pos, float size, int times)
case SURFACE_PAVEMENT:
case SURFACE_SAND:
for (int i = 0; i < times; ++i) {
- CVector adjustedPos = *pos;
+ CVector adjustedPos = pos;
adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
CParticle::AddParticle(PARTICLE_PEDFOOT_DUST, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, 0, 0);
@@ -2040,16 +2040,27 @@ particleProduceFootDust(CPed *ped, CVector *pos, float size, int times)
}
static void
-particleProduceFootSplash(CPed *ped, CVector *pos, float size, int times)
+particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times)
{
+#ifdef PC_PARTICLE
for (int i = 0; i < times; i++) {
- CVector adjustedPos = *pos;
+ CVector adjustedPos = pos;
adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.1f, 0.1f);
CVector direction = ped->GetForward() * -0.05f;
CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, direction, nil, size, CRGBA(32, 32, 32, 32), 0, 0, CGeneral::GetRandomNumber() & 1, 200);
}
+#else
+ for ( int32 i = 0; i < times; i++ )
+ {
+ CVector adjustedPos = pos;
+ adjustedPos.x += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+ adjustedPos.y += CGeneral::GetRandomNumberInRange(-0.2f, 0.2f);
+
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASHUP, adjustedPos, CVector(0.0f, 0.0f, 0.0f), nil, size, CRGBA(0, 0, 0, 0), 0, 0, CGeneral::GetRandomNumber() & 1, 200);
+ }
+#endif
}
void
@@ -2080,6 +2091,50 @@ CPed::PlayFootSteps(void)
}
}
+#ifdef GTA_PS2_STUFF
+ CAnimBlendAssociation *runStopAsoc = NULL;
+
+ if ( IsPlayer() )
+ {
+ runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+
+ if ( runStopAsoc == NULL )
+ runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
+ }
+
+ if ( runStopAsoc != NULL && runStopAsoc->blendAmount > 0.1f )
+ {
+ {
+ CVector pos(0.0f, 0.0f, 0.0f);
+ RwFrame *parent = m_pFrames[PED_FOOTL]->frame;
+ while( parent )
+ {
+ RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(parent));
+ parent = RwFrameGetParent(parent);
+ }
+
+ pos.z -= 0.1f;
+ pos += GetForward()*0.2f;
+ particleProduceFootDust(this, pos, 0.02f, 1);
+ }
+
+ {
+ CVector pos(0.0f, 0.0f, 0.0f);
+ RwFrame *parent = m_pFrames[PED_FOOTR]->frame;
+ while( parent )
+ {
+ RwV3dTransformPoints(pos, pos, 1, RwFrameGetMatrix(parent));
+ parent = RwFrameGetParent(parent);
+ }
+
+ pos.z -= 0.1f;
+ pos += GetForward()*0.2f;
+ particleProduceFootDust(this, pos, 0.02f, 1);
+ }
+ }
+#endif
+
+
if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) {
float stepStart = 1 / 15.0f;
float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart;
@@ -2121,9 +2176,15 @@ CPed::PlayFootSteps(void)
}
if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
if(IsPlayer())
- particleProduceFootDust(this, &footPos, 0.0f, 4);
- } else if(stepPart == 2) {
- particleProduceFootSplash(this, &footPos, 0.15f, 4);
+ particleProduceFootDust(this, footPos, 0.0f, 4);
+ }
+#ifdef PC_PARTICLE
+ else if(stepPart == 2)
+#else
+ else
+#endif
+ {
+ particleProduceFootSplash(this, footPos, 0.15f, 4);
}
}
}
@@ -2131,6 +2192,7 @@ CPed::PlayFootSteps(void)
if (m_nSurfaceTouched == SURFACE_PUDDLE) {
float pedSpeed = CVector2D(m_vecMoveSpeed).Magnitude();
if (pedSpeed > 0.03f && CTimer::GetFrameCounter() % 2 == 0 && pedSpeed > 0.13f) {
+#ifdef PC_PARTICLE
float particleSize = pedSpeed * 2.0f;
if (particleSize < 0.25f)
@@ -2149,6 +2211,12 @@ CPed::PlayFootSteps(void)
particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f);
CParticle::AddParticle(PARTICLE_RUBBER_SMOKE, particlePos, particleDir, nil, particleSize, CRGBA(255,255,255,255), 0, 0, 0, 0);
+#else
+ CVector particlePos = (GetPosition() - 0.3f * GetUp()) + GetForward()*0.3f;
+ CVector particleDir = m_vecMoveSpeed * 0.45f;
+ particleDir.z = CGeneral::GetRandomNumberInRange(0.03f, 0.05f);
+ CParticle::AddParticle(PARTICLE_PED_SPLASH, particlePos-CVector(0.0f, 0.0f, 1.2f), particleDir, nil, 0.0f, CRGBA(155, 185, 155, 255));
+#endif
}
}
}
@@ -15114,7 +15182,11 @@ CPed::ProcessBuoyancy(void)
bIsInTheAir = false;
}
pos.z = pos.z - 0.8f;
+#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true);
+#else
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true);
+#endif
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
m_nPedState = PED_IDLE;
return;
@@ -15143,6 +15215,7 @@ CPed::ProcessBuoyancy(void)
} else {
m_vecMoveSpeed.z = -0.01f;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f);
+#ifdef PC_PARTICLE
CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition();
float level = 0.0f;
if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
@@ -15151,6 +15224,18 @@ CPed::ProcessBuoyancy(void)
CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true);
nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80;
nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100;
+#else
+ CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition();
+ float level = 0.0f;
+ if (CWaterLevel::GetWaterLevel(aBitForward, &level, false))
+ aBitForward.z = level + 0.5f;
+
+ CVector vel = m_vecMoveSpeed * 0.1f;
+ vel.z = 0.18f;
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true);
+ nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
+ nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
+#endif
}
}
} else
@@ -15167,9 +15252,15 @@ CPed::ProcessBuoyancy(void)
if (pos.z != 0.0f) {
nGenerateWaterCircles = 0;
for(int i = 0; i < 4; i++) {
+#ifdef PC_PARTICLE
pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f);
CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0);
+#else
+ pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
+ pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f);
+ CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f));
+#endif
}
}
}
@@ -15181,9 +15272,17 @@ CPed::ProcessBuoyancy(void)
pos.z = level;
if (pos.z >= 0.0f) {
+#ifdef PC_PARTICLE
pos.z += 0.25f;
+#else
+ pos.z += 0.5f;
+#endif
nGenerateRaindrops = 0;
+#ifdef PC_PARTICLE
CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true);
+#else
+ CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true);
+#endif
}
}
}
diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp
index 0388e779..c855c860 100644
--- a/src/render/Particle.cpp
+++ b/src/render/Particle.cpp
@@ -12,9 +12,6 @@
#include "ParticleObject.h"
#include "Particle.h"
-#ifdef TOGGLEABLE_BETA_FEATURES
-bool CParticle::bEnableBannedParticles = false;
-#endif
#define MAX_PARTICLES_ON_SCREEN (1000)
@@ -388,8 +385,12 @@ void CParticle::Initialise()
gpFlame5Tex = RwTextureRead("flame5", nil);
+#ifdef FIX_BUGS
+ gpFlame5Raster = RwTextureGetRaster(gpFlame5Tex);
+#else
gpFlame5Raster = RwTextureGetRaster(gpFlame1Tex); // copy-paste bug ?
-
+#endif
+
gpRainDropSmallTex = RwTextureRead("rainsmall", nil);
gpRainDropSmallRaster = RwTextureGetRaster(gpRainDropSmallTex);
@@ -767,9 +768,8 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
if ( CTimer::GetIsPaused() )
return NULL;
-#ifdef TOGGLEABLE_BETA_FEATURES
- if(!bEnableBannedParticles)
-#endif
+
+#ifdef PC_PARTICLE
if ( ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM
@@ -782,6 +782,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
{
return nil;
}
+#endif
CParticle *pParticle = m_pUnusedListHead;
@@ -853,6 +854,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
pParticle->m_nRotation = nRotation;
+// PC only
if ( pParticle->m_nRotation >= 360 )
pParticle->m_nRotation -= 360;
else if ( pParticle->m_nRotation < 0 )
@@ -1348,12 +1350,13 @@ void CParticle::Update()
particle->m_nAlpha = clamp(particle->m_nAlpha - psystem->m_nFadeAlphaAmount,
0, 255);
-
+#ifdef PC_PARTICLE
if ( particle->m_nAlpha == 0 )
{
bRemoveParticle = true;
continue;
}
+#endif
}
else
++particle->m_nFadeAlphaTimer;
@@ -1448,18 +1451,15 @@ void CParticle::Render()
for ( int32 i = 0; i < MAX_PARTICLES; i++ )
{
tParticleSystemData *psystem = &mod_ParticleSystemManager.m_aParticles[i];
-
+#ifdef PC_PARTICLE
bool particleBanned = false;
-
+#endif
CParticle *particle = psystem->m_pParticles;
RwRaster **frames = psystem->m_ppRaster;
-
+#ifdef PC_PARTICLE
tParticleType type = psystem->m_Type;
-#ifdef TOGGLEABLE_BETA_FEATURES
- if (!bEnableBannedParticles)
-#endif
if ( type == PARTICLE_ENGINE_SMOKE
|| type == PARTICLE_ENGINE_SMOKE2
|| type == PARTICLE_ENGINE_STEAM
@@ -1471,7 +1471,8 @@ void CParticle::Render()
{
particleBanned = true;
}
-
+#endif
+
if ( particle )
{
if ( (flags & DRAW_OPAQUE) != (psystem->Flags & DRAW_OPAQUE)
@@ -1512,10 +1513,11 @@ void CParticle::Render()
while ( particle != nil )
{
bool canDraw = true;
+#ifdef PC_PARTICLE
if ( particle->m_nAlpha == 0 )
canDraw = false;
-
+#endif
if ( canDraw && psystem->m_nFinalAnimationFrame != 0 && frames != nil )
{
RwRaster *curFrame = frames[particle->m_nCurrentFrame];
@@ -1538,7 +1540,7 @@ void CParticle::Render()
particle->m_fSize * 63.0f,
particle->m_Color,
particle->m_nColorIntensity,
- (float)particle->m_nRotation,
+ (float)particle->m_nRotation, //DEGTORAD((float)particle->m_nRotation) ps2
particle->m_nAlpha);
}
else
@@ -1564,8 +1566,10 @@ void CParticle::Render()
if ( CSprite::CalcScreenCoors(particle->m_vecPosition, coors, &w, &h, true) )
{
+#ifdef PC_PARTICLE
if ( (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w)
&& SCREEN_HEIGHT * fParticleScaleLimit >= h )
+#endif
{
if ( particle->m_nRotation != 0 )
{
@@ -1576,7 +1580,7 @@ void CParticle::Render()
particle->m_Color.blue,
particle->m_nColorIntensity,
1.0f / coors.z,
- float(particle->m_nRotation),
+ float(particle->m_nRotation), // DEGTORAD((float)particle->m_nRotation) ps2
particle->m_nAlpha);
}
else if ( psystem->Flags & SCREEN_TRAIL )
@@ -1601,7 +1605,6 @@ void CParticle::Render()
fTrailLength = fDist;
- //Float fRot = Atan2( vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist)) );
float fRot = Asin(vecDist.x / fDist);
fRotation = fRot;
@@ -1653,7 +1656,6 @@ void CParticle::Render()
fTrailLength = fDist;
- //Float fRot = Atan2(vecDist.x / fDist, Sqrt(1.0f - vecDist.x / fDist * (vecDist.x / fDist)));
float fRot = Asin(vecDist.x / fDist);
fRotation = fRot;
diff --git a/src/render/Particle.h b/src/render/Particle.h
index 8999f4f6..b71dc717 100644
--- a/src/render/Particle.h
+++ b/src/render/Particle.h
@@ -89,10 +89,6 @@ public:
static void AddJetExplosion(CVector const &vecPos, float fPower, float fSize);
static void AddYardieDoorSmoke(CVector const &vecPos, CMatrix const &matMatrix);
-
-#ifdef TOGGLEABLE_BETA_FEATURES
- static bool bEnableBannedParticles;
-#endif
};
VALIDATE_SIZE(CParticle, 0x68); \ No newline at end of file
diff --git a/src/render/ParticleMgr.cpp b/src/render/ParticleMgr.cpp
index 00391ac5..3387d471 100644
--- a/src/render/ParticleMgr.cpp
+++ b/src/render/ParticleMgr.cpp
@@ -8,8 +8,7 @@ cParticleSystemMgr mod_ParticleSystemManager;
const char *ParticleFilename = "PARTICLE.CFG";
-//cParticleSystemMgr::cParticleSystemMgr()
-void cParticleSystemMgr::ctor()
+cParticleSystemMgr::cParticleSystemMgr()
{
memset(this, 0, sizeof(*this));
}
diff --git a/src/render/ParticleMgr.h b/src/render/ParticleMgr.h
index 0b4091de..70845a56 100644
--- a/src/render/ParticleMgr.h
+++ b/src/render/ParticleMgr.h
@@ -118,11 +118,11 @@ class cParticleSystemMgr
public:
tParticleSystemData m_aParticles[MAX_PARTICLES];
- cParticleSystemMgr() { ctor(); } void ctor();
+ cParticleSystemMgr();
void Initialise();
void LoadParticleData();
- //void RangeCheck(tParticleSystemData *pData);
+ void RangeCheck(tParticleSystemData *pData) { }
};
VALIDATE_SIZE(cParticleSystemMgr, 0x2420);
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 1b14e7a2..74609e15 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -2848,6 +2848,7 @@ CAutomobile::ProcessBuoyancy(void)
static uint32 nGenerateWaterCircles = 0;
if(initialSpeed.z < -0.3f && impulse.z > 0.3f){
+#if defined(PC_PARTICLE) || defined (PS2_ALTERNATIVE_CARSPLASH)
RwRGBA color;
color.red = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.45f*255;
color.green = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.45f*255;
@@ -2856,6 +2857,30 @@ CAutomobile::ProcessBuoyancy(void)
CParticleObject::AddObject(POBJECT_CAR_WATER_SPLASH, GetPosition(),
CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.15f, 0.3f)),
0.0f, 75, color, true);
+#else
+ CVector pos = (initialSpeed * 2.0f) + (GetPosition() + point);
+
+ for ( int32 i = 0; i < 360; i += 4 )
+ {
+ float fSin = Sin(float(i));
+ float fCos = Cos(float(i));
+
+ CVector dir(fSin*0.01f, fCos*0.01f, CGeneral::GetRandomNumberInRange(0.25f, 0.45f));
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH,
+ pos + CVector(fSin*4.5f, fCos*4.5f, 0.0f),
+ dir, NULL, 0.0f, CRGBA(225, 225, 255, 180));
+
+ for ( int32 j = 0; j < 3; j++ )
+ {
+ float fMul = 1.5f * float(j + 1);
+
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH,
+ pos + CVector(fSin * fMul, fCos * fMul, 0.0f),
+ dir, NULL, 0.0f, CRGBA(225, 225, 255, 180));
+ }
+ }
+#endif
nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300;
nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60;
@@ -2909,9 +2934,16 @@ CAutomobile::ProcessBuoyancy(void)
CVector pos = m_aWheelColPoints[i].point + 0.3f*GetUp() - GetPosition();
CVector vSpeed = GetSpeed(pos);
vSpeed.z = 0.0f;
+#ifdef GTA_PS2_STUFF
+ // ps2 puddle physics
+ CVector moveForce = CTimer::GetTimeStep() * (m_fMass * (vSpeed * -0.003f));
+ ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
+#endif
float fSpeed = vSpeed.MagnitudeSqr();
+#ifdef PC_PARTICLE
if(fSpeed > sq(0.05f)){
fSpeed = Sqrt(fSpeed);
+
float size = Min((fSpeed < 0.15f ? 0.25f : 0.75f)*fSpeed, 0.6f);
CVector right = 0.2f*fSpeed*GetRight() + 0.2f*vSpeed;
@@ -2924,10 +2956,39 @@ CAutomobile::ProcessBuoyancy(void)
CParticle::AddParticle(PARTICLE_RUBBER_SMOKE,
pos + GetPosition(), -0.6f*right,
nil, size, smokeCol, 0, 0, 0, 0);
-
+
if((CTimer::GetFrameCounter() & 0xF) == 0)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed);
}
+#else
+ if ( ( (CTimer::GetFrameCounter() + i) & 3 ) == 0 )
+ {
+ if(fSpeed > sq(0.05f))
+ {
+ fSpeed = Sqrt(fSpeed);
+ CRGBA color(155, 185, 155, 255);
+ float boxY = GetColModel()->boundingBox.max.y;
+ CVector right = 0.5f * GetRight();
+
+ if ( i == 2 )
+ {
+ CParticle::AddParticle(PARTICLE_PED_SPLASH,
+ GetPosition() + (boxY * GetForward()) + right,
+ 0.75f*m_vecMoveSpeed, NULL, 0.0f, color);
+
+ }
+ else if ( i == 0 )
+ {
+ CParticle::AddParticle(PARTICLE_PED_SPLASH,
+ GetPosition() + (boxY * GetForward()) - right,
+ 0.75f*m_vecMoveSpeed, NULL, 0.0f, color);
+ }
+
+ if((CTimer::GetFrameCounter() & 0xF) == 0)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_SPLASH, 2000.0f*fSpeed);
+ }
+ }
+#endif
}
}
}
@@ -3486,14 +3547,29 @@ CAutomobile::AddWheelDirtAndWater(CColPoint *colpoint, uint32 belowEffectSpeed)
}
return 0;
default:
- // Is this even visible?
- if(CWeather::WetRoads > 0.01f && CTimer::GetFrameCounter() & 1){
- CParticle::AddParticle(PARTICLE_WATERSPRAY,
+ if ( CWeather::WetRoads > 0.01f
+#ifdef PC_PARTICLE
+ && CTimer::GetFrameCounter() & 1
+#endif
+ )
+ {
+ CParticle::AddParticle(
+#ifdef FIX_BUGS
+ PARTICLE_WHEEL_WATER,
+#else
+ PARTICLE_WATERSPRAY,
+#endif
colpoint->point + CVector(0.0f, 0.0f, 0.25f+0.25f),
- CVector(0.0f, 0.0f, 1.0f), nil,
+#ifdef PC_PARTICLE
+ CVector(0.0f, 0.0f, 1.0f),
+#else
+ CVector(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(0.005f, 0.04f)),
+#endif
+ nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.5f), waterCol);
return 0;
}
+
return 1;
}
}
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 42beeb6c..d31182cd 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -340,27 +340,46 @@ CBoat::ProcessControl(void)
else
jetPos.z = 0.0f;
+#ifdef PC_PARTICLE
CVector wakePos = GetPosition() + sternPos;
wakePos.z -= 0.65f;
+#else
+ CVector wakePos = GetPosition() + sternPos;
+ wakePos.z = -0.3f;
+#endif
CVector wakeDir = 0.75f * jetDir;
CParticle::AddParticle(PARTICLE_BOAT_THRUSTJET, jetPos, jetDir, nil, 0.0f, jetColor);
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, jetPos, 0.25f * jetDir, nil, 1.0f, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 3);
+#endif
if(!cameraHack)
CParticle::AddParticle(PARTICLE_BOAT_WAKE, wakePos, wakeDir, nil, 0.0f, jetColor);
}else if((CTimer::GetFrameCounter() + m_randomSeed) & 1){
+#ifdef PC_PARTICLE
jetDir.z = 0.018f;
jetDir.x *= 0.01f;
jetDir.y *= 0.01f;
propellerWorld.z += 1.5f;
-
+
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 1.5f, jetColor);
+#else
+ jetDir.z = 0.018f;
+ jetDir.x *= 0.03f;
+ jetDir.y *= 0.03f;
+ propellerWorld.z += 1.0f;
+
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, propellerWorld, jetDir, nil, 0.0f, jetColor);
+#endif
+
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, propellerWorld, 0.1f * jetDir, nil, 0.5f, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 3);
+#endif
}
}
}else if(!onLand){
@@ -416,36 +435,66 @@ CBoat::ProcessControl(void)
}
// Spray particles on sides of boat
- if(m_nDeltaVolumeUnderWater > 75){
+#ifdef PC_PARTICLE
+ if(m_nDeltaVolumeUnderWater > 75)
+#else
+ if(m_nDeltaVolumeUnderWater > 120)
+#endif
+ {
float speed = m_vecMoveSpeed.Magnitude();
float splash1Size = speed;
- float splash2Size = m_nDeltaVolumeUnderWater * 0.005f * 0.2f;
+ float splash2Size = float(m_nDeltaVolumeUnderWater) * 0.005f * 0.2f;
float front = 0.9f * GetColModel()->boundingBox.max.y;
if(splash1Size > 0.75f) splash1Size = 0.75f;
CVector dir, pos;
// right
+#ifdef PC_PARTICLE
dir = -0.5f*m_vecMoveSpeed;
dir.z += 0.1f*speed;
dir += 0.5f*GetRight()*speed;
pos = front*GetForward() + 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
CWaterLevel::GetWaterLevel(pos, &pos.z, true);
+#else
+ dir = 0.3f*m_vecMoveSpeed;
+ dir.z += 0.05f*speed;
+ dir += 0.5f*GetRight()*speed;
+ pos = (GetPosition() + m_vecBuoyancePoint) + (1.5f*GetRight());
+#endif
+
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 1);
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
+#else
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size);
+#endif
+
// left
+#ifdef PC_PARTICLE
dir = -0.5f*m_vecMoveSpeed;
dir.z += 0.1f*speed;
dir -= 0.5f*GetRight()*speed;
pos = front*GetForward() - 0.5f*GetRight() + GetPosition() + m_vecBuoyancePoint;
CWaterLevel::GetWaterLevel(pos, &pos.z, true);
+#else
+ dir = 0.3f*m_vecMoveSpeed;
+ dir.z += 0.05f*speed;
+ dir -= 0.5f*GetRight()*speed;
+ pos = (GetPosition() + m_vecBuoyancePoint) - (1.5f*GetRight());
+#endif
+
+#ifdef PC_PARTICLE
CParticle::AddParticle(PARTICLE_CAR_SPLASH, pos, 0.75f * dir, nil, splash1Size, splashColor,
CGeneral::GetRandomNumberInRange(0, 30),
CGeneral::GetRandomNumberInRange(0, 90), 1);
CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size, jetColor);
+#else
+ CParticle::AddParticle(PARTICLE_BOAT_SPLASH, pos, dir, nil, splash2Size);
+#endif
}
m_fPrevVolumeUnderWater = m_fVolumeUnderWater;