options menu + video options (res & ogl)

This commit is contained in:
SinnamonLat 2021-11-25 23:36:42 +01:00
parent 5adddd13e9
commit 3449064b8b
5 changed files with 846 additions and 4 deletions

View file

@ -6479,6 +6479,7 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glshearing);
CV_RegisterVar(&cv_glshaders);
CV_RegisterVar(&cv_glallowshaders);
CV_RegisterVar(&cv_glanisotropicmode);
CV_RegisterVar(&cv_glfiltermode);
CV_RegisterVar(&cv_glsolvetjoin);
@ -6494,7 +6495,7 @@ void HWR_AddSessionCommands(void)
{
if (gl_sessioncommandsadded)
return;
CV_RegisterVar(&cv_glanisotropicmode);
// Kept in case we ever need this again.
gl_sessioncommandsadded = true;
}

View file

@ -196,6 +196,22 @@ extern menu_t PLAY_MP_RoomSelectDef;
extern menuitem_t PLAY_BattleGamemodesMenu[];
extern menu_t PLAY_BattleGamemodesDef;
// OPTIONS
extern menuitem_t OPTIONS_Main[];
extern menu_t OPTIONS_MainDef;
extern menuitem_t OPTIONS_Video[];
extern menu_t OPTIONS_VideoDef;
extern menuitem_t OPTIONS_VideoModes[];
extern menu_t OPTIONS_VideoModesDef;
#ifdef HWRENDER
extern menuitem_t OPTIONS_VideoOGL[];
extern menu_t OPTIONS_VideoOGLDef;
#endif
// PAUSE
extern menuitem_t PAUSE_Main[];
extern menu_t PAUSE_MainDef;
@ -431,6 +447,55 @@ void M_MPRoomSelect(INT32 choice);
void M_MPRoomSelectTick(void);
void M_MPRoomSelectInit(INT32 choice);
// Options menu:
// mode descriptions for video mode menu
typedef struct
{
INT32 modenum; // video mode number in the vidmodes list
const char *desc; // XXXxYYY
UINT8 goodratio; // aspect correct if 1
} modedesc_t;
#define MAXCOLUMNMODES 12 //max modes displayed in one column
#define MAXMODEDESCS (MAXCOLUMNMODES*3)
// Keep track of some options properties
extern struct optionsmenu_s {
tic_t ticker; // How long the menu's been open for
INT16 offset; // To make the icons move smoothly when we transition!
tic_t buttflash; // Button flashing before transitionning to the new submenu.
// For moving the button when we get into a submenu. it's smooth and cool! (normal x/y and target x/y.)
// this is only used during menu transitions.
INT16 optx;
INT16 opty;
INT16 toptx;
INT16 topty;
// for video mode testing:
INT32 vidm_testingmode;
INT32 vidm_previousmode;
INT32 vidm_selected;
INT32 vidm_nummodes;
INT32 vidm_column_size;
modedesc_t modedescs[MAXMODEDESCS];
} optionsmenu;
void M_InitOptions(INT32 choice); // necessary for multiplayer since there's some options we won't want to access
void M_OptionsTick(void);
boolean M_OptionsInputs(INT32 ch);
boolean M_OptionsQuit(void); // resets buttons when you quit the options.
// video modes menu (resolution)
void M_VideoModeMenu(INT32 choice);
void M_HandleVideoModes(INT32 ch);
// Pause menu:
// Keep track of some pause menu data for visual goodness.
@ -516,6 +581,12 @@ void M_DrawPause(void);
// Replay Playback
void M_DrawPlaybackMenu(void);
// Options menus:
void M_DrawOptionsMovingButton(void); // for sick transitions...
void M_DrawOptions(void);
void M_DrawGenericOptions(void);
void M_DrawVideoModes(void);
// Misc menus:
#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!"
#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make addons!"

View file

