diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index ded3a09b..2a01900e 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -383,6 +383,7 @@ void Game::init(void) ingame_editormode = false; #endif kludge_ingametemp = Menu::mainmenu; + slidermode = SLIDER_NONE; disablepause = false; inputdelay = false; diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index e91a1a38..21a4ca87 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -84,6 +84,13 @@ namespace Menu }; } +enum SLIDERMODE +{ + SLIDER_NONE, + SLIDER_MUSICVOLUME, + SLIDER_SOUNDVOLUME +}; + struct MenuStackFrame { int option; @@ -259,6 +266,7 @@ public: int currentmenuoption ; enum Menu::MenuName currentmenuname; enum Menu::MenuName kludge_ingametemp; + enum SLIDERMODE slidermode; int current_credits_list_index; int menuxoff, menuyoff; int menuspacing; diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 33c1221c..fe4fdfbb 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -1475,7 +1475,7 @@ void Graphics::drawmenu( int cr, int cg, int cb, bool levelmenu /*= false*/ ) SDL_strlcpy(tempstring, opt.text, sizeof(tempstring)); char buffer[MENU_TEXT_BYTES]; - if ((int) i == game.currentmenuoption) + if ((int) i == game.currentmenuoption && game.slidermode == SLIDER_NONE) { if (opt.active) { diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index 5313f9bb..01ddc152 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -200,6 +200,56 @@ static void startmode(const int mode) fadetomodedelay = 16; } +static int* user_changing_volume = NULL; +static int previous_volume = 0; + +static void initvolumeslider(const int menuoption) +{ + switch (menuoption) + { + case 0: + game.slidermode = SLIDER_MUSICVOLUME; + user_changing_volume = &music.user_music_volume; + break; + case 1: + game.slidermode = SLIDER_SOUNDVOLUME; + user_changing_volume = &music.user_sound_volume; + break; + default: + SDL_assert(0 && "Unhandled volume slider option!"); + game.slidermode = SLIDER_NONE; + user_changing_volume = NULL; + return; + } + previous_volume = *user_changing_volume; +} + +static void deinitvolumeslider(void) +{ + user_changing_volume = NULL; + game.savestatsandsettings_menu(); + game.slidermode = SLIDER_NONE; +} + +static void slidermodeinput(void) +{ + if (user_changing_volume == NULL) + { + SDL_assert(0 && "user_changing_volume is NULL!"); + return; + } + + if (game.press_left) + { + *user_changing_volume -= USER_VOLUME_STEP; + } + else if (game.press_right) + { + *user_changing_volume += USER_VOLUME_STEP; + } + *user_changing_volume = clamp(*user_changing_volume, 0, USER_VOLUME_MAX); +} + static void menuactionpress(void) { switch (game.currentmenuname) @@ -786,10 +836,16 @@ static void menuactionpress(void) switch (game.currentmenuoption) { case 0: - /* Not implemented */ - break; case 1: - /* Not implemented */ + music.playef(11); + if (game.slidermode == SLIDER_NONE) + { + initvolumeslider(game.currentmenuoption); + } + else + { + deinitvolumeslider(); + } break; case 2: if (!music.mmmmmm) @@ -1641,7 +1697,27 @@ void titleinput(void) } else { - if (game.ingame_titlemode + if (game.slidermode != SLIDER_NONE) + { + switch (game.slidermode) + { + /* Cancel volume change. */ + case SLIDER_MUSICVOLUME: + case SLIDER_SOUNDVOLUME: + if (user_changing_volume == NULL) + { + SDL_assert(0 && "user_changing_volume is NULL!"); + break; + } + *user_changing_volume = previous_volume; + deinitvolumeslider(); + break; + default: + SDL_assert(0 && "Unhandled slider mode!"); + break; + } + } + else if (game.ingame_titlemode && game.currentmenuname == Menu::options) { game.returntoingame(); @@ -1656,13 +1732,20 @@ void titleinput(void) if(game.menustart) { - if (game.press_left) + if (game.slidermode == SLIDER_NONE) { - game.currentmenuoption--; + if (game.press_left) + { + game.currentmenuoption--; + } + else if (game.press_right) + { + game.currentmenuoption++; + } } - else if (game.press_right) + else { - game.currentmenuoption++; + slidermodeinput(); } } diff --git a/desktop_version/src/Music.h b/desktop_version/src/Music.h index 7ba45ff2..593b339e 100644 --- a/desktop_version/src/Music.h +++ b/desktop_version/src/Music.h @@ -11,6 +11,9 @@ /* The amount of "space" for the scale of the user-set volume. */ #define USER_VOLUME_MAX 256 +/* It is advised that USER_VOLUME_MAX be divisible by this. */ +#define USER_VOLUME_STEP 32 + class musicclass { public: diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 25970783..e1913901 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -46,6 +46,62 @@ static inline void drawslowdowntext(void) } } +static void volumesliderrender(void) +{ + char buffer[40 + 1]; + + char slider[20 + 1]; + int slider_length; + + const char symbol[] = "[]"; + int symbol_length; + + int offset; + int num_positions; + + const int* volume_ptr; + + switch (game.currentmenuoption) + { + case 0: + volume_ptr = &music.user_music_volume; + break; + case 1: + volume_ptr = &music.user_sound_volume; + break; + default: + SDL_assert(0 && "Unhandled volume slider menu option!"); + return; + } + + VVV_fillstring(slider, sizeof(slider), '.'); + slider_length = sizeof(slider) - 1; + + symbol_length = sizeof(symbol) - 1; + + num_positions = slider_length - symbol_length + 1; + + offset = num_positions * (*volume_ptr) / USER_VOLUME_MAX; + offset = clamp(offset, 0, slider_length - symbol_length); + + /* SDL_strlcpy null-terminates, which would end the string in the middle of + * it, which we don't want! + */ + SDL_memcpy(&slider[offset], symbol, symbol_length); + + if (game.slidermode == SLIDER_NONE) + { + SDL_strlcpy(buffer, slider, sizeof(buffer)); + } + else + { + /* Draw selection brackets. */ + SDL_snprintf(buffer, sizeof(buffer), "[ %s ]", slider); + } + + graphics.Print(-1, 85, buffer, tr, tg, tb, true); +} + static void menurender(void) { int temp = 50; @@ -281,10 +337,14 @@ static void menurender(void) switch (game.currentmenuoption) { case 0: - /* Not implemented */ + graphics.bigprint(-1, 30, "Music Volume", tr, tg, tb, true); + graphics.Print(-1, 65, "Change the volume of the music.", tr, tg, tb, true); + volumesliderrender(); break; case 1: - /* Not implemented */ + graphics.bigprint(-1, 30, "Sound Volume", tr, tg, tb, true); + graphics.Print(-1, 65, "Change the volume of sound effects.", tr, tg, tb, true); + volumesliderrender(); break; case 2: if (!music.mmmmmm)