diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/CDAudio.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/CDAudio.java')
| -rw-r--r-- | NET/worlds/scape/CDAudio.java | 518 |
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) + "]"; + } +} |