@ -3,6 +3,9 @@
#include "k_menu.h"
#include "screen.h" // BASEVIDWIDTH
#include "r_main.h" // cv_skybox
#include "v_video.h" // cv_globalgamma
#include "hardware/hw_main.h" // gl consvars
// ==========================================================================
// ORGANIZATION START.
@ -26,9 +29,9 @@ menuitem_t MainMenu[] =
"Check out some bonus features.", "MENUI001",
NULL, 0, 0},
{IT_STRING, "Option",
{IT_STRING, "Options",
"Configure your controls, settings, and preferences.", NULL,
NULL, 0, 0},
M_InitOptions, 0, 0},
{IT_STRING | IT_CALL, "Quit",
"Exit \"Dr. Robotnik's Ring Racers\".", NULL,
@ -291,6 +294,185 @@ menu_t PLAY_MP_RoomSelectDef = {
NULL
};
// options menu
menuitem_t OPTIONS_Main[] =
{
{IT_STRING | IT_SUBMENU, "Control Setup", "Remap keys & buttons to your likings.",
NULL, NULL, 0, 0},
{IT_STRING | IT_SUBMENU, "Video Options", "Change video settings such as the resolution.",
NULL, &OPTIONS_VideoDef, 0, 0},
{IT_STRING | IT_SUBMENU, "Sound Options", "Adjust various sound settings such as the volume.",
NULL, NULL, 0, 0},
{IT_STRING | IT_SUBMENU, "HUD Options", "Options related to the Heads-Up Display.",
NULL, NULL, 0, 0},
{IT_STRING | IT_SUBMENU, "Gameplay Options", "Change various game related options",
NULL, NULL, 0, 0},
{IT_STRING | IT_SUBMENU, "Server Options", "Change various specific options for your game server.",
NULL, NULL, 0, 0},
{IT_STRING | IT_SUBMENU, "Data Options", "Miscellaneous data options such as the screenshot format.",
NULL, NULL, 0, 0},
{IT_STRING | IT_SUBMENU, "Tricks & Secrets", "Those who bother reading a game manual always get the edge over those who don't!",
NULL, NULL, 0, 0},
};
menu_t OPTIONS_MainDef = {
sizeof (OPTIONS_Main) / sizeof (menuitem_t),
&MainDef,
0,
OPTIONS_Main,
0, 0,
2, 10,
M_DrawOptions,
M_OptionsTick,
NULL,
M_OptionsInputs
};
// video options menu...
// options menu
menuitem_t OPTIONS_Video[] =
{
{IT_STRING | IT_CALL, "Set Resolution...", "Change the screen resolution for the game.",
NULL, M_VideoModeMenu, 0, 0},
// A check to see if you're not running on a fucking antique potato powered stone i guess???????
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
{IT_STRING | IT_CVAR, "Fullscreen", "Set whether you want to use fullscreen or windowed mode.",
NULL, &cv_fullscreen, 0, 0},
#endif
{IT_NOTHING|IT_SPACE, NULL, "Kanade best waifu! I promise!",
NULL, NULL, 0, 0},
// Everytime I see a screenshot at max gamma I die inside
{IT_STRING | IT_CVAR | IT_CV_SLIDER, "Gamma", "Adjusts the overall brightness of the game.",
NULL, &cv_globalgamma, 0, 0},
{IT_STRING | IT_CVAR, "Vertical Sync", "Locks the framerate to your monitor's refresh rate.",
NULL, &cv_vidwait, 0, 0},
{IT_STRING | IT_CVAR, "Enable Skyboxes", "Turning this off will improve performance at the detriment of visuals for many maps.",
NULL, &cv_skybox, 0, 0},
{IT_STRING | IT_CVAR, "Draw Distance", "How far objects can be drawn. Lower values may improve performance at the cost of visibility.",
NULL, &cv_drawdist, 0, 0},
{IT_STRING | IT_CVAR, "Weather Draw Distance", "Affects how far weather visuals can be drawn. Lower values improve performance.",
NULL, &cv_drawdist_precip, 0, 0},
{IT_STRING | IT_CVAR, "Show FPS", "Displays the game framerate at the lower right corner of the screen.",
NULL, &cv_ticrate, 0, 0},
{IT_NOTHING|IT_SPACE, NULL, "Kanade best waifu! I promise!",
NULL, NULL, 0, 0},
#ifdef HWRENDER
{IT_STRING | IT_SUBMENU, "Hardware Options...", "For usage and configuration of the OpenGL renderer.",
NULL, &OPTIONS_VideoOGLDef, 0, 0},
#endif
};
menu_t OPTIONS_VideoDef = {
sizeof (OPTIONS_Video) / sizeof (menuitem_t),
&OPTIONS_MainDef,
0,
OPTIONS_Video,
32, 80,
2, 10,
M_DrawGenericOptions,
M_OptionsTick,
NULL,
NULL,
};
menuitem_t OPTIONS_VideoModes[] = {
{IT_KEYHANDLER | IT_NOTHING, NULL, "Select a resolution.",
NULL, M_HandleVideoModes, 0, 0}, // dummy menuitem for the control func
};
menu_t OPTIONS_VideoModesDef = {
sizeof (OPTIONS_VideoModes) / sizeof (menuitem_t),
&OPTIONS_VideoDef,
0,
OPTIONS_VideoModes,
48, 80,
2, 10,
M_DrawVideoModes,
M_OptionsTick,
NULL,
NULL,
};
#ifdef HWRENDER
menuitem_t OPTIONS_VideoOGL[] =
{
{IT_STRING | IT_CVAR, "Renderer", "Change renderers between Software and OpenGL",
NULL, &cv_renderer, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, NULL, 0, 0},
{IT_SPACE | IT_NOTHING | IT_STRING, "OPTIONS BELOW ARE OPENGL ONLY!", "Watch people get confused anyway!!",
NULL, NULL, 0, 0},
{IT_STRING | IT_CVAR, "3D Models", "Use 3D models instead of sprites when applicable.",
NULL, &cv_glmodels, 0, 0},
{IT_STRING | IT_CVAR, "Shaders", "Use GLSL Shaders. Turning them off increases performance at the expanse of visual quality.",
NULL, &cv_glshaders, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, NULL, 0, 0},
{IT_STRING | IT_CVAR, "Texture Quality", "Texture depth. Higher values are recommended.",
NULL, &cv_scr_depth, 0, 0},
{IT_STRING | IT_CVAR, "Texture Filter", "Texture Filter. Nearest is recommended.",
NULL, &cv_glfiltermode, 0, 0},
{IT_STRING | IT_CVAR, "Anisotropic", "Lower values will improve performance at a minor quality loss.",
NULL, &cv_glanisotropicmode, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, NULL, 0, 0},
{IT_STRING | IT_CVAR, "Wall Contrast Style", "Allows faking or not Software wall colour contrast.",
NULL, &cv_glfakecontrast, 0, 0},
{IT_STRING | IT_CVAR, "Sprite Billboarding", "Adjusts sprites when viewed from above or below to not make them appear flat.",
NULL, &cv_glspritebillboarding, 0, 0},
{IT_STRING | IT_CVAR, "Software Perspective", "Emulates Software shearing when looking up or down. Not recommended.",
NULL, &cv_glshearing, 0, 0},
};
menu_t OPTIONS_VideoOGLDef = {
sizeof (OPTIONS_VideoOGL) / sizeof (menuitem_t),
&OPTIONS_VideoDef,
0,
OPTIONS_VideoOGL,
32, 80,
2, 10,
M_DrawGenericOptions,
M_OptionsTick,
NULL,
NULL,
};
#endif
// -------------------
// In-game/pause menus
@ -332,7 +514,7 @@ menuitem_t PAUSE_Main[] =
NULL, M_CharacterSelectInit, 0, 0},
{IT_STRING | IT_CALL, "OPTIONS", "M_ICOOPT",
NULL, NULL, 0, 0},
NULL, M_InitOptions, 0, 0},
{IT_STRING | IT_CALL, "EXIT GAME", "M_ICOEXT",
NULL, M_EndGame, 0, 0},

