Rogue: Savage Rats, a retro-themed dungeon crawler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
rogue-savage-rats/src/mightypork/gamecore/resources/audio/LazyAudio.java

249 lines
5.2 KiB

package mightypork.gamecore.resources.audio;
import java.io.IOException;
import java.io.InputStream;
import mightypork.gamecore.resources.BaseLazyResource;
import mightypork.utils.annotations.Alias;
import mightypork.utils.files.FileUtils;
import mightypork.utils.math.constraints.vect.Vect;
import org.newdawn.slick.openal.Audio;
import org.newdawn.slick.openal.SoundStore;
/**
* Wrapper class for slick audio
*
* @author Ondřej Hruška (MightyPork)
*/
@Alias(name = "Audio")
public class LazyAudio extends BaseLazyResource {
private enum PlayMode
{
EFFECT, MUSIC;
}
/** Audio resource */
private Audio backingAudio = null;
// last play options
private PlayMode mode = PlayMode.EFFECT;
private double pauseLoopPosition = 0;
private boolean looping = false;
private boolean paused = false;
private double lastPlayPitch = 1;
private double lastPlayGain = 1;
/**
* Create deferred primitive audio player
*
* @param resourceName resource to load when needed
*/
public LazyAudio(String resourceName) {
super(resourceName);
}
/**
* Pause loop (remember position and stop playing) - if was looping
*/
public void pauseLoop()
{
if (!ensureLoaded()) return;
if (isPlaying() && looping) {
pauseLoopPosition = backingAudio.getPosition();
stop();
paused = true;
}
}
/**
* Resume loop (if was paused)
*
* @return source ID
*/
public int resumeLoop()
{
if (!ensureLoaded()) return -1;
int source = -1;
if (looping && paused) {
if (mode == PlayMode.MUSIC) {
source = backingAudio.playAsMusic((float) lastPlayPitch, (float) lastPlayGain, true);
} else {
source = backingAudio.playAsSoundEffect((float) lastPlayPitch, (float) lastPlayGain, true);
}
backingAudio.setPosition((float) pauseLoopPosition);
paused = false;
}
return source;
}
@Override
protected void loadResource(String resource) throws IOException
{
final String ext = FileUtils.getExtension(resource);
try (final InputStream stream = FileUtils.getResource(resource)) {
if (ext.equalsIgnoreCase("ogg")) {
backingAudio = SoundStore.get().getOgg(resource, stream);
} else if (ext.equalsIgnoreCase("wav")) {
backingAudio = SoundStore.get().getWAV(resource, stream);
} else if (ext.equalsIgnoreCase("aif")) {
backingAudio = SoundStore.get().getAIF(resource, stream);
} else if (ext.equalsIgnoreCase("mod")) {
backingAudio = SoundStore.get().getMOD(resource, stream);
} else {
throw new RuntimeException("Invalid audio file extension.");
}
}
}
/**
* Stop playing
*/
public void stop()
{
if (!isLoaded()) return;
backingAudio.stop();
paused = false;
}
/**
* @return true if the audio is playing
*/
public boolean isPlaying()
{
if (!isLoaded()) return false;
return backingAudio.isPlaying();
}
/**
* @return trie if the audio is paused
*/
public boolean isPaused()
{
if (!isLoaded()) return false;
return backingAudio.isPaused();
}
/**
* Play as sound effect at listener position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop)
{
return playAsEffect(pitch, gain, loop, SoundSystem.getListener());
}
/**
* Play as sound effect at given X-Y position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @param x
* @param y
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y)
{
return playAsEffect(pitch, gain, loop, x, y, SoundSystem.getListener().z());
}
/**
* Play as sound effect at given position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @param x
* @param y
* @param z
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y, double z)
{
if (!ensureLoaded()) return -1;
this.lastPlayPitch = pitch;
this.lastPlayGain = gain;
looping = loop;
mode = PlayMode.EFFECT;
return backingAudio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z);
}
/**
* Play as sound effect at given position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @param pos coord
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop, Vect pos)
{
if (!ensureLoaded()) return -1;
return playAsEffect(pitch, gain, loop, pos.x(), pos.y(), pos.z());
}
/**
* Play as music using source 0.<br>
* Discouraged, since this does not allow cross-fading.
*
* @param pitch play pitch
* @param gain play gain
* @param loop looping
* @return source
*/
public int playAsMusic(double pitch, double gain, boolean loop)
{
if (!ensureLoaded()) return -1;
this.lastPlayPitch = (float) pitch;
this.lastPlayGain = (float) gain;
looping = loop;
mode = PlayMode.MUSIC;
return backingAudio.playAsMusic((float) pitch, (float) gain, loop);
}
@Override
public void destroy()
{
if (!isLoaded() || backingAudio == null) return;
backingAudio.release();
backingAudio = null;
}
}