summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/WavSoundPlayer.java
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 22:33:32 -0800
committerFuwn <[email protected]>2026-02-12 22:33:32 -0800
commitc7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch)
treedf9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/WavSoundPlayer.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/WavSoundPlayer.java')
-rw-r--r--NET/worlds/scape/WavSoundPlayer.java275
1 files changed, 275 insertions, 0 deletions
diff --git a/NET/worlds/scape/WavSoundPlayer.java b/NET/worlds/scape/WavSoundPlayer.java
new file mode 100644
index 0000000..c1bff8a
--- /dev/null
+++ b/NET/worlds/scape/WavSoundPlayer.java
@@ -0,0 +1,275 @@
+package NET.worlds.scape;
+
+import NET.worlds.core.IniFile;
+import NET.worlds.network.URL;
+import java.util.Vector;
+
+public class WavSoundPlayer extends SoundPlayer implements Runnable {
+ float ang;
+ float dist;
+ float vol;
+ private String playingSoundFile = "";
+ private URL url;
+ private static Vector soundStack = new Vector();
+ private static Thread activeThread;
+ int repeatsLeft;
+ private static int playingThreads;
+ private static int systemPaused;
+ static boolean ignoreVolumeChanges = IniFile.gamma().getIniInt("ignoreVolumeChanges", 1) != 0;
+ private static WavSoundTerminator terminator = new WavSoundTerminator();
+ private static float lastLeftVol;
+ private static float lastRightVol;
+
+ static {
+ nativeInit();
+ }
+
+ public WavSoundPlayer(Sound owner) {
+ super(owner);
+ }
+
+ public static native void nativeInit();
+
+ @Override
+ public boolean open(float volume, float stopDist, boolean atten, boolean pan) {
+ return true;
+ }
+
+ @Override
+ public void close() {
+ this.stop();
+ }
+
+ @Override
+ public boolean position(Point3Temp cam, Point3Temp obj, Point3Temp out, Point3Temp up) {
+ Point3Temp toObj = Point3Temp.make(obj).minus(cam);
+ Point3Temp right = Point3Temp.make(out).cross(up);
+ float y = toObj.dot(out);
+ float x = toObj.dot(right);
+ this.ang = (float)(Math.atan2(y, x) / Math.PI);
+ this.dist = toObj.length();
+ return this.setVolume(this.vol);
+ }
+
+ @Override
+ public boolean setVolume(float v) {
+ this.vol = v;
+ float leftFrac = 0.5F;
+ if (this.owner != null && this.owner.getPanning()) {
+ leftFrac = Math.abs(this.ang);
+ if (this.ang < 0.0F) {
+ v = this.vol * (float)(0.5 + Math.abs(0.5 + this.ang));
+ }
+ }
+
+ if (this.owner != null && this.owner.getAttenuate()) {
+ float stopDist = this.owner.getStopDistance();
+ if (this.dist > stopDist) {
+ this.volume(0.0F, 0.0F);
+ return false;
+ }
+
+ v *= (stopDist - this.dist) / stopDist;
+ }
+
+ this.volume(v * leftFrac, v * (1.0F - leftFrac));
+ return true;
+ }
+
+ @Override
+ public int getState() {
+ return soundStack.contains(this) ? 0 : 1;
+ }
+
+ public void start(URL u) {
+ this.url = u;
+ this.start(1);
+ }
+
+ private static WavSoundPlayer getActive() {
+ return !soundStack.isEmpty() ? (WavSoundPlayer)soundStack.lastElement() : null;
+ }
+
+ public static boolean isActive() {
+ return !soundStack.isEmpty();
+ }
+
+ private void play(int repeatCount, boolean reuseLoop) {
+ this.playingSoundFile = this.url.unalias();
+ soundStack.removeElement(this);
+ soundStack.addElement(this);
+ this.repeatsLeft = repeatCount;
+ if (this.repeatsLeft < 0) {
+ if (!reuseLoop && systemPaused == 0) {
+ this.nativePlay(true);
+ }
+
+ activeThread = null;
+ } else {
+ activeThread = new Thread(this);
+ activeThread.start();
+ }
+ }
+
+ @Override
+ public void start(int repeatCount) {
+ synchronized (soundStack) {
+ WavSoundPlayer active = getActive();
+
+ assert this.repeatsLeft == 0 && active != this;
+
+ if (this.owner != null) {
+ this.url = this.owner.getURL();
+ }
+
+ boolean activeWasLoop = activeThread == null;
+ boolean reuseLoop = active != null && activeWasLoop && repeatCount < 0 && active.playingSoundFile.equals(this.url.unalias());
+ if (active != null) {
+ active.stop(reuseLoop);
+ if (activeWasLoop) {
+ soundStack.addElement(active);
+ }
+ }
+
+ this.play(repeatCount, reuseLoop);
+ }
+ }
+
+ @Override
+ public void run() {
+ synchronized (soundStack) {
+ if (systemPaused > 0) {
+ this.repeatsLeft = 0;
+ return;
+ }
+
+ playingThreads++;
+ }
+
+ while (this.repeatsLeft > 0) {
+ synchronized (soundStack) {
+ if (activeThread != Thread.currentThread()) {
+ break;
+ }
+
+ if (this.repeatsLeft > 0) {
+ this.repeatsLeft--;
+ }
+ }
+
+ this.nativePlay(false);
+ }
+
+ synchronized (soundStack) {
+ if (activeThread == Thread.currentThread()) {
+ assert getActive() == this;
+
+ soundStack.removeElement(this);
+ activeThread = null;
+ WavSoundPlayer active = getActive();
+ if (active != null) {
+ active.play(-1, false);
+ }
+ }
+
+ playingThreads--;
+ soundStack.notifyAll();
+ }
+ }
+
+ private void stop(boolean leaveLoopRunning) {
+ if (getActive() == this) {
+ boolean isLoop = activeThread == null;
+
+ assert this.repeatsLeft < 0 && isLoop || !leaveLoopRunning;
+
+ this.repeatsLeft = 0;
+ if (!leaveLoopRunning && isLoop && systemPaused == 0) {
+ this.nativeStop();
+ }
+
+ activeThread = null;
+ }
+
+ soundStack.removeElement(this);
+ }
+
+ @Override
+ public void stop() {
+ synchronized (soundStack) {
+ if (getActive() == this) {
+ this.stop(false);
+ WavSoundPlayer active = getActive();
+ if (active != null) {
+ active.play(-1, false);
+ }
+ } else {
+ soundStack.removeElement(this);
+ }
+ }
+ }
+
+ public static void pauseSystem() {
+ pauseSystemExceptASF();
+ }
+
+ public static void pauseSystemExceptASF() {
+ synchronized (soundStack) {
+ WavSoundPlayer active = getActive();
+ boolean isLoop = activeThread == null;
+ if (active != null) {
+ if (isLoop) {
+ active.nativeStop();
+ } else {
+ active.stop(false);
+ }
+ }
+
+ systemPaused++;
+ if (active != null) {
+ active.play(-1, false);
+ }
+
+ while (playingThreads > 0) {
+ try {
+ soundStack.wait();
+ } catch (InterruptedException var4) {
+ }
+ }
+ }
+ }
+
+ public static void resumeSystem() {
+ resumeSystemExceptASF();
+ }
+
+ public static void resumeSystemExceptASF() {
+ synchronized (soundStack) {
+ if (systemPaused > 0) {
+ systemPaused = 0;
+ WavSoundPlayer active = getActive();
+ if (active != null && activeThread == null) {
+ active.play(-1, false);
+ }
+ }
+ }
+ }
+
+ public void volume(float left, float right) {
+ if (!ignoreVolumeChanges) {
+ synchronized (soundStack) {
+ if (getActive() == this && (lastLeftVol != left || lastRightVol != right)) {
+ lastLeftVol = left;
+ lastRightVol = right;
+ this.nativeVolume(left, right);
+ }
+ }
+ }
+ }
+
+ private native void nativePlay(boolean var1);
+
+ private native void nativeVolume(float var1, float var2);
+
+ private native void nativeStop();
+}