1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-10-01 08:20:47 +00:00

Account for the game being paused when tracking sound progress

When the game is paused in SSP world, speakers are not ticked. However,
System.nanoTime() continues to increase, which means the next tick
speakers believe there has been a big jump and so schedule a bunch of
extra audio.

To avoid this, we keep track of how long the game has been paused offset
nanoTime by that amount.

Fixes #994
This commit is contained in:
Jonathan Coates 2021-12-19 16:29:06 +00:00
parent 0477b2742c
commit 8a1067940d
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
3 changed files with 58 additions and 3 deletions

View File

@ -7,6 +7,7 @@ package dan200.computercraft.shared.peripheral.speaker;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaTable;
import dan200.computercraft.shared.util.PauseAwareTimer;
import net.minecraft.util.math.MathHelper;
import javax.annotation.Nonnull;
@ -36,7 +37,7 @@ class DfpwmState
private boolean previousBit = false;
private boolean unplayed = true;
private long clientEndTime = System.nanoTime();
private long clientEndTime = PauseAwareTimer.getTime();
private float pendingVolume = 1.0f;
private ByteBuffer pendingAudio;
@ -107,7 +108,7 @@ class DfpwmState
boolean isPlaying()
{
return unplayed || clientEndTime >= System.nanoTime();
return unplayed || clientEndTime >= PauseAwareTimer.getTime();
}
float getVolume()

View File

@ -17,6 +17,7 @@ import dan200.computercraft.shared.network.client.SpeakerAudioClientMessage;
import dan200.computercraft.shared.network.client.SpeakerMoveClientMessage;
import dan200.computercraft.shared.network.client.SpeakerPlayClientMessage;
import dan200.computercraft.shared.network.client.SpeakerStopClientMessage;
import dan200.computercraft.shared.util.PauseAwareTimer;
import net.minecraft.network.play.server.SPlaySoundPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.state.properties.NoteBlockInstrument;
@ -119,7 +120,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
return;
}
long now = System.nanoTime();
long now = PauseAwareTimer.getTime();
if( sound != null )
{
lastPlayTime = clock;

View File

@ -0,0 +1,53 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.util;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Util;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
/**
* A monotonically increasing clock which accounts for the game being paused.
*/
@Mod.EventBusSubscriber( Dist.CLIENT )
public final class PauseAwareTimer
{
private static boolean paused;
private static long pauseTime;
private static long pauseOffset;
private PauseAwareTimer()
{
}
public static long getTime()
{
return (paused ? pauseTime : Util.getNanos()) - pauseOffset;
}
@SubscribeEvent
public static void tick( TickEvent.RenderTickEvent event )
{
if( event.phase != TickEvent.Phase.START ) return;
boolean isPaused = Minecraft.getInstance().isPaused();
if( isPaused == paused ) return;
if( isPaused )
{
pauseTime = Util.getNanos();
paused = true;
}
else
{
pauseOffset += Util.getNanos() - pauseTime;
paused = false;
}
}
}