Sounds/music volume is configurable between 0-100, instead of just ON/OFF. Fixes #320 and addresses #446

This commit is contained in:
UnknownShadow200 2017-06-24 21:30:30 +10:00
parent 64d68829e4
commit eadac08d0a
8 changed files with 87 additions and 59 deletions

View File

@ -21,9 +21,9 @@ namespace ClassicalSharp.Gui.Screens {
widgets = new Widget[] {
// Column 1
MakeBool(-1, -150, "Music", OptionsKey.UseMusic,
OnWidgetClick, g => g.UseMusic,
(g, v) => { g.UseMusic = v; g.AudioPlayer.SetMusic(g.UseMusic); }),
MakeVolumeBool(-1, -150, "Music", OptionsKey.MusicVolume,
g => g.MusicVolume > 0,
(g, v) => { g.MusicVolume = v ? 100 : 0; g.AudioPlayer.SetMusic(g.MusicVolume); }),
MakeBool(-1, -100, "Invert mouse", OptionsKey.InvertMouse,
OnWidgetClick, g => g.InvertMouse, (g, v) => g.InvertMouse = v),
@ -38,9 +38,9 @@ namespace ClassicalSharp.Gui.Screens {
(g, v) => ((SinglePlayerServer)network).physics.Enabled = v),
// Column 2
MakeBool(1, -150, "Sound", OptionsKey.UseSound,
OnWidgetClick, g => g.UseSound,
(g, v) => { g.UseSound = v; g.AudioPlayer.SetSound(g.UseSound); }),
MakeVolumeBool(1, -150, "Sound", OptionsKey.SoundsVolume,
g => g.SoundsVolume > 0,
(g, v) => { g.SoundsVolume = v ? 100 : 0; g.AudioPlayer.SetSounds(g.SoundsVolume); }),
MakeBool(1, -100, "Show FPS", OptionsKey.ShowFPS,
OnWidgetClick, g => g.ShowFPS, (g, v) => g.ShowFPS = v),
@ -72,6 +72,23 @@ namespace ClassicalSharp.Gui.Screens {
btn.SetValue = SetFPSLimitMethod;
}
ButtonWidget MakeVolumeBool(int dir, int y, string text, string optKey,
ButtonBoolGetter getter, ButtonBoolSetter setter) {
string optName = text;
text = text + ": " + (getter(game) ? "ON" : "OFF");
ButtonWidget widget = ButtonWidget.Create(game, 300, text, titleFont, OnWidgetClick)
.SetLocation(Anchor.Centre, Anchor.Centre, 160 * dir, y);
widget.Metadata = optName;
widget.GetValue = g => getter(g) ? "yes" : "no";
widget.SetValue = (g, v) => {
setter(g, v == "yes");
Options.Set(optKey, v == "yes" ? 100 : 0);
widget.SetText((string)widget.Metadata + ": " + (v == "yes" ? "ON" : "OFF"));
};
return widget;
}
void MakeValidators() {
IServerConnection network = game.Server;
validators = new MenuInputValidator[] {

View File

@ -26,13 +26,13 @@ namespace ClassicalSharp.Gui.Screens {
g => g.LocalPlayer.ReachDistance.ToString(),
(g, v) => g.LocalPlayer.ReachDistance = Utils.ParseDecimal(v)),
MakeBool(-1, -50, "Music", OptionsKey.UseMusic,
OnWidgetClick, g => g.UseMusic,
(g, v) => { g.UseMusic = v; g.AudioPlayer.SetMusic(g.UseMusic); }),
MakeOpt(-1, -50, "Music volume", OnWidgetClick,
g => g.MusicVolume.ToString(),
(g, v) => { g.MusicVolume = Int32.Parse(v); g.AudioPlayer.SetMusic(g.MusicVolume); }),
MakeBool(-1, 0, "Sound", OptionsKey.UseSound,
OnWidgetClick, g => g.UseSound,
(g, v) => { g.UseSound = v; g.AudioPlayer.SetSound(g.UseSound); }),
MakeOpt(-1, 0, "Sounds volume", OnWidgetClick,
g => g.SoundsVolume.ToString(),
(g, v) => { g.SoundsVolume = Int32.Parse(v); g.AudioPlayer.SetSounds(g.SoundsVolume); }),
MakeBool(-1, 50, "View bobbing", OptionsKey.ViewBobbing,
OnWidgetClick, g => g.ViewBobbing, (g, v) => g.ViewBobbing = v),
@ -65,8 +65,8 @@ namespace ClassicalSharp.Gui.Screens {
IServerConnection network = game.Server;
validators = new MenuInputValidator[] {
network.IsSinglePlayer ? new RealValidator(1, 1024) : null,
new BooleanValidator(),
new BooleanValidator(),
new IntegerValidator(0, 100),
new IntegerValidator(0, 100),
new BooleanValidator(),
network.IsSinglePlayer ? new BooleanValidator() : null,

View File

@ -12,11 +12,9 @@ namespace ClassicalSharp.Audio {
Soundboard digBoard, stepBoard;
const int maxSounds = 6;
public void SetSound(bool enabled) {
if (enabled)
InitSound();
else
DisposeSound();
public void SetSounds(int volume) {
if (volume > 0) InitSound();
else DisposeSound();
}
void InitSound() {
@ -107,6 +105,7 @@ namespace ClassicalSharp.Audio {
void PlaySound(IAudioOutput output) {
try {
output.SetVolume(game.SoundsVolume / 100.0f);
output.PlayRawAsync(chunk);
} catch (InvalidOperationException ex) {
ErrorHandler.LogError("AudioPlayer.PlayCurrentSound()", ex);
@ -115,8 +114,8 @@ namespace ClassicalSharp.Audio {
else
game.Chat.Add("&cAn error occured when trying to play sounds, disabling sounds.");
SetSound(false);
game.UseSound = false;
SetSounds(0);
game.SoundsVolume = 0;
}
}

View File

@ -23,27 +23,33 @@ namespace ClassicalSharp.Audio {
else
files = new string[0];
game.UseMusic = Options.GetBool(OptionsKey.UseMusic, false);
SetMusic(game.UseMusic);
game.UseSound = Options.GetBool(OptionsKey.UseSound, false);
SetSound(game.UseSound);
game.MusicVolume = GetVolume(OptionsKey.MusicVolume, OptionsKey.UseMusic);
SetMusic(game.MusicVolume);
game.SoundsVolume = GetVolume(OptionsKey.SoundsVolume, OptionsKey.UseSound);
SetSounds(game.SoundsVolume);
game.UserEvents.BlockChanged += PlayBlockSound;
}
static int GetVolume(string volKey, string boolKey) {
int volume = Options.GetInt(volKey, 0, 100, 0);
if (volume != 0) return volume;
return Options.GetBool(boolKey, false) ? 100 : 0;
}
public void Ready(Game game) { }
public void Reset(Game game) { }
public void OnNewMap(Game game) { }
public void OnNewMapLoaded(Game game) { }
public void SetMusic(bool enabled) {
if (enabled)
InitMusic();
else
DisposeMusic();
public void SetMusic(int volume) {
if (volume > 0) InitMusic();
else DisposeMusic();
}
const StringComparison comp = StringComparison.OrdinalIgnoreCase;
void InitMusic() {
if (musicThread != null) { musicOut.SetVolume(game.MusicVolume / 100.0f); return; }
int musicCount = 0;
for (int i = 0; i < files.Length; i++) {
if (files[i].EndsWith(".ogg", comp)) musicCount++;
@ -56,8 +62,9 @@ namespace ClassicalSharp.Audio {
}
disposingMusic = false;
musicThread = MakeThread(DoMusicThread, ref musicOut,
"ClassicalSharp.DoMusic");
musicOut = GetPlatformOut();
musicOut.Create(10);
musicThread = MakeThread(DoMusicThread, "ClassicalSharp.DoMusic");
}
EventWaitHandle musicHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
@ -72,6 +79,7 @@ namespace ClassicalSharp.Audio {
using (FileStream fs = File.OpenRead(path)) {
OggContainer container = new OggContainer(fs);
try {
musicOut.SetVolume(game.MusicVolume / 100.0f);
musicOut.PlayStreaming(container);
} catch (InvalidOperationException ex) {
HandleMusicError(ex);
@ -95,8 +103,8 @@ namespace ClassicalSharp.Audio {
else
game.Chat.Add("&cAn error occured when trying to play music, disabling music.");
SetMusic(false);
game.UseMusic = false;
SetMusic(0);
game.MusicVolume = 0;
}
bool disposingMusic;
@ -113,10 +121,7 @@ namespace ClassicalSharp.Audio {
DisposeOf(ref musicOut, ref musicThread);
}
Thread MakeThread(ThreadStart func, ref IAudioOutput output, string name) {
output = GetPlatformOut();
output.Create(10);
Thread MakeThread(ThreadStart func, string name) {
Thread thread = new Thread(func);
thread.Name = name;
thread.IsBackground = true;

View File

@ -190,7 +190,8 @@ namespace ClassicalSharp {
public bool ClickableChat = false, HideGui = false, ShowFPS = true;
internal float HotbarScale = 1, ChatScale = 1, InventoryScale = 1;
public bool ViewBobbing, ShowBlockInHand;
public bool UseSound, UseMusic, ModifiableLiquids;
public bool ModifiableLiquids;
public int SoundsVolume, MusicVolume;
public Vector3 CurrentCameraPos;

View File

@ -8,11 +8,14 @@ namespace ClassicalSharp {
public static class OptionsKey {
#if !LAUNCHER
public const string ViewDist = "viewdist";
public const string SingleplayerPhysics = "singleplayerphysics";
public const string UseMusic = "usemusic";
public const string UseSound = "usesound";
public const string MusicVolume = "musicvolume";
public const string SoundsVolume = "soundsvolume";
public const string ForceOpenAL = "forceopenal";
public const string ViewDist = "viewdist";
public const string SingleplayerPhysics = "singleplayerphysics";
public const string NamesMode = "namesmode";
public const string InvertMouse = "invertmouse";
public const string Sensitivity = "mousesensitivity";

View File

@ -126,10 +126,10 @@ static Real32 Game_RawInventoryScale;
bool Game_ViewBobbing;
/* Whether block in hand is shown in bottom right. */
bool Game_ShowBlockInHand;
/* Whether playing dig and step sounds is enabled. */
bool Game_UseSound;
/* Whether background music playing is enabled. */
bool Game_UseMusic;
/* Volume of dig and step sounds. 0 means disabled. */
Int32 Game_SoundsVolume;
/* Volume of background music played. 0 means disabled */
Int32 Game_MusicVolume;
/* Whether water/lava can be placed/deleted like normal blocks. */
bool Game_ModifiableLiquids;

View File

@ -13,11 +13,14 @@ typedef UInt8 FpsLimitMethod;
#define FpsLimitMethod_120FPS 3
#define FpsLimitMethod_None 4
#define OptionsKey_ViewDist "viewdist"
#define OptionsKey_SingleplayerPhysics "singleplayerphysics"
#define OptionsKey_UseMusic "usemusic"
#define OptionsKey_UseSound "usesound"
#define OptionsKey_MusicVolume "musicvolume"
#define OptionsKey_SoundVolume "soundvolume"
#define OptionsKey_ForceOpenAL "forceopenal"
#define OptionsKey_ViewDist "viewdist"
#define OptionsKey_SingleplayerPhysics "singleplayerphysics"
#define OptionsKey_NamesMode "namesmode"
#define OptionsKey_InvertMouse "invertmouse"
#define OptionsKey_Sensitivity "mousesensitivity"