summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/CDAudio.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/CDAudio.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/CDAudio.java')
-rw-r--r--NET/worlds/scape/CDAudio.java518
1 files changed, 518 insertions, 0 deletions
diff --git a/NET/worlds/scape/CDAudio.java b/NET/worlds/scape/CDAudio.java
new file mode 100644
index 0000000..2f1ea8f
--- /dev/null
+++ b/NET/worlds/scape/CDAudio.java
@@ -0,0 +1,518 @@
+package NET.worlds.scape;
+
+import NET.worlds.console.Main;
+import NET.worlds.console.MainCallback;
+import NET.worlds.console.MainTerminalCallback;
+import NET.worlds.core.IniFile;
+import NET.worlds.network.URL;
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+
+public class CDAudio implements Runnable, MainCallback, MainTerminalCallback {
+ private static final int STOP = 0;
+ private static final int PLAY = 1;
+ private static final int PAUSE = 2;
+ private static final int NEXT = 3;
+ private static final int PREV = 4;
+ private static final int CHANGE = 5;
+ private static final int CHANGE_MIDI = 6;
+ private boolean performedStartupPlay;
+ private boolean cancel;
+ private Thread playerThread;
+ private Vector commandBuffer = new Vector();
+ private boolean paused;
+ private int driveID;
+ private CDTrackInfo tracks;
+ private int trackOffset;
+ private Object tracksMutex = new Object();
+ private int pos;
+ private SoundPlayer midiPlayer;
+ private URL defaultMIDIFile = URL.make("home:start.mid");
+ private URL curMIDIFile = this.defaultMIDIFile;
+ private int trackToRepeat = -1;
+ private int repeatingTrack = -1;
+ private boolean enabled = true;
+ private static CDAudio instance = new CDAudio();
+ static boolean useMidiFlag = IniFile.gamma().getIniInt("MIDIONSTART", 1) != 0;
+ static boolean useAutoCDFlag = IniFile.gamma().getIniInt("AUTOPLAYCD", 1) != 0;
+ private boolean cdInDrive;
+ private boolean allowMIDIAnyway;
+ private boolean midiPaused;
+ private boolean midiStarted;
+
+ public static CDAudio get() {
+ return instance;
+ }
+
+ public String getTimeReadout() {
+ synchronized (this.tracksMutex) {
+ if (this.tracks == null) {
+ this.tracksMutex.notify();
+ return "00 [00:00]";
+ } else {
+ int count = this.tracks.getNumTracks();
+ if (this.pos != 0) {
+ for (int i = 0; i < count; i++) {
+ if (this.pos < this.tracks.getEndFrames(i)) {
+ return fmt2(i + 1) + " " + fmtFrames(this.pos - this.tracks.getStartFrames(i));
+ }
+ }
+ }
+
+ return fmt2(count) + " " + fmtFrames(this.tracks.getEndFrames(count - 1));
+ }
+ }
+ }
+
+ public void setEnabled(boolean state) {
+ if (this.enabled != state) {
+ this.enabled = state;
+ if (!this.enabled) {
+ this.stop();
+ } else {
+ this.change(true);
+ }
+ }
+ }
+
+ public void play() {
+ this.queueCommand(1);
+ }
+
+ public void pause() {
+ this.queueCommand(2);
+ }
+
+ public void stop() {
+ this.queueCommand(0);
+ }
+
+ public void next() {
+ this.queueCommand(3);
+ }
+
+ public void prev() {
+ this.queueCommand(4);
+ }
+
+ public void change(boolean loop) {
+ this.queueCommand(5);
+ }
+
+ public static void startupPlay() {
+ get();
+ }
+
+ public void setMIDIFile(URL url) {
+ this.curMIDIFile = url;
+ }
+
+ public URL getDefaultMIDIFile() {
+ return this.defaultMIDIFile;
+ }
+
+ public URL getMIDIFile() {
+ return this.curMIDIFile;
+ }
+
+ public void setCDTrack(int track) {
+ this.trackToRepeat = track - 1;
+ }
+
+ public int getCDTrack() {
+ return this.trackToRepeat + 1;
+ }
+
+ private CDAudio() {
+ this.playerThread = new Thread(this);
+ this.playerThread.start();
+ }
+
+ @Override
+ public void run() {
+ Main.register(this);
+ int numDrives = CDPlayerAction.getNumDrives();
+
+ while (!this.cancel) {
+ for (int i = 0; i < numDrives; i++) {
+ this.cdInDrive = false;
+
+ try {
+ if ((this.driveID = CDPlayerAction.openDrive(i)) != 0) {
+ if (!CDPlayerAction.isPlaying(this.driveID)) {
+ CDTrackInfo tmp = CDPlayerAction.getDriveTrackList(this.driveID);
+ char drive = (char)(65 + CDPlayerAction.getDriveLetterOffset(i));
+ File f = new File(drive + ":\\WORLDS.CD");
+ if (f.exists()) {
+ synchronized (this.tracksMutex) {
+ this.tracks = tmp;
+ this.trackOffset = 0;
+ if (f.length() == 1L) {
+ this.trackOffset = 1;
+ }
+ }
+
+ this.cdInDrive = true;
+ if (this.performedStartupPlay) {
+ this.flushPendingCommands();
+ } else {
+ this.performedStartupPlay = true;
+ }
+
+ this.change(true);
+ this.waitForCommands();
+ }
+ }
+
+ this.driveID = 0;
+ }
+ } catch (IOException var12) {
+ }
+
+ if (this.driveID != 0) {
+ try {
+ CDPlayerAction.closeDrive(this.driveID);
+ } catch (IOException var10) {
+ }
+
+ this.driveID = 0;
+ this.paused = false;
+ this.pos = 0;
+ }
+ }
+
+ this.performedStartupPlay = true;
+ this.cdInDrive = false;
+ synchronized (this.tracksMutex) {
+ this.tracks = null;
+ }
+
+ if (!this.cancel) {
+ this.timedWait(10);
+ synchronized (this.tracksMutex) {
+ if (!this.cancel) {
+ try {
+ this.tracksMutex.wait();
+ } catch (InterruptedException var7) {
+ }
+ }
+ }
+ }
+ }
+
+ Main.unregister(this);
+ }
+
+ public void useAutoCD(boolean f) {
+ if (f != useAutoCDFlag) {
+ useAutoCDFlag = f;
+ IniFile.gamma().setIniInt("AUTOPLAYCD", useAutoCDFlag ? 1 : 0);
+ if (f) {
+ if (this.trackToRepeat != -1) {
+ this.queueCommand(5);
+ }
+ } else {
+ this.queueCommand(0);
+ }
+ }
+ }
+
+ private synchronized void flushPendingCommands() {
+ this.commandBuffer.removeAllElements();
+ }
+
+ private synchronized void prequeueCommand(int command) {
+ this.commandBuffer.insertElementAt(new Integer(command), 0);
+ }
+
+ private synchronized void queueCommand(int command) {
+ if (command != 6) {
+ this.allowMIDIAnyway = false;
+ }
+
+ this.commandBuffer.addElement(new Integer(command));
+ }
+
+ private synchronized int getQueuedCommand(boolean isMidi) {
+ if (this.commandBuffer.size() <= 0) {
+ return -1;
+ } else {
+ int command = (Integer)this.commandBuffer.elementAt(0);
+ if (command == 6) {
+ if (!isMidi) {
+ return -1;
+ }
+ } else if (isMidi == this.cdInDrive) {
+ return -1;
+ }
+
+ this.commandBuffer.removeElementAt(0);
+ return command;
+ }
+ }
+
+ private synchronized int peekQueuedCommand() {
+ return this.commandBuffer.size() <= 0 ? -1 : (Integer)this.commandBuffer.elementAt(0);
+ }
+
+ private void waitForCommands() throws IOException {
+ while (!this.cancel) {
+ boolean playing = CDPlayerAction.isPlaying(this.driveID);
+ if (playing) {
+ int tmp = CDPlayerAction.getPosition(this.driveID);
+ if (tmp > this.pos) {
+ this.pos = tmp;
+ }
+
+ this.paused = false;
+ } else {
+ CDPlayerAction.checkDrive(this.driveID);
+ if (!this.paused) {
+ this.pos = 0;
+ }
+
+ if (this.repeatingTrack != -1) {
+ this.pos = this.tracks.getStartFrames(this.repeatingTrack + this.trackOffset);
+ CDPlayerAction.playAudio(this.driveID, this.pos, this.tracks.getEndFrames(this.repeatingTrack + this.trackOffset));
+ }
+ }
+
+ int command;
+ if ((command = this.getQueuedCommand(false)) >= 0) {
+ this.processCommand(command, playing);
+ } else {
+ this.timedWait(1);
+ }
+ }
+
+ CDPlayerAction.stopAudio(this.driveID);
+ }
+
+ private void processCommand(int command, boolean playing) throws IOException {
+ int wasRepeatingTrack = this.repeatingTrack;
+ this.repeatingTrack = -1;
+ switch (command) {
+ case 0:
+ if (playing || this.paused) {
+ CDPlayerAction.stopAudio(this.driveID);
+ }
+
+ this.paused = false;
+ break;
+ case 1:
+ if (!playing) {
+ this.play(-this.pos);
+ }
+ break;
+ case 2:
+ if (playing && !this.paused) {
+ CDPlayerAction.stopAudio(this.driveID);
+ this.paused = true;
+ }
+ break;
+ case 3:
+ if (!playing && !this.paused) {
+ this.play(0);
+ } else {
+ for (int ix = 0; ix < this.tracks.getNumTracks() - 1; ix++) {
+ if (this.pos >= this.tracks.getStartFrames(ix) && this.pos < this.tracks.getEndFrames(ix)) {
+ this.play(ix + 1);
+ return;
+ }
+ }
+ }
+ break;
+ case 4:
+ if (playing || this.paused) {
+ for (int i = 0; i < this.tracks.getNumTracks(); i++) {
+ if (this.pos < this.tracks.getEndFrames(i)) {
+ if (i > 0 && this.pos < this.tracks.getStartFrames(i) + 75) {
+ this.play(i - 1);
+ } else {
+ this.play(i);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case 5:
+ if (useAutoCDFlag && this.enabled) {
+ if (this.trackToRepeat == -1 || this.trackToRepeat < this.tracks.getNumTracks()) {
+ this.repeatingTrack = this.trackToRepeat;
+ if (wasRepeatingTrack == this.trackToRepeat && wasRepeatingTrack != -1) {
+ return;
+ }
+ }
+
+ CDPlayerAction.stopAudio(this.driveID);
+ if (this.repeatingTrack == -1) {
+ this.allowMIDIAnyway = true;
+ this.queueCommand(6);
+ }
+
+ this.paused = false;
+ }
+ }
+ }
+
+ private void play(int location) throws IOException {
+ if (location < 0) {
+ this.pos = -location;
+ } else {
+ this.pos = this.tracks.getStartFrames(location);
+ }
+
+ CDPlayerAction.playAudio(this.driveID, this.pos, this.tracks.getEndFrames(this.tracks.getNumTracks() - 1));
+ this.paused = false;
+ }
+
+ private void startMidi() {
+ if (this.curMIDIFile != this.defaultMIDIFile) {
+ if (this.midiPlayer != null) {
+ this.midiPlayer.stop();
+ this.midiPlayer.close();
+ this.midiStarted = false;
+ if (MCISoundPlayer.isActive() || WMPSoundPlayer.isActive()) {
+ this.midiPlayer = null;
+ return;
+ }
+ } else if (MCISoundPlayer.isActive() || WMPSoundPlayer.isActive()) {
+ return;
+ }
+
+ Sound s = new Sound(this.curMIDIFile);
+ if (!this.curMIDIFile.endsWith(".mid") && !this.curMIDIFile.endsWith(".wav")) {
+ this.midiPlayer = new WMPSoundPlayer(s);
+ } else {
+ this.midiPlayer = new MCISoundPlayer(s);
+ }
+
+ this.midiPlayer.open(1.0F, 0.0F, false, false);
+ if (!this.midiPaused) {
+ this.midiPlayer.start(1);
+ }
+ }
+ }
+
+ private void killMidi() {
+ if (this.midiPlayer != null) {
+ this.midiStarted = false;
+ this.midiPlayer.stop();
+ this.midiPlayer.close();
+ this.midiPlayer = null;
+ }
+ }
+
+ private void useMidi() {
+ if (useMidiFlag && this.enabled && (!this.cdInDrive || this.allowMIDIAnyway)) {
+ if (this.midiPlayer == null) {
+ this.startMidi();
+ } else if (this.midiPlayer.getState() == 1) {
+ if (this.midiStarted) {
+ this.startMidi();
+ this.midiStarted = false;
+ }
+ } else {
+ this.midiStarted = true;
+ }
+ }
+
+ if (!useMidiFlag || !this.enabled || this.cdInDrive && !this.allowMIDIAnyway) {
+ this.killMidi();
+ }
+ }
+
+ public void setMidiFlag(boolean f) {
+ useMidiFlag = f;
+ IniFile.gamma().setIniInt("MIDIONSTART", useMidiFlag ? 1 : 0);
+ }
+
+ @Override
+ public void mainCallback() {
+ if (this.performedStartupPlay) {
+ this.useMidi();
+
+ while (this.midiPlayer != null || this.peekQueuedCommand() == 6) {
+ if (this.cdInDrive && this.repeatingTrack != -1) {
+ if (this.peekQueuedCommand() == 6) {
+ this.getQueuedCommand(true);
+ }
+
+ this.allowMIDIAnyway = false;
+ this.useMidi();
+ return;
+ }
+
+ int command;
+ if ((command = this.getQueuedCommand(true)) < 0) {
+ return;
+ }
+
+ switch (command) {
+ case 0:
+ case 2:
+ this.midiPaused = true;
+ this.midiPlayer.stop();
+ this.midiStarted = false;
+ break;
+ case 1:
+ if (this.midiPaused || !this.midiStarted) {
+ this.midiPaused = false;
+ this.startMidi();
+ }
+ break;
+ case 3:
+ case 4:
+ this.startMidi();
+ break;
+ case 5:
+ case 6:
+ if (useMidiFlag && this.enabled) {
+ this.midiStarted = false;
+ this.midiPaused = false;
+ this.startMidi();
+ }
+ }
+ }
+ }
+ }
+
+ private synchronized void timedWait(int secs) {
+ if (!this.cancel) {
+ try {
+ this.wait(secs * 1000);
+ } catch (InterruptedException var3) {
+ }
+ }
+ }
+
+ @Override
+ public void terminalCallback() {
+ this.cancel = true;
+ this.killMidi();
+ synchronized (this) {
+ this.notify();
+ }
+
+ synchronized (this.tracksMutex) {
+ this.tracksMutex.notify();
+ }
+ }
+
+ private static String fmt2(int val) {
+ return val < 10 ? "0" + val : "" + val;
+ }
+
+ private static String fmtFrames(int frames) {
+ if (frames < 0) {
+ frames = 0;
+ }
+
+ int minutes = frames / 4500;
+ frames -= minutes * 4500;
+ int seconds = frames / 75;
+ return "[" + fmt2(minutes) + ":" + fmt2(seconds) + "]";
+ }
+}