Skip to content

Commit d182d43

Browse files
Control sliders via mouse cursor
Control via arrows and mouse wheel is still possible as well. Co-Authored-By: Polina "Aura" N. <185700473+pvictress@users.noreply.github.com>
1 parent 696c524 commit d182d43

File tree

5 files changed

+296
-152
lines changed

5 files changed

+296
-152
lines changed

src/doom/m_menu.c

Lines changed: 94 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,7 @@ typedef struct menu_s
186186
#define M_SKIP -1,0 // Skippable, cursor can't get here.
187187
#define M_SWTC 1,0 // On/off type or entering function.
188188
#define M_LFRT 2,0 // Multichoice function.
189-
#define M_SLD1 3,0 // Slider 1st line.
190-
#define M_SLD2 4,0 // Slider 2st line.
189+
#define M_SLDR 3,0 // Slider line.
191190

192191
// [JN] Small cursor timer for glowing effect.
193192
static short cursor_tics = 0;
@@ -250,6 +249,7 @@ static int M_StringHeight(const char *string);
250249
static void M_StartMessage(const char *string, void (*routine)(int), boolean input);
251250
static void M_ClearMenus (void);
252251

252+
static void M_ID_HandleSliderMouseControl (int x, int y, int width, void *value, boolean is_float, float min, float max);
253253

254254
// =============================================================================
255255
// DOOM MENU
@@ -431,10 +431,10 @@ enum
431431

432432
static menuitem_t SoundMenu[]=
433433
{
434-
{ M_LFRT, "M_SFXVOL", M_SfxVol, 's' },
435-
{ M_SLD1, "", 0, '\0' },
436-
{ M_LFRT, "M_MUSVOL", M_MusicVol, 'm' },
437-
{ M_SLD1, "", 0, '\0' }
434+
{ M_SLDR, "M_SFXVOL", M_SfxVol, 's' },
435+
{ M_SKIP, "", 0, '\0' },
436+
{ M_SLDR, "M_MUSVOL", M_MusicVol, 'm' },
437+
{ M_SKIP, "", 0, '\0' }
438438
};
439439