View file

@ -80,6 +80,74 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#define SLIDER_WIDTH (8*SLIDER_RANGE+6)
#define SERVERS_PER_PAGE 11
// horizontally centered text
static void M_CentreText(INT32 xoffs, INT32 y, const char *string)
{
INT32 x;
//added : 02-02-98 : centre on 320, because V_DrawString centers on vid.width...
x = ((BASEVIDWIDTH - V_StringWidth(string, V_OLDSPACING))>>1) + xoffs;
V_DrawString(x,y,V_OLDSPACING,string);
}
// A smaller 'Thermo', with range given as percents (0-100)
static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop)
{
INT32 i;
INT32 range;
patch_t *p;
for (i = 0; cv->PossibleValue[i+1].strvalue; i++);
x = BASEVIDWIDTH - x - SLIDER_WIDTH;
if (ontop)
{
V_DrawCharacter(x - 16 - (skullAnimCounter/5), y,
'\x1C' | highlightflags, false); // left arrow
V_DrawCharacter(x+(SLIDER_RANGE*8) + 8 + (skullAnimCounter/5), y,
'\x1D' | highlightflags, false); // right arrow
}
if ((range = atoi(cv->defaultvalue)) != cv->value)
{
range = ((range - cv->PossibleValue[0].value) * 100 /
(cv->PossibleValue[1].value - cv->PossibleValue[0].value));
if (range < 0)
range = 0;
if (range > 100)
range = 100;
// draw the default
p = W_CachePatchName("M_SLIDEC", PU_CACHE);
V_DrawScaledPatch(x - 4 + (((SLIDER_RANGE)*8 + 4)*range)/100, y, 0, p);
}
V_DrawScaledPatch(x - 8, y, 0, W_CachePatchName("M_SLIDEL", PU_CACHE));
p = W_CachePatchName("M_SLIDEM", PU_CACHE);
for (i = 0; i < SLIDER_RANGE; i++)
V_DrawScaledPatch (x+i*8, y, 0,p);
p = W_CachePatchName("M_SLIDER", PU_CACHE);
V_DrawScaledPatch(x+SLIDER_RANGE*8, y, 0, p);
range = ((cv->value - cv->PossibleValue[0].value) * 100 /
(cv->PossibleValue[1].value - cv->PossibleValue[0].value));
if (range < 0)
range = 0;
if (range > 100)
range = 100;
// draw the slider cursor
p = W_CachePatchName("M_SLIDEC", PU_CACHE);
V_DrawScaledPatch(x - 4 + (((SLIDER_RANGE)*8 + 4)*range)/100, y, 0, p);
}
static patch_t *addonsp[NUM_EXT+5];
static UINT32 bgTextScroll = 0;
@ -1582,6 +1650,275 @@ void M_DrawMPRoomSelect(void)
V_DrawFixedPatch(160<<FRACBITS, 100<<FRACBITS, FRACUNIT, (!mpmenu.room) ? (5<<V_ALPHASHIFT) : 0, butt2[(!mpmenu.room) ? 1 : 0], NULL);
}
// OPTIONS MENU
static void M_DrawOptionsCogs(void)
{
patch_t *back[3] = {W_CachePatchName("OPT_BAK1", PU_CACHE), W_CachePatchName("OPT_BAK2", PU_CACHE), W_CachePatchName("OPT_BAK3", PU_CACHE)};
V_DrawFixedPatch(0, 0, FRACUNIT, 0, back[(optionsmenu.ticker/10) %3], NULL);
}
void M_DrawOptionsMovingButton(void)
{
patch_t *butt = W_CachePatchName("OPT_BUTT", PU_CACHE);
UINT8 *c = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
V_DrawFixedPatch((optionsmenu.optx)*FRACUNIT, (optionsmenu.opty)*FRACUNIT, FRACUNIT, 0, butt, c);
V_DrawCenteredGamemodeString((optionsmenu.optx)-3, (optionsmenu.opty) - 16, V_ALLOWLOWERCASE, c, OPTIONS_MainDef.menuitems[OPTIONS_MainDef.lastOn].text);
}
void M_DrawOptions(void)
{
UINT8 i;
INT32 x = 140 - (48*itemOn) + optionsmenu.offset;
INT32 y = 70 + optionsmenu.offset;
patch_t *buttback = W_CachePatchName("OPT_BUTT", PU_CACHE);
UINT8 *c = NULL;
M_DrawOptionsCogs();
for (i=0; i < currentMenu->numitems; i++)
{
INT32 py = y - (itemOn*48);
INT32 px = x - menutransition.tics*64;
if (i == itemOn)
c = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
else
c = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLACK, GTC_CACHE);
if (!(menutransition.tics && i == itemOn))
{
V_DrawFixedPatch(px*FRACUNIT, py*FRACUNIT, FRACUNIT, 0, buttback, c);
V_DrawCenteredGamemodeString(px-3, py - 16, V_ALLOWLOWERCASE, (i == itemOn ? c : NULL), currentMenu->menuitems[i].text);
}
y += 48;
x += 48;
}
M_DrawMenuTooltips();
if (menutransition.tics)
M_DrawOptionsMovingButton();
}
void M_DrawGenericOptions(void)
{
INT32 x = currentMenu->x - menutransition.tics*48, y = currentMenu->y, w, i, cursory = 0;
M_DrawOptionsCogs();
M_DrawMenuTooltips();
M_DrawOptionsMovingButton();
for (i = 0; i < currentMenu->numitems; i++)
{
if (i == itemOn)
cursory = y;
switch (currentMenu->menuitems[i].status & IT_DISPLAY)
{
case IT_PATCH:
if (currentMenu->menuitems[i].patch && currentMenu->menuitems[i].patch[0])
{
if (currentMenu->menuitems[i].status & IT_CENTER)
{
patch_t *p;
p = W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE);
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, y, 0, p);
}
else
{
V_DrawScaledPatch(x, y, 0,
W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE));
}
}
/* FALLTHRU */
case IT_NOTHING:
case IT_DYBIGSPACE:
y += SMALLLINEHEIGHT;
break;
#if 0
case IT_BIGSLIDER:
M_DrawThermo(x, y, (consvar_t *)currentMenu->menuitems[i].itemaction);
y += LINEHEIGHT;
break;
#endif
case IT_STRING:
case IT_WHITESTRING:
if (i == itemOn)
cursory = y;
if ((currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING)
V_DrawString(x, y, 0, currentMenu->menuitems[i].text);
else
V_DrawString(x, y, highlightflags, currentMenu->menuitems[i].text);
// Cvar specific handling
switch (currentMenu->menuitems[i].status & IT_TYPE)
case IT_CVAR:
{
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
{
case IT_CV_SLIDER:
M_DrawSlider(x, y, cv, (i == itemOn));
case IT_CV_NOPRINT: // color use this
case IT_CV_INVISSLIDER: // monitor toggles use this
break;
case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false);
y += 16;
break;
default:
w = V_StringWidth(cv->string, 0);
V_DrawString(BASEVIDWIDTH - x - w, y,
((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? warningflags : highlightflags), cv->string);
if (i == itemOn)
{
V_DrawCharacter(BASEVIDWIDTH - x - 10 - w - (skullAnimCounter/5), y,
'\x1C' | highlightflags, false); // left arrow
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | highlightflags, false); // right arrow
}
break;
}
break;
}
y += STRINGHEIGHT;
break;
case IT_STRING2:
V_DrawString(x, y, 0, currentMenu->menuitems[i].text);
/* FALLTHRU */
case IT_DYLITLSPACE:
case IT_SPACE:
y += SMALLLINEHEIGHT;
break;
case IT_GRAYPATCH:
if (currentMenu->menuitems[i].patch && currentMenu->menuitems[i].patch[0])
V_DrawMappedPatch(x, y, 0,
W_CachePatchName(currentMenu->menuitems[i].patch,PU_CACHE), graymap);
y += LINEHEIGHT;
break;
case IT_TRANSTEXT:
if (currentMenu->menuitems[i].mvar1)
y = currentMenu->y+currentMenu->menuitems[i].mvar1;
/* FALLTHRU */
case IT_TRANSTEXT2:
V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text);
y += SMALLLINEHEIGHT;
break;
case IT_QUESTIONMARKS:
if (currentMenu->menuitems[i].mvar1)
y = currentMenu->y+currentMenu->menuitems[i].mvar1;
V_DrawString(x, y, V_TRANSLUCENT|V_OLDSPACING, M_CreateSecretMenuOption(currentMenu->menuitems[i].text));
y += SMALLLINEHEIGHT;
break;
case IT_HEADERTEXT: // draws 16 pixels to the left, in yellow text
if (currentMenu->menuitems[i].mvar1)
y = currentMenu->y+currentMenu->menuitems[i].mvar1;
V_DrawString(x-16, y, highlightflags, currentMenu->menuitems[i].text);
y += SMALLLINEHEIGHT;
break;
}
}
// DRAW THE SKULL CURSOR
if (((currentMenu->menuitems[itemOn].status & IT_DISPLAY) == IT_PATCH)
|| ((currentMenu->menuitems[itemOn].status & IT_DISPLAY) == IT_NOTHING))
{
V_DrawScaledPatch(x + SKULLXOFF, cursory - 5, 0,
W_CachePatchName("M_CURSOR", PU_CACHE));
}
else
{
V_DrawScaledPatch(x - 24, cursory, 0,
W_CachePatchName("M_CURSOR", PU_CACHE));
V_DrawString(x, cursory, highlightflags, currentMenu->menuitems[itemOn].text);
}
}
// Draw the video modes list, a-la-Quake
void M_DrawVideoModes(void)
{
INT32 i, j, row, col;
M_DrawOptionsCogs();
M_DrawMenuTooltips();
M_DrawOptionsMovingButton();
V_DrawCenteredString(BASEVIDWIDTH/2 + menutransition.tics*64, currentMenu->y,
highlightflags, "Choose mode, reselect to change default");
row = 41 + menutransition.tics*64;
col = currentMenu->y + 14;
for (i = 0; i < optionsmenu.vidm_nummodes; i++)
{
if (i == optionsmenu.vidm_selected)
V_DrawString(row, col, highlightflags, optionsmenu.modedescs[i].desc);
// Show multiples of 320x200 as green.
else
V_DrawString(row, col, (optionsmenu.modedescs[i].goodratio) ? recommendedflags : 0, optionsmenu.modedescs[i].desc);
col += 8;
if ((i % optionsmenu.vidm_column_size) == (optionsmenu.vidm_column_size-1))
{
row += 7*13;
col = currentMenu->y + 14;
}
}
if (optionsmenu.vidm_testingmode > 0)
{
INT32 testtime = (optionsmenu.vidm_testingmode/TICRATE) + 1;
M_CentreText(menutransition.tics*64, currentMenu->y + 75,
va("Previewing mode %c%dx%d",
(SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80,
vid.width, vid.height));
M_CentreText(menutransition.tics*64, currentMenu->y + 75+8,
"Press ENTER again to keep this mode");
M_CentreText(menutransition.tics*64, currentMenu->y + 75+16,
va("Wait %d second%s", testtime, (testtime > 1) ? "s" : ""));
M_CentreText(menutransition.tics*64, currentMenu->y + 75+24,
"or press ESC to return");
}
else
{
M_CentreText(menutransition.tics*64, currentMenu->y + 75,
va("Current mode is %c%dx%d",
(SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80,
vid.width, vid.height));
M_CentreText(menutransition.tics*64, currentMenu->y + 75+8,
va("Default mode is %c%dx%d",
(SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80,
cv_scr_width.value, cv_scr_height.value));
V_DrawCenteredString(BASEVIDWIDTH/2 + menutransition.tics*64, currentMenu->y + 75+16,
recommendedflags, "Marked modes are recommended.");
V_DrawCenteredString(BASEVIDWIDTH/2 + menutransition.tics*64, currentMenu->y + 75+24,
highlightflags, "Other modes may have visual errors.");
V_DrawCenteredString(BASEVIDWIDTH/2 + menutransition.tics*64, currentMenu->y + 75+32,
highlightflags, "Larger modes may have performance issues.");
}
// Draw the cursor for the VidMode menu
i = 41 - 10 + ((optionsmenu.vidm_selected / optionsmenu.vidm_column_size)*7*13) + menutransition.tics*64;
j = currentMenu->y + 14 + ((optionsmenu.vidm_selected % optionsmenu.vidm_column_size)*8);
V_DrawScaledPatch(i - 8, j, 0,
W_CachePatchName("M_CURSOR", PU_CACHE));
}
//
// INGAME / PAUSE MENUS
//

View file

@ -2943,6 +2943,257 @@ void M_MPRoomSelectInit(INT32 choice)
M_SetupNextMenu(&PLAY_MP_RoomSelectDef, false);
}
// Options menu:
struct optionsmenu_s optionsmenu;
void M_InitOptions(INT32 choice)
{
(void)choice;
// @TODO: Change options when you do them from a netgame.
optionsmenu.ticker = 0;
optionsmenu.offset = 0;
optionsmenu.optx = 0;
optionsmenu.opty = 0;
optionsmenu.toptx = 0;
optionsmenu.topty = 0;
OPTIONS_MainDef.prevMenu = currentMenu;
M_SetupNextMenu(&OPTIONS_MainDef, false);
}
boolean M_OptionsQuit(void)
{
optionsmenu.toptx = 140-1;
optionsmenu.topty = 70+1;
return true; // Always allow quitting, duh.
}
void M_OptionsTick(void)
{
optionsmenu.offset /= 2;
optionsmenu.ticker++;
optionsmenu.optx += (optionsmenu.toptx - optionsmenu.optx)/2;
optionsmenu.opty += (optionsmenu.topty - optionsmenu.opty)/2;
if (abs(optionsmenu.optx - optionsmenu.opty) < 2)
{
optionsmenu.optx = optionsmenu.toptx;
optionsmenu.opty = optionsmenu.topty; // Avoid awkward 1 px errors.
}
// Garbage:
if (currentMenu == &OPTIONS_MainDef)
{
M_OptionsQuit(); // ...So now this is used here.
}
else
{
optionsmenu.toptx = 160;
optionsmenu.topty = 50;
}
}
boolean M_OptionsInputs(INT32 ch)
{
switch (ch)
{
case KEY_DOWNARROW:
{
optionsmenu.offset += 48;
M_NextOpt();
if (itemOn == 0)
optionsmenu.offset -= currentMenu->numitems*48;
return true;
}
case KEY_UPARROW:
{
optionsmenu.offset -= 48;
M_PrevOpt();
if (itemOn == currentMenu->numitems-1)
optionsmenu.offset += currentMenu->numitems*48;
return true;
}
case KEY_ENTER:
{
optionsmenu.optx = 140;
optionsmenu.opty = 70; // Default position for the currently selected option.
return false; // Don't eat.
}
}
return false;
}
// setup video mode menu
void M_VideoModeMenu(INT32 choice)
{
INT32 i, j, vdup, nummodes, width, height;
const char *desc;
(void)choice;
memset(optionsmenu.modedescs, 0, sizeof(optionsmenu.modedescs));
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // FIXME: hack
#endif
optionsmenu.vidm_nummodes = 0;
optionsmenu.vidm_selected = 0;
nummodes = VID_NumModes();
#ifdef _WINDOWS
// clean that later: skip windowed mode 0, video modes menu only shows FULL SCREEN modes
if (nummodes <= NUMSPECIALMODES)
i = 0; // unless we have nothing
else
i = NUMSPECIALMODES;
#else
// DOS does not skip mode 0, because mode 0 is ALWAYS present
i = 0;
#endif
for (; i < nummodes && optionsmenu.vidm_nummodes < MAXMODEDESCS; i++)
{
desc = VID_GetModeName(i);
if (desc)
{
vdup = 0;
// when a resolution exists both under VGA and VESA, keep the
// VESA mode, which is always a higher modenum
for (j = 0; j < optionsmenu.vidm_nummodes; j++)
{
if (!strcmp(optionsmenu.modedescs[j].desc, desc))
{
// mode(0): 320x200 is always standard VGA, not vesa
if (optionsmenu.modedescs[j].modenum)
{
optionsmenu.modedescs[j].modenum = i;
vdup = 1;
if (i == vid.modenum)
optionsmenu.vidm_selected = j;
}
else
vdup = 1;
break;
}
}
if (!vdup)
{
optionsmenu.modedescs[optionsmenu.vidm_nummodes].modenum = i;
optionsmenu.modedescs[optionsmenu.vidm_nummodes].desc = desc;
if (i == vid.modenum)
optionsmenu.vidm_selected = optionsmenu.vidm_nummodes;
// Pull out the width and height
sscanf(desc, "%u%*c%u", &width, &height);
// Show multiples of 320x200 as green.
if (SCR_IsAspectCorrect(width, height))
optionsmenu.modedescs[optionsmenu.vidm_nummodes].goodratio = 1;
optionsmenu.vidm_nummodes++;
}
}
}
optionsmenu.vidm_column_size = (optionsmenu.vidm_nummodes+2) / 3;
M_SetupNextMenu(&OPTIONS_VideoModesDef, false);
}
// special menuitem key handler for video mode list
void M_HandleVideoModes(INT32 ch)
{
if (optionsmenu.vidm_testingmode > 0) switch (ch)
{
// change back to the previous mode quickly
case KEY_ESCAPE:
setmodeneeded = optionsmenu.vidm_previousmode + 1;
optionsmenu.vidm_testingmode = 0;
break;
case KEY_ENTER:
S_StartSound(NULL, sfx_menu1);
optionsmenu.vidm_testingmode = 0; // stop testing
}
else switch (ch)
{
case KEY_DOWNARROW:
S_StartSound(NULL, sfx_menu1);
if (++optionsmenu.vidm_selected >= optionsmenu.vidm_nummodes)
optionsmenu.vidm_selected = 0;
break;
case KEY_UPARROW:
S_StartSound(NULL, sfx_menu1);
if (--optionsmenu.vidm_selected < 0)
optionsmenu.vidm_selected = optionsmenu.vidm_nummodes - 1;
break;
case KEY_LEFTARROW:
S_StartSound(NULL, sfx_menu1);
optionsmenu.vidm_selected -= optionsmenu.vidm_column_size;
if (optionsmenu.vidm_selected < 0)
optionsmenu.vidm_selected = (optionsmenu.vidm_column_size*3) + optionsmenu.vidm_selected;
if (optionsmenu.vidm_selected >= optionsmenu.vidm_nummodes)
optionsmenu.vidm_selected = optionsmenu.vidm_nummodes - 1;
break;
case KEY_RIGHTARROW:
S_StartSound(NULL, sfx_menu1);
optionsmenu.vidm_selected += optionsmenu.vidm_column_size;
if (optionsmenu.vidm_selected >= (optionsmenu.vidm_column_size*3))
optionsmenu.vidm_selected %= optionsmenu.vidm_column_size;
if (optionsmenu.vidm_selected >= optionsmenu.vidm_nummodes)
optionsmenu.vidm_selected = optionsmenu.vidm_nummodes - 1;
break;
case KEY_ENTER:
S_StartSound(NULL, sfx_menu1);
if (vid.modenum == optionsmenu.modedescs[optionsmenu.vidm_selected].modenum)
SCR_SetDefaultMode();
else
{
optionsmenu.vidm_testingmode = 15*TICRATE;
optionsmenu.vidm_previousmode = vid.modenum;
if (!setmodeneeded) // in case the previous setmode was not finished
setmodeneeded = optionsmenu.modedescs[optionsmenu.vidm_selected].modenum + 1;
}
break;
case KEY_ESCAPE: // this one same as M_Responder
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu, false);
else
M_ClearMenus(true);
break;
default:
break;
}
}
// =====================
// PAUSE / IN-GAME MENUS
// =====================