initial commit
This commit is contained in:
parent
3c9ee26b06
commit
22186c33b9
1458 changed files with 282792 additions and 0 deletions
267
java/src/game/audio/AudioInterface.java
Normal file
267
java/src/game/audio/AudioInterface.java
Normal file
|
@ -0,0 +1,267 @@
|
|||
package game.audio;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioFormat.Encoding;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.DataLine.Info;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.SourceDataLine;
|
||||
|
||||
import game.Log;
|
||||
import game.collect.Lists;
|
||||
|
||||
public class AudioInterface implements Runnable {
|
||||
private static class Channel {
|
||||
short[] buffer;
|
||||
int pos;
|
||||
int level;
|
||||
int type;
|
||||
boolean loop;
|
||||
boolean run;
|
||||
boolean load;
|
||||
}
|
||||
|
||||
private static class Command {
|
||||
Object buffer;
|
||||
Cmd command;
|
||||
short address;
|
||||
int param;
|
||||
}
|
||||
|
||||
private static enum Cmd {
|
||||
STOP,
|
||||
QUERY,
|
||||
VOLUME,
|
||||
PLAY,
|
||||
BREAK,
|
||||
LEVEL
|
||||
};
|
||||
|
||||
private final int blocksize;
|
||||
private final int devbufsize;
|
||||
private final byte[] buffer;
|
||||
|
||||
private final Thread thread;
|
||||
private final List<Command> cmds = Lists.newArrayList();
|
||||
private final short[] volumes = new short[Volume.values().length];
|
||||
// private final int[] mix = new int[Volume.values().length];
|
||||
// private final int[] attn = new int[Volume.values().length];
|
||||
private final Channel[] channels = new Channel[32];
|
||||
|
||||
private SourceDataLine line;
|
||||
private int smppos;
|
||||
private long peak = 32767L;
|
||||
private boolean opened;
|
||||
private boolean waiting;
|
||||
|
||||
private void push(short data) {
|
||||
for(int z = 0; z < 2 * 2; z++) {
|
||||
this.buffer[this.smppos * 2 * 2 + z] = (byte)((data >> ((z & 1) * 8)) & 0xff);
|
||||
}
|
||||
this.smppos++;
|
||||
if(this.smppos == this.blocksize) {
|
||||
this.write(this.buffer, this.blocksize);
|
||||
this.smppos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void write(byte[] data, int samples) {
|
||||
if(this.line == null)
|
||||
return;
|
||||
int rc;
|
||||
int avail;
|
||||
int channels = 2;
|
||||
int offset = 0;
|
||||
samples *= 2 * 2;
|
||||
int block = this.blocksize * 2 * 2;
|
||||
while(samples > 0) {
|
||||
block = samples < block ? samples : block;
|
||||
avail = this.line.available();
|
||||
rc = this.line.write(data, offset, avail < block ? avail : block);
|
||||
// this.line.drain();
|
||||
if(rc > 0) {
|
||||
offset += rc;
|
||||
samples -= rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private short generate() {
|
||||
long mix = 0;
|
||||
long attn = 0; // (32767 * 100) / 95);
|
||||
for(int z = 0; z < this.channels.length; z++) {
|
||||
Channel ch = this.channels[z];
|
||||
if(ch.run) {
|
||||
attn += (long)ch.level * (long)this.volumes[ch.type]; // (this.attn[ch.type] * 95) / 100;
|
||||
mix += (long)ch.buffer[ch.pos] * (long)ch.level * (((long)this.volumes[ch.type] * (long)this.volumes[0]) / 32767);
|
||||
if(++ch.pos >= ch.buffer.length) {
|
||||
ch.pos = 0;
|
||||
if(!ch.loop)
|
||||
ch.run = ch.load = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// for(int z = 1; z < this.volumes.length; z++) {
|
||||
// if(this.attn[z] > 0)
|
||||
// this.mix[0] += (short)(int)(((this.mix[z] * 32767 / this.attn[z]) * (int)this.volumes[z]) / 32767);
|
||||
// }
|
||||
mix /= 32767L * 32767L;
|
||||
long amp = Math.abs(mix);
|
||||
if(amp > 32767L)
|
||||
this.peak = Math.max(this.peak, amp);
|
||||
else if(this.peak > 32767L)
|
||||
this.peak = Math.max(this.peak - 3L, 32767L);
|
||||
return (short)((mix * 32767L) / this.peak);
|
||||
// return attn == 0L ? 0 : (short)(mix / Math.min(attn, 32767L * 32767L * 2L));
|
||||
}
|
||||
|
||||
private void dispatch(Object buf, Cmd op, short addr, int param) {
|
||||
switch(op) {
|
||||
case VOLUME:
|
||||
this.volumes[addr] = (short)param;
|
||||
break;
|
||||
case PLAY:
|
||||
if(buf != null) {
|
||||
this.channels[addr].buffer = (short[])buf;
|
||||
this.channels[addr].pos = 0;
|
||||
this.channels[addr].type = param & 0xff;
|
||||
this.channels[addr].run = this.channels[addr].load = true;
|
||||
this.channels[addr].loop = (param & 0x100) != 0;
|
||||
}
|
||||
break;
|
||||
case BREAK:
|
||||
this.channels[addr].run = this.channels[addr].load = false;
|
||||
break;
|
||||
case LEVEL:
|
||||
this.channels[addr].level = param;
|
||||
break;
|
||||
case QUERY:
|
||||
this.waiting = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 48000, 16, 2, 2 * 2, 48000, false);
|
||||
Info info = new Info(SourceDataLine.class, format, this.devbufsize);
|
||||
try {
|
||||
this.line = (SourceDataLine)AudioSystem.getLine(info);
|
||||
this.line.open(format, this.devbufsize);
|
||||
}
|
||||
catch(LineUnavailableException e) {
|
||||
this.line = null;
|
||||
Log.SOUND.error(e, "Konnte Audiogerät nicht öffnen");
|
||||
}
|
||||
if(this.line != null)
|
||||
this.line.start();
|
||||
this.opened = this.line != null;
|
||||
long sampletime = 1000000000L / 48000L; // * (long)this.blocksize;
|
||||
boolean running = true;
|
||||
long elapsed = 0;
|
||||
while(running) {
|
||||
synchronized(this.cmds) {
|
||||
while(!this.cmds.isEmpty()) {
|
||||
Command cmd = this.cmds.remove(0);
|
||||
if(cmd.command == Cmd.STOP)
|
||||
running = false;
|
||||
else
|
||||
this.dispatch(cmd.buffer, cmd.command, cmd.address, cmd.param);
|
||||
}
|
||||
}
|
||||
elapsed += 1000L;
|
||||
while((elapsed >= sampletime)) {
|
||||
this.push(this.generate());
|
||||
elapsed -= sampletime;
|
||||
}
|
||||
}
|
||||
if(this.smppos != 0)
|
||||
this.write(this.buffer, this.smppos);
|
||||
if(this.line != null) {
|
||||
this.line.drain();
|
||||
this.line.stop();
|
||||
this.line.close();
|
||||
}
|
||||
this.line = null;
|
||||
this.waiting = false;
|
||||
}
|
||||
|
||||
private void instruct(Object buf, Cmd op, int addr, int param) {
|
||||
if(this.thread == null)
|
||||
return;
|
||||
Command cmd = new Command();
|
||||
cmd.command = op;
|
||||
cmd.address = (short)addr;
|
||||
cmd.param = param;
|
||||
cmd.buffer = buf;
|
||||
synchronized(this.cmds) {
|
||||
this.cmds.add(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public AudioInterface(int frames, int bufsize, boolean disabled) {
|
||||
this.blocksize = frames;
|
||||
this.devbufsize = bufsize;
|
||||
this.buffer = new byte[this.blocksize * 2 * 2];
|
||||
this.thread = disabled ? null : new Thread(this, "Audio Thread");
|
||||
for(int z = 0; z < this.channels.length; z++) {
|
||||
this.channels[z] = new Channel();
|
||||
}
|
||||
Arrays.fill(this.volumes, (short)32767);
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
if(this.thread == null)
|
||||
return false;
|
||||
this.thread.start();
|
||||
this.waiting = true;
|
||||
this.instruct(null, Cmd.QUERY, 0, 0);
|
||||
while(this.waiting) {
|
||||
try {
|
||||
Thread.sleep(1L);
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
}
|
||||
}
|
||||
return this.opened;
|
||||
}
|
||||
|
||||
public boolean end() {
|
||||
if(this.thread == null)
|
||||
return false;
|
||||
this.waiting = true;
|
||||
this.instruct(null, Cmd.STOP, 0, 0);
|
||||
while(this.waiting) {
|
||||
try {
|
||||
Thread.sleep(1L);
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
}
|
||||
}
|
||||
return this.opened;
|
||||
}
|
||||
|
||||
public void alSetVolume(Volume channel, short volume) {
|
||||
this.instruct(null, Cmd.VOLUME, channel.ordinal(), volume);
|
||||
}
|
||||
|
||||
public void alSourcePlay(int source, short[] buffer, Volume channel, boolean loop) {
|
||||
this.channels[source].load = true;
|
||||
this.instruct(buffer, Cmd.PLAY, source, channel.ordinal() | (loop ? 0x100 : 0));
|
||||
}
|
||||
|
||||
public void alSourceStop(int source) {
|
||||
this.channels[source].load = false;
|
||||
this.instruct(null, Cmd.BREAK, source, 0);
|
||||
}
|
||||
|
||||
public boolean alPlaying(int source) {
|
||||
return this.channels[source].load;
|
||||
}
|
||||
|
||||
public void alGain(int source, float value) {
|
||||
this.instruct(null, Cmd.LEVEL, source, (int)(value * 32767.0f));
|
||||
}
|
||||
}
|
3000
java/src/game/audio/Midi.java
Normal file
3000
java/src/game/audio/Midi.java
Normal file
File diff suppressed because it is too large
Load diff
20
java/src/game/audio/MovingSound.java
Executable file
20
java/src/game/audio/MovingSound.java
Executable file
|
@ -0,0 +1,20 @@
|
|||
package game.audio;
|
||||
|
||||
import game.init.SoundEvent;
|
||||
|
||||
public abstract class MovingSound extends Sound
|
||||
{
|
||||
protected boolean donePlaying = false;
|
||||
|
||||
protected MovingSound(SoundEvent event)
|
||||
{
|
||||
super(event);
|
||||
}
|
||||
|
||||
public boolean isDonePlaying()
|
||||
{
|
||||
return this.donePlaying;
|
||||
}
|
||||
|
||||
public abstract void update();
|
||||
}
|
48
java/src/game/audio/MovingSoundMinecart.java
Executable file
48
java/src/game/audio/MovingSoundMinecart.java
Executable file
|
@ -0,0 +1,48 @@
|
|||
package game.audio;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.entity.item.EntityCart;
|
||||
import game.init.SoundEvent;
|
||||
|
||||
public class MovingSoundMinecart extends MovingSound
|
||||
{
|
||||
private final EntityCart minecart;
|
||||
private float distance = 0.0F;
|
||||
|
||||
public MovingSoundMinecart(EntityCart minecartIn)
|
||||
{
|
||||
super(SoundEvent.CART);
|
||||
this.minecart = minecartIn;
|
||||
this.repeat = true;
|
||||
// this.repeatDelay = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the old updateEntity(), except more generic.
|
||||
*/
|
||||
public void update()
|
||||
{
|
||||
if (this.minecart.dead)
|
||||
{
|
||||
this.donePlaying = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.xPosF = (float)this.minecart.posX;
|
||||
this.yPosF = (float)this.minecart.posY;
|
||||
this.zPosF = (float)this.minecart.posZ;
|
||||
float f = ExtMath.sqrtd(this.minecart.motionX * this.minecart.motionX + this.minecart.motionZ * this.minecart.motionZ);
|
||||
|
||||
if ((double)f >= 0.01D)
|
||||
{
|
||||
this.distance = ExtMath.clampf(this.distance + 0.0025F, 0.0F, 1.0F);
|
||||
this.volume = 0.0F + ExtMath.clampf(f, 0.0F, 0.5F) * 0.7F;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.distance = 0.0F;
|
||||
this.volume = 0.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
46
java/src/game/audio/MovingSoundMinecartRiding.java
Executable file
46
java/src/game/audio/MovingSoundMinecartRiding.java
Executable file
|
@ -0,0 +1,46 @@
|
|||
package game.audio;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.entity.item.EntityCart;
|
||||
import game.entity.npc.EntityNPC;
|
||||
import game.init.SoundEvent;
|
||||
|
||||
public class MovingSoundMinecartRiding extends MovingSound
|
||||
{
|
||||
private final EntityNPC player;
|
||||
private final EntityCart minecart;
|
||||
|
||||
public MovingSoundMinecartRiding(EntityNPC playerRiding, EntityCart minecart)
|
||||
{
|
||||
super(SoundEvent.CART_INSIDE);
|
||||
this.player = playerRiding;
|
||||
this.minecart = minecart;
|
||||
this.attenuationType = false;
|
||||
this.repeat = true;
|
||||
// this.repeatDelay = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the old updateEntity(), except more generic.
|
||||
*/
|
||||
public void update()
|
||||
{
|
||||
if (!this.minecart.dead && this.player.isRiding() && this.player.vehicle == this.minecart)
|
||||
{
|
||||
float f = ExtMath.sqrtd(this.minecart.motionX * this.minecart.motionX + this.minecart.motionZ * this.minecart.motionZ);
|
||||
|
||||
if ((double)f >= 0.01D)
|
||||
{
|
||||
this.volume = 0.0F + ExtMath.clampf(f, 0.0F, 1.0F) * 0.75F;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.volume = 0.0F;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.donePlaying = true;
|
||||
}
|
||||
}
|
||||
}
|
33
java/src/game/audio/PositionedSound.java
Executable file
33
java/src/game/audio/PositionedSound.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
package game.audio;
|
||||
|
||||
import game.init.SoundEvent;
|
||||
|
||||
public class PositionedSound extends Sound
|
||||
{
|
||||
// public PositionedSound(SoundEvent event, float pitch)
|
||||
// {
|
||||
// this(event, 0.25F, pitch, false, false, 0.0F, 0.0F, 0.0F);
|
||||
// }
|
||||
|
||||
public PositionedSound(SoundEvent event)
|
||||
{
|
||||
this(event, 1.0F, false, 0.0F, 0.0F, 0.0F);
|
||||
}
|
||||
|
||||
public PositionedSound(SoundEvent event, float volume, float xPosition, float yPosition, float zPosition)
|
||||
{
|
||||
this(event, volume, true, xPosition, yPosition, zPosition);
|
||||
}
|
||||
|
||||
private PositionedSound(SoundEvent event, float volume, boolean attenuationType, float xPosition, float yPosition, float zPosition)
|
||||
{
|
||||
super(event);
|
||||
this.volume = volume;
|
||||
// this.pitch = pitch;
|
||||
this.xPosF = xPosition;
|
||||
this.yPosF = yPosition;
|
||||
this.zPosF = zPosition;
|
||||
this.repeat = false;
|
||||
this.attenuationType = attenuationType;
|
||||
}
|
||||
}
|
66
java/src/game/audio/Sound.java
Executable file
66
java/src/game/audio/Sound.java
Executable file
|
@ -0,0 +1,66 @@
|
|||
package game.audio;
|
||||
|
||||
import game.init.SoundEvent;
|
||||
|
||||
public abstract class Sound
|
||||
{
|
||||
protected final SoundEvent event;
|
||||
protected Volume type = Volume.SFX;
|
||||
protected float volume = 1.0F;
|
||||
// protected float pitch = 1.0F;
|
||||
protected float xPosF;
|
||||
protected float yPosF;
|
||||
protected float zPosF;
|
||||
protected boolean repeat = false;
|
||||
protected boolean attenuationType = true;
|
||||
|
||||
protected Sound(SoundEvent event)
|
||||
{
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public SoundEvent getSoundLocation()
|
||||
{
|
||||
return this.event;
|
||||
}
|
||||
|
||||
public boolean canRepeat()
|
||||
{
|
||||
return this.repeat;
|
||||
}
|
||||
|
||||
public float getVolume()
|
||||
{
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
// public float getPitch()
|
||||
// {
|
||||
// return this.pitch;
|
||||
// }
|
||||
|
||||
public float getXPosF()
|
||||
{
|
||||
return this.xPosF;
|
||||
}
|
||||
|
||||
public float getYPosF()
|
||||
{
|
||||
return this.yPosF;
|
||||
}
|
||||
|
||||
public float getZPosF()
|
||||
{
|
||||
return this.zPosF;
|
||||
}
|
||||
|
||||
public boolean getAttenuationType()
|
||||
{
|
||||
return this.attenuationType;
|
||||
}
|
||||
|
||||
public Volume getChannelType()
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
}
|
246
java/src/game/audio/SoundManager.java
Executable file
246
java/src/game/audio/SoundManager.java
Executable file
|
@ -0,0 +1,246 @@
|
|||
package game.audio;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import game.ExtMath;
|
||||
import game.Game;
|
||||
import game.collect.BiMap;
|
||||
import game.collect.HashBiMap;
|
||||
import game.collect.Lists;
|
||||
import game.collect.Maps;
|
||||
import game.entity.npc.EntityNPC;
|
||||
|
||||
public class SoundManager {
|
||||
private class Source {
|
||||
private final boolean attModel;
|
||||
private final float distOrRoll;
|
||||
// private final short[] buffer;
|
||||
private final int source;
|
||||
|
||||
private float positionX;
|
||||
private float positionY;
|
||||
private float positionZ;
|
||||
private float volume;
|
||||
|
||||
public Source(short[] buffer, Volume type, boolean toLoop, String sourcename, float x, float y, float z, boolean attModel,
|
||||
float distOrRoll, float volume) {
|
||||
this.positionX = x;
|
||||
this.positionY = y;
|
||||
this.positionZ = z;
|
||||
this.attModel = attModel;
|
||||
this.distOrRoll = distOrRoll;
|
||||
// this.buffer = buffer;
|
||||
this.volume = volume;
|
||||
this.source = SoundManager.this.getNextChannel(sourcename);
|
||||
updateGain();
|
||||
SoundManager.this.gm.getAudioInterface().alSourcePlay(this.source, buffer, type, toLoop);
|
||||
}
|
||||
|
||||
public void updateGain() {
|
||||
float gain;
|
||||
if(attModel) {
|
||||
double dX = positionX - SoundManager.this.listenerX;
|
||||
double dY = positionY - SoundManager.this.listenerY;
|
||||
double dZ = positionZ - SoundManager.this.listenerZ;
|
||||
float dist = (float)Math.sqrt(dX * dX + dY * dY + dZ * dZ);
|
||||
if(dist <= 0) {
|
||||
gain = 1.0f;
|
||||
}
|
||||
else if(dist >= distOrRoll) {
|
||||
gain = 0.0f;
|
||||
}
|
||||
else {
|
||||
gain = 1.0f - (dist / distOrRoll);
|
||||
}
|
||||
if(gain > 1.0f)
|
||||
gain = 1.0f;
|
||||
if(gain < 0.0f)
|
||||
gain = 0.0f;
|
||||
}
|
||||
else {
|
||||
gain = 1.0f;
|
||||
}
|
||||
SoundManager.this.gm.getAudioInterface().alGain(source, (gain * volume));
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, Sound> playingSounds = HashBiMap.<String, Sound>create();
|
||||
private final Map<Sound, String> invPlayingSounds = ((BiMap)this.playingSounds).inverse();
|
||||
private final List<MovingSound> tickableSounds = Lists.<MovingSound>newArrayList();
|
||||
private final Map<String, Integer> playingSoundsStopTime = Maps.<String, Integer>newHashMap();
|
||||
private final Map<String, Source> sources = new HashMap<String, Source>();
|
||||
private final String[] channels = new String[28];
|
||||
private final Game gm;
|
||||
|
||||
private float listenerX;
|
||||
private float listenerY;
|
||||
private float listenerZ;
|
||||
private int nextChannel = 0;
|
||||
private int playTime = 0;
|
||||
private int eventId = 0;
|
||||
|
||||
public SoundManager(Game gm) {
|
||||
this.gm = gm;
|
||||
}
|
||||
|
||||
public void unload()
|
||||
{
|
||||
this.stopSounds();
|
||||
for(int x = 0; x < this.channels.length; x++) {
|
||||
channels[x] = null;
|
||||
}
|
||||
this.sources.clear();
|
||||
this.nextChannel = 0;
|
||||
this.eventId = 0;
|
||||
}
|
||||
|
||||
public void stopSounds()
|
||||
{
|
||||
for (String s : this.playingSounds.keySet())
|
||||
{
|
||||
Source src = sources.get(s);
|
||||
if(src != null)
|
||||
this.gm.getAudioInterface().alSourceStop(src.source);
|
||||
sources.remove(s);
|
||||
}
|
||||
this.playingSounds.clear();
|
||||
this.tickableSounds.clear();
|
||||
this.playingSoundsStopTime.clear();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
++this.playTime;
|
||||
|
||||
for (MovingSound itickablesound : this.tickableSounds)
|
||||
{
|
||||
itickablesound.update();
|
||||
|
||||
if (itickablesound.isDonePlaying())
|
||||
{
|
||||
String s = (String)this.invPlayingSounds.get(itickablesound);
|
||||
|
||||
if (s != null)
|
||||
{
|
||||
Source src = sources.get(s);
|
||||
if(src != null)
|
||||
this.gm.getAudioInterface().alSourceStop(src.source);
|
||||
sources.remove(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String s = (String)this.invPlayingSounds.get(itickablesound);
|
||||
Source source = sources.get(s);
|
||||
if(source != null) {
|
||||
source.volume = ExtMath.clampf(itickablesound.getVolume(), 0.0f, 1.0f);
|
||||
source.positionX = itickablesound.getXPosF();
|
||||
source.positionY = itickablesound.getYPosF();
|
||||
source.positionZ = itickablesound.getZPosF();
|
||||
source.updateGain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Entry<String, Sound>> iterator = this.playingSounds.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Entry<String, Sound> entry = (Entry)iterator.next();
|
||||
String s1 = (String)entry.getKey();
|
||||
Sound isound = (Sound)entry.getValue();
|
||||
|
||||
Source source = this.sources.get(s1);
|
||||
if (source == null || !this.gm.getAudioInterface().alPlaying(source.source))
|
||||
{
|
||||
int i = ((Integer)this.playingSoundsStopTime.get(s1)).intValue();
|
||||
|
||||
if (i <= this.playTime)
|
||||
{
|
||||
iterator.remove();
|
||||
this.sources.remove(s1);
|
||||
this.playingSoundsStopTime.remove(s1);
|
||||
|
||||
if (isound instanceof MovingSound)
|
||||
{
|
||||
this.tickableSounds.remove(isound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void playSound(Sound sound)
|
||||
{
|
||||
float volume = sound.getVolume();
|
||||
float attn = 16.0F;
|
||||
if (volume > 1.0F)
|
||||
attn *= volume;
|
||||
volume = ExtMath.clampf(volume, 0.0f, 1.0f);
|
||||
if (volume > 0.0F)
|
||||
{
|
||||
String s = String.format("snd-%016x", this.eventId++);
|
||||
this.sources.put(s, new Source(sound.getSoundLocation().getBuffer(), sound.getChannelType(), sound.canRepeat(), s, sound.getXPosF(), sound.getYPosF(), sound.getZPosF(), sound.getAttenuationType(), attn, volume));
|
||||
this.playingSoundsStopTime.put(s, this.playTime + 20);
|
||||
this.playingSounds.put(s, sound);
|
||||
if (sound instanceof MovingSound)
|
||||
this.tickableSounds.add((MovingSound)sound);
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(EntityNPC player, float partial)
|
||||
{
|
||||
double x = player.prevX + (player.posX - player.prevX) * (double)partial;
|
||||
double y = player.prevY + (player.posY - player.prevY) * (double)partial + (double)player.getEyeHeight();
|
||||
double z = player.prevZ + (player.posZ - player.prevZ) * (double)partial;
|
||||
this.listenerX = (float)x;
|
||||
this.listenerY = (float)y;
|
||||
this.listenerZ = (float)z;
|
||||
for(Source source : this.sources.values()) {
|
||||
source.updateGain();
|
||||
}
|
||||
}
|
||||
|
||||
private int getNextChannel(String sourcename) {
|
||||
int x;
|
||||
int next;
|
||||
String name;
|
||||
next = nextChannel;
|
||||
|
||||
int n = next;
|
||||
Source src;
|
||||
for(x = 0; x < channels.length; x++) {
|
||||
name = this.channels[n];
|
||||
src = name == null ? null : sources.get(name);
|
||||
|
||||
if(src == null || !this.gm.getAudioInterface().alPlaying(src.source)) {
|
||||
nextChannel = n + 1;
|
||||
if(nextChannel >= channels.length)
|
||||
nextChannel = 0;
|
||||
this.channels[n] = sourcename;
|
||||
if(src != null)
|
||||
this.sources.remove(name);
|
||||
return n;
|
||||
}
|
||||
n++;
|
||||
if(n >= channels.length)
|
||||
n = 0;
|
||||
}
|
||||
|
||||
n = next;
|
||||
name = this.channels[n];
|
||||
src = name == null ? null : sources.get(name);
|
||||
|
||||
nextChannel = n + 1;
|
||||
if(nextChannel >= channels.length)
|
||||
nextChannel = 0;
|
||||
this.channels[n] = sourcename;
|
||||
if(src != null)
|
||||
this.sources.remove(name);
|
||||
return n;
|
||||
}
|
||||
}
|
124
java/src/game/audio/SoundType.java
Executable file
124
java/src/game/audio/SoundType.java
Executable file
|
@ -0,0 +1,124 @@
|
|||
package game.audio;
|
||||
|
||||
import game.init.SoundEvent;
|
||||
|
||||
public class SoundType
|
||||
{
|
||||
public static final SoundType SLIME = new SoundType(SoundEvent.SLIME_BIG, SoundEvent.SLIME_SMALL, 1.0F, 1.0F);
|
||||
// {
|
||||
// public Sounds getBreakSound()
|
||||
// {
|
||||
// return "mob.slime.big";
|
||||
// }
|
||||
// public Sounds getPlaceSound()
|
||||
// {
|
||||
// return "mob.slime.big";
|
||||
// }
|
||||
// public Sounds getStepSound()
|
||||
// {
|
||||
// return "mob.slime.small";
|
||||
// }
|
||||
// };
|
||||
public static final SoundType ANVIL = new SoundType(SoundEvent.STONE, SoundEvent.ANVIL_LAND, SoundEvent.STONE, 0.3F, 1.0F);
|
||||
// {
|
||||
// public Sounds getBreakSound()
|
||||
// {
|
||||
// return "dig.stone";
|
||||
// }
|
||||
// public Sounds getPlaceSound()
|
||||
// {
|
||||
// return "random.anvil_land";
|
||||
// }
|
||||
// public Sounds getStepSound() // fix ...
|
||||
// {
|
||||
// return "dig.stone";
|
||||
// }
|
||||
// };
|
||||
public static final SoundType LADDER = new SoundType(SoundEvent.WOOD, null, 1.0F, 1.0F);
|
||||
// {
|
||||
// public Sounds getBreakSound()
|
||||
// {
|
||||
// return "dig.wood";
|
||||
// }
|
||||
// public Sounds getStepSound()
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
public static final SoundType SNOW = new SoundType(SoundEvent.SNOW, 1.0F, 1.0F);
|
||||
public static final SoundType SAND = new SoundType(SoundEvent.SAND, 1.0F, 1.0F);
|
||||
public static final SoundType CLOTH = new SoundType(SoundEvent.CLOTH, 1.0F, 1.0F);
|
||||
public static final SoundType GLASS = new SoundType(SoundEvent.GLASS, SoundEvent.STONE, SoundEvent.STONE, 1.0F, 1.0F);
|
||||
// {
|
||||
// public Sounds getBreakSound()
|
||||
// {
|
||||
// return "dig.glass";
|
||||
// }
|
||||
// public Sounds getPlaceSound()
|
||||
// {
|
||||
// return "dig.stone";
|
||||
// }
|
||||
// };
|
||||
public static final SoundType METAL = new SoundType(SoundEvent.STONE, 1.0F, 1.5F);
|
||||
public static final SoundType PISTON = new SoundType(SoundEvent.STONE, 1.0F, 1.0F);
|
||||
public static final SoundType GRASS = new SoundType(SoundEvent.GRASS /* , null */ , 1.0F, 1.0F);
|
||||
// {
|
||||
// public Sounds getStepSound()
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
public static final SoundType GRAVEL = new SoundType(SoundEvent.GRAVEL, 1.0F, 1.0F);
|
||||
public static final SoundType WOOD = new SoundType(SoundEvent.WOOD, 1.0F, 1.0F);
|
||||
public static final SoundType STONE = new SoundType(SoundEvent.STONE, 1.0F, 1.0F);
|
||||
|
||||
private final SoundEvent breakSound;
|
||||
private final SoundEvent placeSound;
|
||||
private final SoundEvent stepSound;
|
||||
private final float volume;
|
||||
// private final float frequency;
|
||||
|
||||
private SoundType(SoundEvent breakSound, SoundEvent placeSound, SoundEvent stepSound, float volume, float frequency)
|
||||
{
|
||||
this.breakSound = breakSound;
|
||||
this.placeSound = placeSound;
|
||||
this.stepSound = stepSound;
|
||||
this.volume = volume;
|
||||
// this.frequency = frequency;
|
||||
}
|
||||
|
||||
private SoundType(SoundEvent breakPlaceSound, SoundEvent stepSound, float volume, float frequency)
|
||||
{
|
||||
this(breakPlaceSound, breakPlaceSound, stepSound, volume, frequency);
|
||||
}
|
||||
|
||||
private SoundType(SoundEvent sound, float volume, float frequency)
|
||||
{
|
||||
this(sound, sound, sound, volume, frequency);
|
||||
}
|
||||
|
||||
public SoundEvent getBreakSound()
|
||||
{
|
||||
return this.breakSound;
|
||||
}
|
||||
|
||||
public SoundEvent getPlaceSound()
|
||||
{
|
||||
return this.placeSound;
|
||||
}
|
||||
|
||||
public SoundEvent getStepSound()
|
||||
{
|
||||
return this.stepSound;
|
||||
}
|
||||
|
||||
public float getVolume()
|
||||
{
|
||||
return this.volume;
|
||||
}
|
||||
|
||||
public float getFrequency()
|
||||
{
|
||||
return 1.0f; // this.frequency;
|
||||
}
|
||||
}
|
86
java/src/game/audio/Volume.java
Normal file
86
java/src/game/audio/Volume.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
package game.audio;
|
||||
|
||||
import game.CVar;
|
||||
import game.CVarCategory;
|
||||
import game.Game;
|
||||
import game.Slider;
|
||||
import game.color.TextColor;
|
||||
|
||||
public enum Volume implements CVar {
|
||||
MASTER("master", "Gesamt"),
|
||||
MUSIC("music", "Musik"),
|
||||
SFX("sfx", "Geräusche"),
|
||||
GUI("gui", "Oberfläche");
|
||||
|
||||
public final String id;
|
||||
public final String name;
|
||||
|
||||
private int value = 100;
|
||||
|
||||
private Volume(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDisplay() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getCVarName() {
|
||||
return "snd_volume_" + this.id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return TextColor.DGREEN + "volume";
|
||||
}
|
||||
|
||||
public CVarCategory getCategory() {
|
||||
return CVarCategory.SOUND;
|
||||
}
|
||||
|
||||
public boolean parse(String str) {
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt(str);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
if(value < 0 || value > 100)
|
||||
return false;
|
||||
this.value = value;
|
||||
this.apply();
|
||||
return true;
|
||||
}
|
||||
|
||||
public String format() {
|
||||
return "" + this.value;
|
||||
}
|
||||
|
||||
public String getDefault() {
|
||||
return "100";
|
||||
}
|
||||
|
||||
public void setDefault() {
|
||||
this.value = 100;
|
||||
this.apply();
|
||||
}
|
||||
|
||||
public String getValues() {
|
||||
return "0..100";
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
if(Game.getGame().getAudioInterface() != null)
|
||||
Game.getGame().getAudioInterface().alSetVolume(this, (short)(((float)this.value) / 100.0f * 32767.0f));
|
||||
}
|
||||
|
||||
public Slider selector(int x, int y, int w, int h) {
|
||||
return new Slider(x, y, w, h, 0, 0, 100, 100, this.value, new Slider.Callback() {
|
||||
public void use(Slider elem, int value) {
|
||||
Volume.this.value = value;
|
||||
Volume.this.apply();
|
||||
}
|
||||
}, this.name, "%");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue