From f566d62bd86a4f00fb0531998073c86a7f75acec Mon Sep 17 00:00:00 2001 From: Sen Date: Wed, 3 Sep 2025 22:09:35 +0200 Subject: [PATCH] add MIDI compat options + fix gui --- client/src/main/java/client/Client.java | 4 ++++ .../src/main/java/client/audio/MidiDecoder.java | 6 +++--- .../src/main/java/client/audio/MidiHandle.java | 16 +++++++++++----- client/src/main/java/client/gui/GuiPlayer.java | 14 +++++++++----- .../main/java/client/gui/options/GuiSound.java | 3 +++ 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/client/src/main/java/client/Client.java b/client/src/main/java/client/Client.java index d54766e2..0288d071 100755 --- a/client/src/main/java/client/Client.java +++ b/client/src/main/java/client/Client.java @@ -680,6 +680,10 @@ public class Client implements IThreadListener { public boolean midiDebug = false; @Variable(name = "mid_visualizer", category = CVarCategory.SOUND, display = "Visualisation") public boolean midiVisualizer = true; + @Variable(name = "mid_ch_16_workaround", category = CVarCategory.SOUND, display = "Kanal 16 als Perkussion") + public boolean midiCh16Drums = false; + @Variable(name = "mid_allow_switch_perc_ch", category = CVarCategory.SOUND, display = "Perk.-Kanäle änderbar") + public boolean midiDrumProgs = false; @Variable(name = "draw_use_shader", category = CVarCategory.RENDER, display = "Shader verwenden") public boolean useShader = false; diff --git a/client/src/main/java/client/audio/MidiDecoder.java b/client/src/main/java/client/audio/MidiDecoder.java index e54029cf..6f2b756e 100644 --- a/client/src/main/java/client/audio/MidiDecoder.java +++ b/client/src/main/java/client/audio/MidiDecoder.java @@ -161,7 +161,7 @@ public class MidiDecoder { return value; } - public MidiDecoder(byte[] data, boolean nowait, int voices, MidiBank bank, boolean keep, boolean useunkn, int velofunc) throws IOException { + public MidiDecoder(byte[] data, boolean nowait, int voices, MidiBank bank, boolean keep, boolean useunkn, boolean percsw, int velofunc, int[] percussion) throws IOException { int size = data.length; if(size < 14) { throw new IOException("Datei zu klein"); @@ -222,7 +222,7 @@ public class MidiDecoder { this.nowait = nowait; this.setTempo(500000); this.chip = new OPLChip(48000, voices, velofunc, 0, false, false); - this.bank = new MidiHandle(this.chip, bank.getData(), keep, useunkn); + this.bank = new MidiHandle(this.chip, bank.getData(), keep, useunkn, percsw, percussion); this.playing = true; } @@ -231,7 +231,7 @@ public class MidiDecoder { this.tpqn = note; this.nowait = false; this.chip = new OPLChip(48000, 16, 0, 0, false, false); - this.bank = new MidiHandle(this.chip, bank.getData(), false, true); + this.bank = new MidiHandle(this.chip, bank.getData(), false, true, false, new int[] {10}); this.ticktime = start; this.uspb = end; this.time = (long)delay * 1000000L; diff --git a/client/src/main/java/client/audio/MidiHandle.java b/client/src/main/java/client/audio/MidiHandle.java index b08bbcb2..752c4106 100644 --- a/client/src/main/java/client/audio/MidiHandle.java +++ b/client/src/main/java/client/audio/MidiHandle.java @@ -57,17 +57,23 @@ public class MidiHandle { public final Instrument[] instruments; public final boolean keep; public final boolean useunkn; + public final boolean percsw; + public final boolean[] percussion = new boolean[16]; public int index; public int used; - public MidiHandle(OPLChip chip, Instrument[] instr, boolean keep, boolean useunkn) { + public MidiHandle(OPLChip chip, Instrument[] instr, boolean keep, boolean useunkn, boolean percsw, int[] percussion) { this.keep = keep; this.useunkn = useunkn; + this.percsw = percsw; this.instruments = instr; this.voices = new Voice[chip.channel.length]; + for(int ch : percussion) { + this.percussion[ch - 1] = true; + } for(int z = 0; z < this.channels.length; z++) { - this.channels[z] = new Channel(z == 9); + this.channels[z] = new Channel(this.percussion[z]); } for(int z = 0; z < this.voices.length; z++) { this.voices[z] = new Voice(chip.channel[z]); @@ -252,7 +258,7 @@ public class MidiHandle { // ch.pbank = 128; // } // else { - if(channel != 9) { + if(this.percsw || !this.percussion[channel]) { ch.pbank &= 0x007f; ch.pbank |= (value << 7) & 0x3f80; } @@ -263,7 +269,7 @@ public class MidiHandle { // ch.pbank = 128; // } // else { - if(channel != 9) { + if(this.percsw || !this.percussion[channel]) { ch.pbank &= 0x3f80; ch.pbank |= value & 0x007f; } @@ -278,7 +284,7 @@ public class MidiHandle { this.levelupdate(ch); break; case 0x79: // reset - ch.pbank = (channel == 9) ? 128 : 0; + ch.pbank = this.percussion[channel] ? 128 : 0; ch.volume = 127; ch.pan = 0; this.progupdate(ch); diff --git a/client/src/main/java/client/gui/GuiPlayer.java b/client/src/main/java/client/gui/GuiPlayer.java index bf8f6d7c..317a52a0 100644 --- a/client/src/main/java/client/gui/GuiPlayer.java +++ b/client/src/main/java/client/gui/GuiPlayer.java @@ -33,7 +33,7 @@ public class GuiPlayer extends GuiList { } public void draw(int x, int y, int width, int height, int mouseX, int mouseY, boolean hovered) { - Drawing.drawText(this.file.getName(), x + 3, y, GuiPlayer.this.playing && GuiPlayer.this.entry == this ? (GuiPlayer.this.paused != null ? 0xffffff00 : 0xff00ff00) : 0xffffffff); + Drawing.drawText(this.file.getName(), x + 3, y, GuiPlayer.this.playing && this.file.equals(GuiPlayer.this.entry) ? (GuiPlayer.this.paused != null ? 0xffffff00 : 0xff00ff00) : 0xffffffff); } public void select(boolean dclick, int mx, int my) { @@ -223,7 +223,7 @@ public class GuiPlayer extends GuiList { private final Random rand = new Random(); private MidiDecoder paused; private int position = -1; - private SongEntry entry; + private File entry; private boolean playing; private RepeatMode mode = RepeatMode.REPEAT_OFF; private ActButton playButton; @@ -240,12 +240,16 @@ public class GuiPlayer extends GuiList { this.modeButton.setText(this.mode.display); } + private int[] getPercussionChannels() { + return this.gm.midiCh16Drums ? new int[] {10, 16} : new int[] {10}; + } + public void playMidi(int index) { this.paused = null; this.playing = true; - this.entry = this.getListEntry(this.position = index); + this.entry = this.getListEntry(this.position = index).file; this.updateDisplay(); - File file = this.entry.file; + File file = this.entry; byte[] data; try { data = Files.readAllBytes(file.toPath()); @@ -256,7 +260,7 @@ public class GuiPlayer extends GuiList { } MidiDecoder midi; try { - midi = new MidiDecoder(data, this.gm.midiNoWait, this.gm.midiVoices, this.gm.midiBank, this.gm.midiKeep, this.gm.midiUnknown, this.gm.midiVelocity); + midi = new MidiDecoder(data, this.gm.midiNoWait, this.gm.midiVoices, this.gm.midiBank, this.gm.midiKeep, this.gm.midiUnknown, this.gm.midiDrumProgs, this.gm.midiVelocity, this.getPercussionChannels()); } catch(Throwable e) { Log.SOUND.error(e, "Konnte MIDI '%s' nicht laden", file); diff --git a/client/src/main/java/client/gui/options/GuiSound.java b/client/src/main/java/client/gui/options/GuiSound.java index 95132a2b..6a328ffc 100644 --- a/client/src/main/java/client/gui/options/GuiSound.java +++ b/client/src/main/java/client/gui/options/GuiSound.java @@ -42,6 +42,9 @@ public class GuiSound extends GuiOptions { this.addSelector("mid_visualizer", 0, 190, 240, 0); this.addSelector("mid_debug_events", 242, 190, 240, 0); + this.addSelector("mid_ch_16_workaround", 0, 210, 240, 0); + this.addSelector("mid_allow_switch_perc_ch", 242, 210, 240, 0); + super.init(width, height); }