Semmieboy YT afe3e78b0f Switched Java version to 8 so the mod works on more Minecraft versions
Made the loading of songs multithreaded, decreasing startup time of the client
Fixed a bug where incorrect instruments were getting played
Fixed a bug where the blocks overlay was unable to be closed
Fixed a bug where the mod would continue playing the song after switching worlds
Fixed a bug where note blocks with a block above them were seen as a valid note block
2022-03-06 03:10:35 +01:00

104 lines
4.6 KiB
Java

package semmieboy_yt.disc_jockey;
import semmieboy_yt.disc_jockey.gui.SongListWidget;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
public class SongLoader {
public static final ArrayList<Song> SONGS = new ArrayList<>();
public static volatile boolean loadingSongs;
public static void loadSongs() {
if (loadingSongs) return;
new Thread(() -> {
loadingSongs = true;
SONGS.clear();
for (File file : Main.songsFolder.listFiles()) {
if (file.isFile()) {
try {
BinaryReader reader = new BinaryReader(new FileInputStream(file));
Song song = new Song();
song.fileName = file.getName();
song.length = reader.readShort();
boolean newFormat = song.length == 0;
if (newFormat) {
song.formatVersion = reader.readByte();
song.vanillaInstrumentCount = reader.readByte();
song.length = reader.readShort();
}
song.height = reader.readShort();
song.name = reader.readString();
song.author = reader.readString();
song.originalAuthor = reader.readString();
song.description = reader.readString();
song.tempo = reader.readShort();
song.autoSaving = reader.readByte();
song.autoSavingDuration = reader.readByte();
song.timeSignature = reader.readByte();
song.minutesSpent = reader.readInt();
song.leftClicks = reader.readInt();
song.rightClicks = reader.readInt();
song.blocksAdded = reader.readInt();
song.blocksRemoved = reader.readInt();
song.importFileName = reader.readString();
if (newFormat) {
song.loop = reader.readByte();
song.maxLoopCount = reader.readByte();
song.loopStartTick = reader.readShort();
}
song.entry = new SongListWidget.SongEntry(song.name.replaceAll("\\s", "").isEmpty() ? song.fileName : song.name+" ("+song.fileName+")", SONGS.size());
song.searchableFileName = song.fileName.toLowerCase().replaceAll("\\s", "");
song.searchableName = song.name.toLowerCase().replaceAll("\\s", "");
short tick = -1;
short jumps;
while ((jumps = reader.readShort()) != 0) {
tick += jumps;
short layer = -1;
while ((jumps = reader.readShort()) != 0) {
layer += jumps;
byte instrumentId = reader.readByte();
byte noteId = (byte)(reader.readByte() - 33);
if (newFormat) {
// Data that is not needed as it only works with commands
reader.readByte(); // Velocity
reader.readByte(); // Panning
reader.readShort(); // Pitch
}
if (noteId < 0) {
noteId = 0;
} else if (noteId > 24) {
noteId = 24;
}
Note note = new Note(Note.INSTRUMENTS[instrumentId], noteId);
if (!song.uniqueNotes.contains(note)) song.uniqueNotes.add(note);
song.notes = Arrays.copyOf(song.notes, song.notes.length + 1);
song.notes[song.notes.length - 1] = tick | layer << Note.LAYER_SHIFT | (long)instrumentId << Note.INSTRUMENT_SHIFT | (long)noteId << Note.NOTE_SHIFT;
}
}
SONGS.add(song);
} catch (Throwable exception) {
Main.LOGGER.error("Unable to read song "+file.getName(), exception);
}
}
}
loadingSongs = false;
}).start();
}
}