2025-03-11 00:23:54 +01:00
|
|
|
package game.init;
|
|
|
|
|
|
|
|
import java.io.BufferedInputStream;
|
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2025-03-21 13:08:55 +01:00
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.nio.ShortBuffer;
|
|
|
|
|
|
|
|
import org.lwjgl.BufferUtils;
|
|
|
|
import org.lwjgl.util.opus.OpusFile;
|
2025-03-11 00:23:54 +01:00
|
|
|
|
2025-03-11 10:26:48 +01:00
|
|
|
import game.log.Log;
|
2025-03-11 00:23:54 +01:00
|
|
|
import game.rng.Random;
|
2025-03-11 10:26:48 +01:00
|
|
|
import game.util.FileUtils;
|
2025-03-11 00:23:54 +01:00
|
|
|
|
|
|
|
public enum SoundEvent {
|
|
|
|
CLOTH("cloth1", "cloth2", "cloth3", "cloth4"),
|
|
|
|
GRASS("grass1", "grass2", "grass3", "grass4"),
|
|
|
|
GRAVEL("gravel1", "gravel2", "gravel3", "gravel4"),
|
|
|
|
SAND("sand1", "sand2", "sand3", "sand4"),
|
|
|
|
SNOW("snow1", "snow2", "snow3", "snow4"),
|
|
|
|
STONE("stone1", "stone2", "stone3", "stone4"),
|
|
|
|
WOOD("wood1", "wood2", "wood3", "wood4"),
|
|
|
|
GLASS("glass1", "glass2", "glass3"),
|
|
|
|
|
|
|
|
SPELL("spell"),
|
|
|
|
TELEPORT("teleport"),
|
|
|
|
TELEPORT_REV("teleport_back"),
|
|
|
|
FIREBALL("fireball"),
|
|
|
|
METAL("metal1", "metal2", "metal3"),
|
|
|
|
METALHIT("metalhit1", "metalhit2"),
|
|
|
|
ANVIL_BREAK("anvil_break"),
|
|
|
|
ANVIL_LAND("anvil_land"),
|
|
|
|
ANVIL_USE("anvil_use"),
|
|
|
|
THROW("bow"),
|
|
|
|
BOWHIT("bowhit1", "bowhit2", "bowhit3", "bowhit4"),
|
|
|
|
BREAK("break"),
|
|
|
|
CHESTCLOSED("chestclosed"),
|
|
|
|
CHESTOPEN("chestopen"),
|
|
|
|
CLICK("click"),
|
|
|
|
DOOR("door_close", "door_open"),
|
|
|
|
DRINK("drink"),
|
|
|
|
EAT("eat1", "eat2", "eat3"),
|
|
|
|
EXPLODE("explode1", "explode2", "explode3", "explode4"),
|
|
|
|
EXPLODE_ALT("old_explode"),
|
|
|
|
FIZZ("fizz"),
|
|
|
|
FUSE("fuse"),
|
|
|
|
LEVELUP("levelup"),
|
|
|
|
ORB("orb"),
|
|
|
|
POP("pop"),
|
|
|
|
SPLASH("splash"),
|
|
|
|
FALL_BIG("fallbig1", "fallbig2"),
|
|
|
|
FALL_SMALL("fallsmall"),
|
|
|
|
HIT("hit1", "hit2", "hit3"),
|
|
|
|
IGNITE("ignite"),
|
|
|
|
FIRE("fire"),
|
|
|
|
RAIN("rain1", "rain2", "rain3", "rain4"),
|
|
|
|
THUNDER("thunder1", "thunder2", "thunder3"),
|
|
|
|
PISTON_IN("piston_in"),
|
|
|
|
PISTON_OUT("piston_out"),
|
|
|
|
CART("minecart_base"),
|
|
|
|
CART_INSIDE("minecart_inside"),
|
|
|
|
MOLTEN("molten"),
|
|
|
|
MOLTEN_POP("magmapop"),
|
|
|
|
LAVA("lava"),
|
|
|
|
LAVA_POP("lavapop"),
|
|
|
|
WATER("water"),
|
|
|
|
NOTE("note"),
|
|
|
|
BLAST_SMALL("blast"),
|
|
|
|
BLAST_SMALL_FAR("blast_far"),
|
|
|
|
BLAST_LARGE("large_blast"),
|
|
|
|
BLAST_LARGE_FAR("large_blast_far"),
|
|
|
|
LAUNCH("launch"),
|
|
|
|
TWINKLE("twinkle"),
|
|
|
|
TWINKLE_FAR("twinkle_far"),
|
|
|
|
PLOP("plop"),
|
|
|
|
CUT("cut"),
|
|
|
|
|
|
|
|
BAT_DEATH("bat_death"),
|
|
|
|
BAT_HIT("bat_hurt1", "bat_hurt2", "bat_hurt3", "bat_hurt4"),
|
|
|
|
BAT_IDLE("bat_idle1", "bat_idle2", "bat_idle3", "bat_idle4"),
|
|
|
|
BAT_TAKEOFF("bat_takeoff"),
|
|
|
|
|
|
|
|
CAT_HIT("cat_hitt1", "cat_hitt2", "cat_hitt3"),
|
|
|
|
CAT_MEOW("cat_meow1", "cat_meow2", "cat_meow3", "cat_meow4"),
|
|
|
|
CAT_PURREOW("cat_purreow1", "cat_purreow2"),
|
|
|
|
|
|
|
|
CHICKEN_HIT("chicken_hurt1", "chicken_hurt2"),
|
|
|
|
CHICKEN_IDLE("chicken_say1", "chicken_say2", "chicken_say3"),
|
|
|
|
|
|
|
|
COW_HIT("cow_hurt1", "cow_hurt2", "cow_hurt3"),
|
|
|
|
COW_IDLE("cow_say1", "cow_say2", "cow_say3", "cow_say4"),
|
|
|
|
|
|
|
|
DRAGON_IDLE("dragon_growl1", "dragon_growl2", "dragon_growl3", "dragon_growl4"),
|
|
|
|
DRAGON_WINGS("dragon_wings1", "dragon_wings2", "dragon_wings3", "dragon_wings4", "dragon_wings5", "dragon_wings6"),
|
|
|
|
|
|
|
|
HORSE_ANGRY("horse_angry"),
|
|
|
|
HORSE_BREATHE("horse_breathe1", "horse_breathe2", "horse_breathe3"),
|
|
|
|
HORSE_DEATH("horse_death"),
|
|
|
|
HORSE_GALLOP("horse_gallop1", "horse_gallop2", "horse_gallop3", "horse_gallop4"),
|
|
|
|
HORSE_HIT("horse_hit1", "horse_hit2", "horse_hit3", "horse_hit4"),
|
|
|
|
HORSE_IDLE("horse_idle1", "horse_idle2", "horse_idle3"),
|
|
|
|
HORSE_JUMP("horse_jump"),
|
|
|
|
HORSE_LAND("horse_land"),
|
|
|
|
HORSE_SOFT("horse_soft1", "horse_soft2", "horse_soft3", "horse_soft4", "horse_soft5", "horse_soft6"),
|
|
|
|
HORSE_WOOD("horse_wood1", "horse_wood2", "horse_wood3", "horse_wood4", "horse_wood5", "horse_wood6"),
|
|
|
|
|
|
|
|
PIG_DEATH("pig_death"),
|
|
|
|
PIG_IDLE("pig_say1", "pig_say2", "pig_say3"),
|
|
|
|
|
|
|
|
RABBIT_HIT("rabbit_hurt1", "rabbit_hurt2", "rabbit_hurt3", "rabbit_hurt4"),
|
|
|
|
RABBIT_IDLE("rabbit_idle1", "rabbit_idle2", "rabbit_idle3", "rabbit_idle4"),
|
|
|
|
RABBIT_DEATH("rabbit_bunnymurder"),
|
|
|
|
RABBIT_JUMP("rabbit_hop1", "rabbit_hop2", "rabbit_hop3", "rabbit_hop4"),
|
|
|
|
|
|
|
|
SHEEP_IDLE("sheep_say1", "sheep_say2", "sheep_say3"),
|
|
|
|
|
|
|
|
WOLF_BARK("wolf_bark1", "wolf_bark2", "wolf_bark3"),
|
|
|
|
WOLF_DEATH("wolf_death"),
|
|
|
|
WOLF_GROWL("wolf_growl1", "wolf_growl2", "wolf_growl3"),
|
|
|
|
WOLF_HURT("wolf_hurt1", "wolf_hurt2", "wolf_hurt3"),
|
|
|
|
WOLF_PANTING("wolf_panting"),
|
|
|
|
WOLF_SHAKE("wolf_shake"),
|
|
|
|
WOLF_WHINE("wolf_whine"),
|
|
|
|
|
|
|
|
SLIME_ATTACK("slime_attack1", "slime_attack2"),
|
|
|
|
SLIME_BIG("slime_big1", "slime_big2", "slime_big3", "slime_big4"),
|
|
|
|
SLIME_SMALL("slime_small1", "slime_small2", "slime_small3", "slime_small4", "slime_small5");
|
|
|
|
|
|
|
|
private static final Random RANDOM = new Random();
|
|
|
|
|
|
|
|
private final String[] sounds;
|
|
|
|
private final short[][] buffers;
|
|
|
|
|
|
|
|
public static void loadSounds() {
|
|
|
|
int n = 0;
|
|
|
|
for(SoundEvent entry : SoundEvent.values()) {
|
|
|
|
for(int z = 0; z < entry.sounds.length; z++) {
|
|
|
|
String sound = entry.sounds[z];
|
|
|
|
Log.SOUND.trace("Lade Sound %s", sound);
|
2025-03-21 13:08:55 +01:00
|
|
|
entry.buffers[z] = readOpus("sounds/" + sound + ".opus");
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-03-21 13:08:55 +01:00
|
|
|
private static short[] readOpus(String filename) {
|
|
|
|
InputStream in = null;
|
|
|
|
byte[] data;
|
2025-03-11 00:23:54 +01:00
|
|
|
try {
|
2025-03-21 13:08:55 +01:00
|
|
|
in = new BufferedInputStream(FileUtils.getResource(filename));
|
|
|
|
data = FileUtils.readBytes(in);
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
catch(FileNotFoundException e) {
|
2025-03-21 13:08:55 +01:00
|
|
|
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Datei nicht gefunden", filename);
|
|
|
|
return null;
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
catch(IOException e) {
|
2025-03-21 13:08:55 +01:00
|
|
|
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': %s", filename, e.getMessage());
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
finally {
|
|
|
|
try {
|
|
|
|
if(in != null)
|
|
|
|
in.close();
|
|
|
|
}
|
|
|
|
catch(IOException e) {
|
|
|
|
}
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
2025-03-21 13:08:55 +01:00
|
|
|
ByteBuffer buf = BufferUtils.createByteBuffer(data.length);
|
|
|
|
buf.put(data);
|
|
|
|
buf.flip();
|
|
|
|
long fd = OpusFile.op_open_memory(buf, null);
|
|
|
|
if(fd == 0L) {
|
|
|
|
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Falsches oder fehlerhaftes Format", filename);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if(OpusFile.op_channel_count(fd, -1) != 1) {
|
|
|
|
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': Falsches Anzahl von Kanälen (!= 1)", filename);
|
|
|
|
OpusFile.op_free(fd);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
long samples = OpusFile.op_pcm_total(fd, -1);
|
|
|
|
if(samples < 0L) {
|
|
|
|
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': E/A-Fehler", filename);
|
|
|
|
OpusFile.op_free(fd);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
ShortBuffer pcm = BufferUtils.createShortBuffer((int)samples);
|
|
|
|
int state;
|
|
|
|
while((state = OpusFile.op_read(fd, pcm, null)) > 0L) {
|
|
|
|
pcm.position(pcm.position() + state);
|
|
|
|
}
|
|
|
|
if(state < 0L) {
|
|
|
|
Log.IO.error("Fehler beim Lesen von OPUS-Datei '%s': E/A-Fehler", filename);
|
|
|
|
OpusFile.op_free(fd);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
OpusFile.op_free(fd);
|
|
|
|
short[] decoded = new short[(int)samples];
|
|
|
|
pcm.rewind();
|
|
|
|
pcm.get(decoded);
|
|
|
|
return decoded;
|
2025-03-11 00:23:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private SoundEvent(String ... sounds) {
|
|
|
|
this.sounds = sounds;
|
|
|
|
this.buffers = new short[sounds.length][];
|
|
|
|
}
|
|
|
|
|
|
|
|
public short[] getBuffer() {
|
|
|
|
return RANDOM.pick(this.buffers);
|
|
|
|
}
|
|
|
|
}
|