440440
static menu_t SoundDef =
@@ -1188,7 +1188,8 @@ static byte *M_SaveLoad_Glow (int itemSetOn, int tics, int type)
11881188
static const int M_INT_Slider (int val, int min, int max, int direction, boolean capped)
11891189
{
11901190
// [PN] Adjust the slider value based on direction and handle min/max limits
1191-
val += (direction == 0) ? -1 : 1;
1191+
val += (direction == -1) ? 0 : // [JN] Routine "-1" just reintializes value.
1192+
(direction == 0) ? -1 : 1; // Otherwise, move either left "0" or right "1".
11921193

11931194
if (val < min)
11941195
val = capped ? min : max;
@@ -1875,12 +1876,12 @@ static void M_ID_LocalTime (int choice)
18751876

18761877
static menuitem_t ID_Menu_Sound[]=
18771878
{
1878-
{ M_LFRT, "SFX VOLUME", M_SfxVol, 's' },
1879-
{ M_SLD1, "", 0, '\0' },
1880-
{ M_SLD2, "", 0, '\0' },
1881-
{ M_LFRT, "MUSIC VOLUME", M_MusicVol, 'm' },
1882-
{ M_SLD1, "", 0, '\0' },
1883-
{ M_SLD2, "", 0, '\0' },
1879+
{ M_SLDR, "SFX VOLUME", M_SfxVol, 's' },
1880+
{ M_SKIP, "", 0, '\0' },
1881+
{ M_SKIP, "", 0, '\0' },
1882+
{ M_SLDR, "MUSIC VOLUME", M_MusicVol, 'm' },
1883+
{ M_SKIP, "", 0, '\0' },
1884+
{ M_SKIP, "", 0, '\0' },
18841885
{ M_SKIP, "", 0, '\0' },
18851886
{ M_LFRT, "SFX PLAYBACK", M_ID_SFXSystem, 's' },
18861887
{ M_LFRT, "MUSIC PLAYBACK", M_ID_MusicSystem, 'm' },
@@ -1915,10 +1916,12 @@ static void M_Draw_ID_Sound (void)
19151916
M_WriteTextCentered(9, "VOLUME", cr[CR_YELLOW]);
19161917

19171918
M_DrawThermo(46, 27, 16, sfxVolume, 0);
1919+
M_ID_HandleSliderMouseControl(52, 27, 132, &sfxVolume, false, 0, 15);
19181920
sprintf(str,"%d", sfxVolume);
19191921
M_WriteText (192, 30, str, M_Item_Glow(0, GLOW_UNCOLORED));
19201922

19211923
M_DrawThermo(46, 54, 16, musicVolume, 3);
1924+
M_ID_HandleSliderMouseControl(52, 54, 132, &musicVolume, false, 0, 15);
19221925
sprintf(str,"%d", musicVolume);
19231926
M_WriteText (192, 57, str, M_Item_Glow(3, GLOW_UNCOLORED));
19241927

@@ -2168,15 +2171,15 @@ static menuitem_t ID_Menu_Controls[]=
21682171
{ M_SWTC, "KEYBOARD BINDINGS", M_Choose_ID_Keybinds, 'k' },
21692172
{ M_SWTC, "MOUSE BINDINGS", M_Choose_ID_MouseBinds, 'm' },
21702173
{ M_SKIP, "", 0, '\0' },
2171-
{ M_LFRT, "SENSIVITY", M_ID_Controls_Sensivity, 's' },
2172-
{ M_SLD1, "", 0, '\0' },
2173-
{ M_SLD2, "", 0, '\0' },
2174-
{ M_LFRT, "ACCELERATION", M_ID_Controls_Acceleration, 'a' },
2175-
{ M_SLD1, "", 0, '\0' },
2176-
{ M_SLD2, "", 0, '\0' },
2177-
{ M_LFRT, "ACCELERATION THRESHOLD", M_ID_Controls_Threshold, 'a' },
2178-
{ M_SLD1, "", 0, '\0' },
2179-
{ M_SLD2, "", 0, '\0' },
2174+
{ M_SLDR, "SENSIVITY", M_ID_Controls_Sensivity, 's' },
2175+
{ M_SKIP, "", 0, '\0' },
2176+
{ M_SKIP, "", 0, '\0' },
2177+
{ M_SLDR, "ACCELERATION", M_ID_Controls_Acceleration, 'a' },
2178+
{ M_SKIP, "", 0, '\0' },
2179+
{ M_SKIP, "", 0, '\0' },
2180+
{ M_SLDR, "ACCELERATION THRESHOLD", M_ID_Controls_Threshold, 'a' },
2181+
{ M_SKIP, "", 0, '\0' },
2182+
{ M_SKIP, "", 0, '\0' },
21802183
{ M_LFRT, "MOUSE LOOK", M_ID_Controls_MLook, 'm' },
21812184
{ M_LFRT, "VERTICAL MOUSE MOVEMENT", M_ID_Controls_NoVert, 'v' },
21822185
{ M_LFRT, "INVERT VERTICAL AXIS", M_ID_Controls_InvertY, 'v' },
@@ -2207,16 +2210,19 @@ static void M_Draw_ID_Controls (void)
22072210

22082211
M_WriteTextCentered(36, "MOUSE CONFIGURATION", cr[CR_YELLOW]);
22092212

2210-
M_DrawThermo(46, 54, 10, mouseSensitivity, 3);
2213+
M_DrawThermo(46, 54, 15, mouseSensitivity, 3);
2214+
M_ID_HandleSliderMouseControl(52, 54, 124, &mouseSensitivity, false, 0, 14);
22112215
sprintf(str,"%d", mouseSensitivity);
2212-
M_WriteText (144, 57, str, M_Item_Glow(3, mouseSensitivity == 255 ? GLOW_YELLOW :
2213-
mouseSensitivity > 9 ? GLOW_GREEN : GLOW_UNCOLORED));
2216+
M_WriteText (184, 57, str, M_Item_Glow(3, mouseSensitivity == 255 ? GLOW_YELLOW :
2217+
mouseSensitivity > 14 ? GLOW_GREEN : GLOW_UNCOLORED));
22142218

2215-
M_DrawThermo(46, 81, 12, (mouse_acceleration * 3) - 3, 6);
2219+
M_DrawThermo(46, 81, 8, (mouse_acceleration * 1.8f) - 2, 6);
2220+
M_ID_HandleSliderMouseControl(52, 81, 100, &mouse_acceleration, true, 0, 9);
22162221
sprintf(str,"%.1f", mouse_acceleration);
2217-
M_WriteText (160, 84, str, M_Item_Glow(6, GLOW_UNCOLORED));
2222+
M_WriteText (128, 84, str, M_Item_Glow(6, GLOW_UNCOLORED));
22182223

2219-
M_DrawThermo(46, 108, 15, mouse_threshold / 2, 9);
2224+
M_DrawThermo(46, 108, 15, mouse_threshold / 2.2f, 9);
2225+
M_ID_HandleSliderMouseControl(52, 108, 124, &mouse_threshold, false, 0, 32);
22202226
sprintf(str,"%d", mouse_threshold);
22212227
M_WriteText (184, 111, str, M_Item_Glow(9, GLOW_UNCOLORED));
22222228

@@ -5222,10 +5228,12 @@ static void M_DrawSound(void)
52225228
V_DrawShadowedPatchOptional(60, 38, 0, W_CacheLumpName(DEH_String("M_SVOL"), PU_CACHE));
52235229

52245230
M_DrawThermo(SoundDef.x, SoundDef.y + LINEHEIGHT * (sfx_vol + 1), 16, sfxVolume, 0);
5231+
M_ID_HandleSliderMouseControl(86, 80, 132, &sfxVolume, false, 0, 15);
52255232
sprintf(str,"%d", sfxVolume);
52265233
M_WriteText (226, 83, str, M_Item_Glow(0, sfxVolume ? GLOW_UNCOLORED : GLOW_DARKRED));
52275234

52285235
M_DrawThermo(SoundDef.x, SoundDef.y + LINEHEIGHT * (music_vol + 1), 16, musicVolume, 2);
5236+
M_ID_HandleSliderMouseControl(86, 112, 132, &musicVolume, false, 0, 15);
52295237
sprintf(str,"%d", musicVolume);
52305238
M_WriteText (226, 115, str, M_Item_Glow(2, musicVolume ? GLOW_UNCOLORED : GLOW_DARKRED));
52315239
}
@@ -5996,10 +6004,12 @@ boolean M_Responder (event_t* ev)
59966004
{
59976005
// [JN] Shows the mouse cursor when moved.
59986006
if (ev->data2 || ev->data3)
6007+
{
59996008
menu_mouse_allow = true;
6009+
menu_mouse_allow_click = false;
6010+
}
60006011

6001-
if (ev->type == ev_mouse && mousewait < I_GetTime()
6002-
&& !ev->data2 && !ev->data3) // [JN] Do not consider movement as pressing.
6012+
if (ev->type == ev_mouse && mousewait < I_GetTime())
60036013
{
60046014
// [crispy] mouse_novert disables controlling the menus with the mouse
60056015
// [JN] Not needed, as menu is fully controllable by mouse wheel and buttons.
@@ -6053,6 +6063,14 @@ boolean M_Responder (event_t* ev)
60536063

60546064
if (ev->data1&1)
60556065
{
6066+
if (menuactive && currentMenu->menuitems[itemOn].status == 3)
6067+
{
6068+
// [JN] Allow repetitive on sliders to move it while mouse movement.
6069+
menu_mouse_allow_click = true;
6070+
}
6071+
else
6072+
if (!ev->data2 && !ev->data3) // [JN] Do not consider movement as pressing.
6073+
{
60566074
if (!menuactive && !usergame)
60576075
{
60586076
M_StartControlPanel(); // [JN] Open the main menu if the game is not active.
@@ -6068,8 +6086,10 @@ boolean M_Responder (event_t* ev)
60686086
}
60696087
mousewait = I_GetTime() + 1;
60706088
}
6089+
}
60716090

6072-
if (ev->data1&2)
6091+
if (ev->data1&2
6092+
&& !ev->data2 && !ev->data3) // [JN] Do not consider movement as pressing.
60736093
{
60746094
if (!menuactive && !usergame)
60756095
{
@@ -6097,7 +6117,7 @@ boolean M_Responder (event_t* ev)
60976117
// [JN] Scrolls through menu item values or navigates between pages.
60986118
if (ev->data1 & (1 << 4) && menuactive)
60996119
{
6100-
if (currentMenu->menuitems[itemOn].status == 2)
6120+
if (currentMenu->menuitems[itemOn].status > 1)
61016121
{
61026122
// Scroll menu item backward
61036123
currentMenu->menuitems[itemOn].routine(0);
@@ -6113,7 +6133,7 @@ boolean M_Responder (event_t* ev)
61136133
else
61146134
if (ev->data1 & (1 << 3) && menuactive)
61156135
{
6116-
if (currentMenu->menuitems[itemOn].status == 2)
6136+
if (currentMenu->menuitems[itemOn].status > 1)
61176137
{
61186138
// Scroll menu item forward
61196139
currentMenu->menuitems[itemOn].routine(1);
@@ -6463,9 +6483,7 @@ boolean M_Responder (event_t* ev)
64636483
do
64646484
{
64656485
itemOn = (itemOn + 1) % currentMenu->numitems;
6466-
} while (currentMenu->menuitems[itemOn].status == -1 ||
6467-
currentMenu->menuitems[itemOn].status == 3 || // [JN] Skip sliders
6468-
currentMenu->menuitems[itemOn].status == 4);
6486+
} while (currentMenu->menuitems[itemOn].status == -1);
64696487

64706488
S_StartSound(NULL, sfx_pstop);
64716489
return true;
@@ -6476,9 +6494,7 @@ boolean M_Responder (event_t* ev)
64766494
do
64776495
{
64786496
itemOn = (itemOn == 0) ? currentMenu->numitems - 1 : itemOn - 1;
6479-
} while (currentMenu->menuitems[itemOn].status == -1 ||
6480-
currentMenu->menuitems[itemOn].status == 3 || // [JN] Skip sliders
6481-
currentMenu->menuitems[itemOn].status == 4);
6497+
} while (currentMenu->menuitems[itemOn].status == -1);
64826498

64836499
S_StartSound(NULL, sfx_pstop);
64846500
return true;
@@ -6493,7 +6509,7 @@ boolean M_Responder (event_t* ev)
64936509

64946510
// Slide slider left
64956511
if (currentMenu->menuitems[itemOn].routine
6496-
&& currentMenu->menuitems[itemOn].status == 2)
6512+
&& currentMenu->menuitems[itemOn].status > 1)
64976513
{
64986514
S_StartSound(NULL,sfx_stnmov);
64996515
currentMenu->menuitems[itemOn].routine(0);
@@ -6510,7 +6526,7 @@ boolean M_Responder (event_t* ev)
65106526

65116527
// Slide slider right
65126528
if (currentMenu->menuitems[itemOn].routine
6513-
&& currentMenu->menuitems[itemOn].status == 2)
6529+
&& currentMenu->menuitems[itemOn].status > 1)
65146530
{
65156531
S_StartSound(NULL,sfx_stnmov);
65166532
currentMenu->menuitems[itemOn].routine(1);
@@ -6689,25 +6705,55 @@ static void M_ID_MenuMouseControl (void)
66896705
// [PN] Check if the cursor is hovering over a menu item
66906706
for (int i = 0; i < currentMenu->numitems; i++)
66916707
{
6708+
// [JN] Slider takes three lines.
6709+
const int line_item = currentMenu->menuitems[i].status == 3 ? 3 : 1;
6710+
66926711
if (menu_mouse_x >= (currentMenu->x + WIDESCREENDELTA) * vid_resolution
66936712
&& menu_mouse_x <= (ORIGWIDTH + WIDESCREENDELTA - currentMenu->x) * vid_resolution
66946713
&& menu_mouse_y >= (currentMenu->y + i * line_height) * vid_resolution
6695-
&& menu_mouse_y <= (currentMenu->y + (i + 1) * line_height) * vid_resolution
6714+
&& menu_mouse_y <= (currentMenu->y + (i + line_item) * line_height) * vid_resolution
66966715
&& currentMenu->menuitems[i].status != -1)
66976716
{
66986717
// [PN] Highlight the current menu item
66996718
itemOn = i;
6700-
6701-
// [JN] Move menu cursor higher when hovering slider lines.
6702-
if (currentMenu->menuitems[itemOn].status == 3)
6703-
itemOn -= 1;
6704-
if (currentMenu->menuitems[itemOn].status == 4)
6705-
itemOn -= 2;
67066719
}
67076720
}
67086721
}
67096722
}
67106723

6724+
static void M_ID_HandleSliderMouseControl (int x, int y, int width, void *value, boolean is_float, float min, float max)
6725+
{
6726+
if (!menu_mouse_allow_click)
6727+
return;
6728+
6729+
// [JN/PN] Adjust slider boundaries
6730+
const int adj_x = (x + WIDESCREENDELTA) * vid_resolution;
6731+
const int adj_y = y * vid_resolution;
6732+
const int adj_width = width * vid_resolution;
6733+
const int adj_height = LINEHEIGHT * vid_resolution;
6734+
6735+
// [PN] Check cursor position and item status
6736+
if (menu_mouse_x < adj_x || menu_mouse_x > adj_x + adj_width
6737+
|| menu_mouse_y < adj_y || menu_mouse_y > adj_y + adj_height
6738+
|| currentMenu->menuitems[itemOn].status != 3)
6739+
return;
6740+
6741+
// [PN] Calculate and update slider value
6742+
const float normalized = (float)(menu_mouse_x - adj_x + 5) / adj_width;
6743+
const float newValue = min + normalized * (max - min);
6744+
if (is_float)
6745+
*((float *)value) = newValue;
6746+
else
6747+
*((int *)value) = (int)newValue;
6748+
6749+
// [JN/PN] Call related routine and reset mouse click allowance
6750+
currentMenu->menuitems[itemOn].routine(-1);
6751+
menu_mouse_allow_click = false;
6752+
6753+
// Play sound
6754+
S_StartSound(NULL, sfx_stnmov);
6755+
}
6756+
67116757
//
67126758
// M_Drawer
67136759
// Called after the view has been rendered,

0 commit comments

Comments
 (0)