Skip to content

Commit

Permalink
Fix sound effects delay (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
conker-rsc authored Nov 5, 2023
1 parent 401b65f commit 5c573c0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Client/ConfigWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ public class ConfigWindow {
private JRadioButton audioPanelOverrideAudioSettingOnButton;
private JRadioButton audioPanelOverrideAudioSettingOffButton;
private JCheckBox audioPanelFixSpiderWebDummySoundCheckbox;
private JCheckBox audioPanelFixSfxDelayCheckbox;
private JCheckBox soundEffectAdvanceCheckbox;
private JCheckBox soundEffectAnvilCheckbox;
private JCheckBox soundEffectChiselCheckbox;
Expand Down Expand Up @@ -2985,6 +2986,12 @@ public void actionPerformed(ActionEvent e) {
SearchUtils.addSearchMetadata(
audioPanelFixSpiderWebDummySoundCheckbox, CommonMetadata.SFX.getText());

audioPanelFixSfxDelayCheckbox =
addCheckbox("Remove sound effect delay (Requires restart)", audioPanel);
audioPanelFixSfxDelayCheckbox.setToolTipText(
"Fixes a bug where sound effects were delayed by a significant amount.");
SearchUtils.addSearchMetadata(audioPanelFixSfxDelayCheckbox, CommonMetadata.SFX.getText());

addSettingsHeader(audioPanel, "Toggle individual sound effects");

JPanel audioPanelEnableAllSfxPanel = new JPanel();
Expand Down Expand Up @@ -6164,6 +6171,7 @@ private void executeSynchronizeGuiValues() {
!Settings.OVERRIDE_AUDIO_SETTING_SETTING_ON.get(Settings.currentProfile));
audioPanelFixSpiderWebDummySoundCheckbox.setSelected(
Settings.SOUND_EFFECT_COMBAT1.get(Settings.currentProfile));
audioPanelFixSfxDelayCheckbox.setSelected(Settings.FIX_SFX_DELAY.get(Settings.currentProfile));
soundEffectAdvanceCheckbox.setSelected(
Settings.SOUND_EFFECT_ADVANCE.get(Settings.currentProfile));
soundEffectAnvilCheckbox.setSelected(Settings.SOUND_EFFECT_ANVIL.get(Settings.currentProfile));
Expand Down Expand Up @@ -6630,6 +6638,7 @@ private void saveSettings() {
.isSelected()); // audioPanelOverrideAudioSettingOffButton ignored
Settings.SOUND_EFFECT_COMBAT1.put(
Settings.currentProfile, audioPanelFixSpiderWebDummySoundCheckbox.isSelected());
Settings.FIX_SFX_DELAY.put(Settings.currentProfile, audioPanelFixSfxDelayCheckbox.isSelected());
Settings.SOUND_EFFECT_ADVANCE.put(
Settings.currentProfile, soundEffectAdvanceCheckbox.isSelected());
Settings.SOUND_EFFECT_ANVIL.put(Settings.currentProfile, soundEffectAnvilCheckbox.isSelected());
Expand Down
43 changes: 43 additions & 0 deletions src/Client/JClassPatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public byte[] patch(byte[] data) {
else if (node.name.equals("lb")) patchRendererHelper(node);
else if (node.name.equals("sa")) patchSoundHelper(node);
else if (node.name.equals("wb")) patchRightClickMenu(node);
else if (node.name.equals("pb")) patchSoundPlayerJava(node);

// Patch applied to all classes
patchGeneric(node);
Expand Down Expand Up @@ -5378,6 +5379,48 @@ private void patchRightClickMenu(ClassNode node) {
}
}

private void patchSoundPlayerJava(ClassNode node) {
Logger.Info("Patching java sound player (" + node.name + ".class)");

Iterator<MethodNode> methodNodeList = node.methods.iterator();
while (methodNodeList.hasNext()) {
MethodNode methodNode = methodNodeList.next();

if (Settings.FIX_SFX_DELAY.get(Settings.currentProfile)) {
if (methodNode.name.equals("b") && methodNode.desc.equals("(I)V")) {
AbstractInsnNode start = methodNode.instructions.getFirst();

while (start != null) {
if (start.getOpcode() == Opcodes.INVOKEINTERFACE) {
AbstractInsnNode insnNode = start;

methodNode.instructions.insertBefore(insnNode, new VarInsnNode(Opcodes.ALOAD, 0));
methodNode.instructions.insertBefore(
insnNode,
new FieldInsnNode(
Opcodes.GETFIELD, "pb", "y", "Ljavax/sound/sampled/AudioFormat;"));
// 0.1s delay * 22050 (sample rate) = 2205 samples * 16 bits = 35280 / 8 = 4410 bytes
methodNode.instructions.insertBefore(insnNode, new IntInsnNode(Opcodes.SIPUSH, 4410));
methodNode.instructions.insertBefore(
insnNode,
new MethodInsnNode(
Opcodes.INVOKEINTERFACE,
"javax/sound/sampled/SourceDataLine",
"open",
"(Ljavax/sound/sampled/AudioFormat;I)V",
true));
methodNode.instructions.remove(insnNode);

break;
}

start = start.getNext();
}
}
}
}
}

/**
* TODO: Complete JavaDoc
*
Expand Down
11 changes: 11 additions & 0 deletions src/Client/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ public class Settings {
public static HashMap<String, Boolean> OVERRIDE_AUDIO_SETTING = new HashMap<String, Boolean>();
public static HashMap<String, Boolean> OVERRIDE_AUDIO_SETTING_SETTING_ON =
new HashMap<String, Boolean>();
public static HashMap<String, Boolean> FIX_SFX_DELAY = new HashMap<String, Boolean>();
public static HashMap<String, Boolean> SOUND_EFFECT_COMBAT1 = new HashMap<String, Boolean>();
public static HashMap<String, Boolean> SOUND_EFFECT_ADVANCE = new HashMap<String, Boolean>();
public static HashMap<String, Boolean> SOUND_EFFECT_ANVIL = new HashMap<String, Boolean>();
Expand Down Expand Up @@ -1171,6 +1172,15 @@ public static void definePresets(Properties props) {
"custom",
getPropBoolean(props, "sound_effect_combat1", SOUND_EFFECT_COMBAT1.get("default")));

FIX_SFX_DELAY.put("vanilla", false);
FIX_SFX_DELAY.put("vanilla_resizable", false);
FIX_SFX_DELAY.put("lite", true);
FIX_SFX_DELAY.put("default", true);
FIX_SFX_DELAY.put("heavy", true);
FIX_SFX_DELAY.put("all", true);
FIX_SFX_DELAY.put(
"custom", getPropBoolean(props, "fix_sfx_delay", FIX_SFX_DELAY.get("default")));

SOUND_EFFECT_ADVANCE.put("vanilla", true);
SOUND_EFFECT_ADVANCE.put("vanilla_resizable", true);
SOUND_EFFECT_ADVANCE.put("lite", true);
Expand Down Expand Up @@ -3304,6 +3314,7 @@ public static void save(String preset) {
"override_audio_setting_setting_on",
Boolean.toString(OVERRIDE_AUDIO_SETTING_SETTING_ON.get(preset)));
props.setProperty("sound_effect_combat1", Boolean.toString(SOUND_EFFECT_COMBAT1.get(preset)));
props.setProperty("fix_sfx_delay", Boolean.toString(FIX_SFX_DELAY.get(preset)));
props.setProperty("sound_effect_advance", Boolean.toString(SOUND_EFFECT_ADVANCE.get(preset)));
props.setProperty("sound_effect_anvil", Boolean.toString(SOUND_EFFECT_ANVIL.get(preset)));
props.setProperty("sound_effect_chisel", Boolean.toString(SOUND_EFFECT_CHISEL.get(preset)));
Expand Down

0 comments on commit 5c573c0

Please sign in to comment.