mirror of
https://github.com/nzp-team/quakec.git
synced 2024-12-11 05:00:52 +00:00
850 lines
25 KiB
C++
850 lines
25 KiB
C++
vector MENU_BG = '0.2 0.3 0.4';
|
|
vector MENU_BG_DARK = '0.1 0.15 0.2';
|
|
vector MENU_BORDER = '0.3 0.4 0.5';
|
|
vector MENU_BUTTON = '0.3 0.4 0.5';
|
|
vector MENU_BUTTON_BORDER = '0.35 0.45 0.55';
|
|
vector MENU_TEXT_1 = '1 1 1';
|
|
vector MENU_TEXT_2 = '0.7 0.75 0.75';
|
|
vector MENU_HIGHLIGHT = '1 1 1';
|
|
vector MENU_DARKEN = '1 1 1';
|
|
|
|
vector MENU_TEXT_SUPERSMALL = '10 10 0';
|
|
vector MENU_TEXT_SMALL = '12 12 0';
|
|
vector MENU_TEXT_MEDIUM = '14 14 0';
|
|
vector MENU_TEXT_LARGE = '28 28 0';
|
|
|
|
void() input_tester =
|
|
{
|
|
float char = 0;
|
|
float scan = 0;
|
|
string printme = "";
|
|
while (sui_get_input(char, scan))
|
|
{
|
|
printme = strcat(printme, chr2str(char));
|
|
}
|
|
};
|
|
|
|
void(string id, vector pos, vector size, float maxlen, __inout string text, __inout float cursor) text_input_control =
|
|
{
|
|
vector textsize = [size_y - 4, size_y - 4];
|
|
sui_push_frame(pos, size);
|
|
vector basecolor = sui_is_hovered(id) ? MENU_BG_DARK + MENU_HIGHLIGHT * 0.08 : MENU_BG_DARK;
|
|
sui_fill([0, 0], size, basecolor, 0.6, 0);
|
|
|
|
sui_text_input(id, [0, 0], size, maxlen, text, cursor);
|
|
|
|
sui_cap_input_length(maxlen, text, cursor);
|
|
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_CENTER]);
|
|
float focused = sui_is_last_clicked(id);
|
|
// Under focus
|
|
focused ? sui_border_box([0, 0], size, 1, MENU_BORDER, 0.6, 0) : 0;
|
|
|
|
sui_push_frame([2, 0], [size_x - 4, size_y - 4]);
|
|
|
|
float cursorx;
|
|
if (stringwidth(text, 1, textsize) > size_x - 4)
|
|
{
|
|
sui_clip_to_frame();
|
|
cursorx = 0;
|
|
sui_set_align([SUI_ALIGN_END, SUI_ALIGN_CENTER]);
|
|
sui_text([0, 0], textsize, text, MENU_TEXT_1, 1, 0);
|
|
}
|
|
else
|
|
{
|
|
cursorx = stringwidth(substring(text, 0, cursor), 1, textsize);
|
|
sui_text([0, 0], textsize, text, MENU_TEXT_1, 1, 0);
|
|
}
|
|
if (focused)
|
|
{
|
|
sui_fill([cursorx, 0], [2, textsize_y], MENU_TEXT_1, fabs(sin(time * 4)), 0);
|
|
}
|
|
sui_reset_clip();
|
|
sui_pop_frame();
|
|
|
|
sui_pop_frame();
|
|
};
|
|
|
|
//
|
|
// Menu_DrawDivider(order)
|
|
// Draws a division line between menu
|
|
// entries.
|
|
//
|
|
void(float order) Menu_DrawDivider =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
vector position = [0, 45 + (order * 25)];
|
|
sui_fill(position, [285, 2], [0.2, 0.2, 0.2], 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_SocialBadge(order, id, text, index)
|
|
// Displays a social badge with a URL
|
|
// when hovered over with the mouse.
|
|
//
|
|
void(float order, string id, string text, float index) Menu_SocialBadge =
|
|
{
|
|
sui_set_align([SUI_ALIGN_END, SUI_ALIGN_END]);
|
|
|
|
vector position = [-6, -62 - ((order - 1) * 30)];
|
|
vector coords_size = [0.5, 0.5];
|
|
vector coords_pos = [0, 0];
|
|
|
|
switch(index) {
|
|
case 1: coords_pos = [0, 0]; break;
|
|
case 2: coords_pos = [0.5, 0]; break;
|
|
case 3: coords_pos = [0, 0.5]; break;
|
|
case 4: coords_pos = [0.5, 0.5]; break;
|
|
}
|
|
|
|
sui_subpic(position, [28, 28], "gfx/menu/social", [1, 1, 1], coords_pos, coords_size, 1, 0);
|
|
|
|
if (sui_is_hovered(id)) {
|
|
sui_fill(position - [36, 8], [getTextWidth(text, MENU_TEXT_SUPERSMALL_x) + 1, 10], [0, 0, 0], 0.9, 0);
|
|
sui_text(position - [35, 8], MENU_TEXT_SUPERSMALL, text, [1, 1, 0], 1, 0);
|
|
}
|
|
|
|
sui_action_element(position, [28, 28], id, sui_noop);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawYesNoPanel()
|
|
// Draws a ribbon over the screen typically used
|
|
// for Yes/No message boxes.
|
|
//
|
|
void(string line_1, string line_2) Menu_DrawYesNoPanel =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
sui_fill([0, 0], sui_current_frame_size(), [0.01, 0, 0], 0.5, 0);
|
|
|
|
// Black Fill
|
|
sui_fill([0, 160], [sui_current_frame_size()[0], 160], [0, 0, 0], 1, 0);
|
|
|
|
// Yellow borders
|
|
sui_fill([0, 160], [sui_current_frame_size()[0], 3], [1, 1, 0], 0.9, 0);
|
|
sui_fill([0, sui_current_frame_size()[1] - 160], [sui_current_frame_size()[0], 3], [1, 1, 0], 0.9, 0);
|
|
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_START]);
|
|
sui_text([0, 170], MENU_TEXT_MEDIUM, line_1, [1, 1, 1], 1, 0);
|
|
sui_text([0, 190], MENU_TEXT_MEDIUM, line_2, [1, 1, 1], 1, 0);
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawMapPanel()
|
|
// Draws a translucent box on the right
|
|
// side of the window to make map text easier
|
|
// to read.
|
|
//
|
|
void() Menu_DrawMapPanel =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
sui_fill([300, 55], [sui_current_frame_size()[0], sui_current_frame_size()[1] - 55 - 58], [0, 0, 0], 0.9, 0);
|
|
sui_fill([300, 55], [3, sui_current_frame_size()[1] - 55 - 58], [1, 1, 0], 0.9, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawOptionValue(order, value)
|
|
// Draws the value of the option at a given order.
|
|
//
|
|
void(float order, string value) Menu_DrawOptionValue =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
vector position = [320, 50 + (order * 25)];
|
|
sui_text(position, MENU_TEXT_MEDIUM, value, [1, 1, 1], 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawOptionKey(order, value)
|
|
// Draws a key/glyph at a given order.
|
|
//
|
|
void(float order, string bind) Menu_DrawOptionKey =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
vector position = [320, 50 + (order * 25)];
|
|
float keynum = stringtokeynum(bind);
|
|
|
|
if (keynum >= 816 && keynum <= 839) {
|
|
vector tilemap_position = [0, 0];
|
|
|
|
// Get the position of the button in the tilemap.
|
|
switch(keynum) {
|
|
case K_GP_A: tilemap_position = [0, 0]; break;
|
|
case K_GP_B: tilemap_position = [0.125, 0]; break;
|
|
case K_GP_X: tilemap_position = [0.250, 0]; break;
|
|
case K_GP_Y: tilemap_position = [0.375, 0]; break;
|
|
case K_GP_LSHOULDER: tilemap_position = [0.250, 0.125]; break;
|
|
case K_GP_RSHOULDER: tilemap_position = [0.375, 0.125]; break;
|
|
case K_GP_LTRIGGER: tilemap_position = [0.500, 0.125]; break;
|
|
case K_GP_RTRIGGER: tilemap_position = [0.625, 0.125]; break;
|
|
case K_GP_BACK: tilemap_position = [0.875, 0.125]; break;
|
|
case K_GP_START: tilemap_position = [0.750, 0.125]; break;
|
|
case K_GP_LTHUMB: tilemap_position = [0, 0.125]; break;
|
|
case K_GP_RTHUMB: tilemap_position = [0.125, 0.125]; break;
|
|
case K_GP_DPAD_UP: tilemap_position = [0.500, 0]; break;
|
|
case K_GP_DPAD_DOWN: tilemap_position = [0.625, 0]; break;
|
|
case K_GP_DPAD_LEFT: tilemap_position = [0.750, 0]; break;
|
|
case K_GP_DPAD_RIGHT: tilemap_position = [0.875, 0]; break;
|
|
}
|
|
|
|
sui_subpic([position_x, position_y - 2], [MENU_TEXT_MEDIUM_x + 5, MENU_TEXT_MEDIUM_x + 5], sprintf("gfx/controller_glyphs/%s.tga", cvar_string("cl_controllerglyphs")), [1, 1, 1], tilemap_position, [0.125, 0.125], 1, 0);
|
|
}
|
|
else {
|
|
sui_text(position, MENU_TEXT_MEDIUM, bind, [1, 1, 0], 1, 0);
|
|
}
|
|
};
|
|
|
|
//
|
|
// Menu_MapButton(order, id, bsp_name)
|
|
// Displays a fancy menu option that loads
|
|
// and draws the details for the given
|
|
// .BSP.
|
|
//
|
|
float(float order, string id, string bsp_name, float usermap_index) Menu_MapButton =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
float is_hovered = sui_is_hovered(id);
|
|
vector text_color = is_hovered ? [1, 0, 0] : [1, 1, 1];
|
|
vector position = [6, 50 + (order * 25)];
|
|
vector bbox_pos = position - [6, 5, 0];
|
|
vector bbox_size = [290, 22];
|
|
|
|
if (is_hovered) {
|
|
// Background
|
|
sui_fill(bbox_pos, bbox_size, [0, 0, 0], 0.9, 0);
|
|
// Top
|
|
sui_fill(bbox_pos, [bbox_size_x, 2], [0.4, 0, 0], 1, 0);
|
|
// Bottom
|
|
sui_fill(bbox_pos + [0, bbox_size_y - 2], [bbox_size_x, 2], [0.4, 0, 0], 1, 0);
|
|
// Right
|
|
sui_fill(bbox_pos + [bbox_size_x - 2, 0], [2, bbox_size_y], [0.4, 0, 0], 1, 0);
|
|
}
|
|
|
|
int i;
|
|
int index = 0;
|
|
|
|
// Draw the map data from stock_maps
|
|
if (usermap_index == -1) {
|
|
for(i = 0; i < stock_maps.length; i++) {
|
|
if (stock_maps[i].bsp_name == bsp_name) {
|
|
index = stock_maps[i].array_index;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
index = usermap_index;
|
|
}
|
|
|
|
// Map title
|
|
string title = user_maps[index].map_name_pretty;
|
|
if (!title)
|
|
title = user_maps[index].map_name;
|
|
sui_text(position - [getTextWidth(strtoupper(title), MENU_TEXT_MEDIUM_x), 0, 0] + [275, 0, 0], MENU_TEXT_MEDIUM, strtoupper(title), text_color, 1, 0);
|
|
|
|
if (is_hovered) {
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_CENTER]);
|
|
|
|
// Map thumbnail
|
|
if (user_maps[index].map_use_thumbnail) {
|
|
sui_fill([150, -70], [302, 174], [0.4, 0.4, 0.4], 1, 0);
|
|
sui_pic([150, -70], [300, 170], strcat("menu/custom/", user_maps[index].map_name, ".png"), [1, 1, 1], 1, 0);
|
|
}
|
|
|
|
// Map description
|
|
for(i = 0; i < 8; i++) {
|
|
sui_text([150, 30 + (i * 14)], MENU_TEXT_SMALL, user_maps[index].map_desc[i], [1, 1, 1], 1, 0);
|
|
}
|
|
|
|
// Author/Description
|
|
if (user_maps[index].map_author) {
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_END]);
|
|
string author = user_maps[index].map_author;
|
|
|
|
sui_text([0, -30], MENU_TEXT_MEDIUM, title, [1, 1, 1], 1, 0);
|
|
sui_text([0, -15], MENU_TEXT_MEDIUM, author, [1, 1, 0], 1, 0);
|
|
}
|
|
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
}
|
|
|
|
sui_action_element(bbox_pos, bbox_size, id, sui_noop);
|
|
|
|
return sui_is_clicked(id);
|
|
}
|
|
|
|
//
|
|
// Menu_GreyButton(order, title)
|
|
// Draws Grey (unselect-able text) in place of
|
|
// menu button.
|
|
//
|
|
void(float order, string title) Menu_GreyButton =
|
|
{
|
|
vector alignment;
|
|
|
|
if (order > 0) alignment = [SUI_ALIGN_START, SUI_ALIGN_START];
|
|
else alignment = [SUI_ALIGN_START, SUI_ALIGN_END];
|
|
|
|
sui_set_align(alignment);
|
|
|
|
vector text_color = [0.5, 0.3, 0.3]; // make it kinda red, for flavor.
|
|
vector position;
|
|
|
|
if (order > 0) {
|
|
position = [6, 50 + (order * 25)];
|
|
} else {
|
|
position = [6, -50 + (order * 25)];
|
|
}
|
|
|
|
sui_text(position - [getTextWidth(title, MENU_TEXT_MEDIUM_x), 0, 0] + [275, 0, 0], MENU_TEXT_MEDIUM, title, text_color, 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_Button(order, id, title, description)
|
|
// Displays a menu option and draws the description
|
|
// plus flair if selected.
|
|
//
|
|
float(float order, string id, string title, string description) Menu_Button =
|
|
{
|
|
vector alignment;
|
|
|
|
if (order > 0) alignment = [SUI_ALIGN_START, SUI_ALIGN_START];
|
|
else alignment = [SUI_ALIGN_START, SUI_ALIGN_END];
|
|
|
|
sui_set_align(alignment);
|
|
|
|
float is_hovered = sui_is_hovered(id);
|
|
vector text_color = is_hovered ? [1, 0, 0] : [1, 1, 1];
|
|
vector position, bbox_pos;
|
|
|
|
if (order > 0) {
|
|
position = [6, 50 + (order * 25)];
|
|
bbox_pos = position - [6, 5, 0];
|
|
} else {
|
|
position = [6, -50 + (order * 25)];
|
|
bbox_pos = position + [-6, 5, 0];
|
|
}
|
|
|
|
vector bbox_size = [290, 22];
|
|
|
|
if (is_hovered) {
|
|
// Description
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_END]);
|
|
sui_text([0, -30], MENU_TEXT_MEDIUM, description, [1, 1, 1], 1, 0);
|
|
sui_set_align(alignment);
|
|
|
|
// Background
|
|
sui_fill(bbox_pos, bbox_size, [0, 0, 0], 0.9, 0);
|
|
|
|
if (order > 0) {
|
|
// Top
|
|
sui_fill(bbox_pos, [bbox_size_x, 2], [0.4, 0, 0], 1, 0);
|
|
// Bottom
|
|
sui_fill(bbox_pos + [0, bbox_size_y - 2], [bbox_size_x, 2], [0.4, 0, 0], 1, 0);
|
|
} else {
|
|
// Top
|
|
sui_fill(bbox_pos - [0, bbox_size_y], [bbox_size_x, 2], [0.4, 0, 0], 1, 0);
|
|
// Bottom
|
|
sui_fill(bbox_pos, [bbox_size_x, 2], [0.4, 0, 0], 1, 0);
|
|
}
|
|
|
|
// Right
|
|
sui_fill(bbox_pos + [bbox_size_x - 2, 0], [2, bbox_size_y], [0.4, 0, 0], 1, 0);
|
|
}
|
|
|
|
sui_text(position - [getTextWidth(title, MENU_TEXT_MEDIUM_x), 0, 0] + [275, 0, 0], MENU_TEXT_MEDIUM, title, text_color, 1, 0);
|
|
sui_action_element(bbox_pos, bbox_size, id, sui_noop);
|
|
|
|
return sui_is_clicked(id);
|
|
};
|
|
|
|
float(string id, vector pos, vector size, string text) my_button =
|
|
{
|
|
sui_push_frame(pos, size);
|
|
vector basecolor = sui_is_hovered(id) ? MENU_BUTTON + MENU_HIGHLIGHT * 0.1 : MENU_BUTTON;
|
|
basecolor = sui_is_held(id) ? MENU_BUTTON - MENU_DARKEN * 0.1 : basecolor;
|
|
sui_fill([0, 0], size, basecolor, 0.6, 0);
|
|
sui_border_box([0, 0], size, 1, MENU_BUTTON_BORDER, 0.4, 0);
|
|
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_CENTER]);
|
|
sui_text([0, 0], MENU_TEXT_SMALL, text, MENU_TEXT_1, 1, 0);
|
|
sui_action_element([0, 0], size, id, sui_noop);
|
|
sui_pop_frame();
|
|
|
|
return sui_is_clicked(id);
|
|
};
|
|
|
|
|
|
//
|
|
// Menu_DrawControllerGlyphDemo(order)
|
|
// Draws ABXY on the same line as an OptionVal to demonstrate
|
|
// the current cl_controllerglyphs value.
|
|
//
|
|
void(float order) Menu_DrawControllerGlyphDemo =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
vector tilemap_positions[4] = {[0, 0], [0.125, 0], [0.250, 0], [0.375, 0]};
|
|
vector position = [450, 50 + (order * 25)];
|
|
|
|
for(int i = 0; i < 4; i++) {
|
|
sui_subpic(position, [MENU_TEXT_MEDIUM_x, MENU_TEXT_MEDIUM_x], sprintf("gfx/controller_glyphs/%s.tga", cvar_string("cl_controllerglyphs")), [1, 1, 1], tilemap_positions[i], [0.125, 0.125], 1, 0);
|
|
position_x += 14;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Menu_DrawCreditHeader()
|
|
// Wrapper for drawing the role/title in credits.
|
|
//
|
|
void(float order, string header) Menu_DrawCreditHeader =
|
|
{
|
|
vector position = [8, 60 + (order * 60)];
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
sui_text(position - [getTextWidth(header, MENU_TEXT_SMALL_x), 0, 0] + [275, 0, 0], MENU_TEXT_SMALL, header, [1, 1, 0], 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawCreditContributor()
|
|
// Wrapper for drawing the contributor list in credits.
|
|
//
|
|
void(float order, float sub_order, string header) Menu_DrawCreditContributor =
|
|
{
|
|
vector position = [315, 60 + (order * 60)];
|
|
position_y += sub_order * (MENU_TEXT_SUPERSMALL_x + 3);
|
|
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
sui_text(position, MENU_TEXT_SUPERSMALL, header, [1, 1, 1], 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawBuildDate()
|
|
// Wrapper for drawing the build date
|
|
// retrieved from nzp/version.txt
|
|
//
|
|
void() Menu_DrawBuildDate =
|
|
{
|
|
sui_set_align([SUI_ALIGN_END, SUI_ALIGN_START]);
|
|
sui_text([-6, 8], MENU_TEXT_SMALL, build_datetime, [1, 1, 1], 1, 0);
|
|
sui_text([-6, 22], MENU_TEXT_SMALL, sprintf("Welcome, %s", cvar_string("name")), [1, 1, 0], 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawBackground()
|
|
// Wrapper for drawing menu background,
|
|
// i.e., the Zombie pose with a black
|
|
// background for readibility, and some
|
|
// style lines.
|
|
//
|
|
void() Menu_DrawBackground =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
#ifdef MENU
|
|
|
|
float elapsed_background_time = time - menu_starttime;
|
|
|
|
//
|
|
// Slight background pan
|
|
//
|
|
float x_pos = 0 - (((sui_current_frame_size()[0] * 1.05) - sui_current_frame_size()[0]) * (elapsed_background_time/7));
|
|
|
|
sui_pic([x_pos, 0], [sui_current_frame_size()[0] * 1.05, sui_current_frame_size()[1]], menu_background, [1, 1, 1], 1, 1);
|
|
sui_fill([0, 0], sui_current_frame_size(), [0, 0, 0], 0.7, 0);
|
|
|
|
//
|
|
// Fade new images in/out
|
|
//
|
|
float alpha = 0;
|
|
|
|
if (elapsed_background_time < 1.0) {
|
|
alpha = 1.0f - sin((elapsed_background_time / 1.0f) * (M_PI / 2)); // Opacity from 1 -> 0
|
|
} else if (elapsed_background_time < 6.0f) {
|
|
alpha = 0.0f;
|
|
} else if (elapsed_background_time < 7.0f) {
|
|
alpha = sin(((elapsed_background_time - 6.0f) / 1.0f) * (M_PI / 2)); // Opacity from 0 -> 1
|
|
}
|
|
|
|
sui_fill([0, 0], sui_current_frame_size(), [0, 0, 0], alpha, 0);
|
|
|
|
#else
|
|
|
|
sui_fill([0, 0], sui_current_frame_size(), [0, 0, 0], 0.8, 0);
|
|
|
|
#endif // MENU
|
|
|
|
// Top Bars
|
|
sui_fill([0, 0], [sui_current_frame_size()[0], 55], [0, 0, 0], 0.9, 0);
|
|
sui_fill([0, 52], [sui_current_frame_size()[0], 3], [0.2, 0.2, 0.2], 1, 0);
|
|
|
|
// Bottom Bars
|
|
sui_fill([0, sui_current_frame_size()[1] - 55], [sui_current_frame_size()[0], 55], [0, 0, 0], 0.9, 0);
|
|
sui_fill([0, sui_current_frame_size()[1] - 58], [sui_current_frame_size()[0], 3], [0.2, 0.2, 0.2], 1, 0);
|
|
};
|
|
|
|
//
|
|
// Menu_DrawTitle(menu_title)
|
|
// Wrapper for drawing the current Menu title
|
|
// in the desired location + at the desired size.
|
|
//
|
|
void(string menu_title) Menu_DrawTitle =
|
|
{
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
sui_text([6, 18], MENU_TEXT_LARGE, menu_title, [1, 1, 1], 1, 0);
|
|
};
|
|
|
|
void(string id, vector pos, vector size, vector minmaxsteps, __inout float value) my_slider =
|
|
{
|
|
sui_push_frame(pos, size);
|
|
|
|
value = sui_slidercontrol(id, [0, 0], size, minmaxsteps, value, sui_slider_noop);
|
|
float maxval = minmaxsteps[1];
|
|
float sliderx = (value / maxval) * size_x;
|
|
sui_fill([0, size_y * 0.25], [size_x, size_y * 0.5], [0.5, 0.1, 0.1], 1.0, 0);
|
|
sui_fill([sliderx - 2, 0], [4, size_y], [0.6, 0.4, 0.4], 1.0, 0);
|
|
|
|
sui_pop_frame();
|
|
};
|
|
|
|
void(vector pos, vector size, vector minmaxsteps, string cvar_s, string name, string format) cvar_slider =
|
|
{
|
|
float current = cvar(cvar_s);
|
|
float old = current;
|
|
sui_push_frame(pos, [size_x, size_y * 0.5 - 4]);
|
|
sui_text([0, 0], MENU_TEXT_SMALL, name, MENU_TEXT_1, 1, 0);
|
|
sui_set_align([SUI_ALIGN_END, SUI_ALIGN_START]);
|
|
sui_text([0, 0], MENU_TEXT_SMALL, sprintf(format, current), MENU_TEXT_1, 1, 0);
|
|
sui_pop_frame();
|
|
my_slider(strcat(cvar_s, "sldr"), [pos_x, pos_y + size_y * 0.5], [size_x, size_y * 0.5], minmaxsteps, current);
|
|
if (current != old) cvar_set(cvar_s, ftos(current));
|
|
};
|
|
|
|
//
|
|
// Menu_CvarSlider(order, minmaxsteps, cvar_s, is_int, no_text)
|
|
// Draws a Slider at the given order position
|
|
// that controls a cvar.
|
|
//
|
|
void(float order, vector minmaxsteps, string cvar_s, float is_int, float no_text) Menu_CvarSlider =
|
|
{
|
|
float current = cvar(cvar_s);
|
|
float old = current;
|
|
|
|
vector position = [320, 50 + (order * 25)];
|
|
vector size = [150, 30];
|
|
|
|
my_slider(strcat(cvar_s, "sldr"), [position_x, (position_y - 17) + size_y * 0.5], [size_x, size_y * 0.5], minmaxsteps, current);
|
|
|
|
if (current != old) {
|
|
if (is_int)
|
|
cvar_set(cvar_s, ftos(rint(current)));
|
|
else
|
|
cvar_set(cvar_s, ftos(current));
|
|
}
|
|
|
|
if (!no_text) {
|
|
if (is_int)
|
|
sui_text(position + [175, 0, 0], MENU_TEXT_MEDIUM, ftos(rint(current)), [1, 1, 1], 1, 0);
|
|
else
|
|
sui_text(position + [175, 0, 0], MENU_TEXT_MEDIUM, ftos(current), [1, 1, 1], 1, 0);
|
|
}
|
|
};
|
|
|
|
static void(string id, vector pos, vector size, __inout string text, __inout float cursor) handle_text_input =
|
|
{
|
|
// best length to fit the largest character in the font
|
|
// ex: AAAAAAAAAAAAAAAAAAAAAAA
|
|
float maxlen = 23;
|
|
|
|
sui_action_element(pos, size, id, sui_noop);
|
|
if (sui_is_clicked(id)) cursor = strlen(text);
|
|
if (sui_is_hovered(id))
|
|
{
|
|
float char = 0;
|
|
float scan = 0;
|
|
while(sui_get_input(char, scan)) sui_handle_text_input(char, scan, maxlen, text, cursor);
|
|
}
|
|
};
|
|
|
|
static void(string id, vector pos, vector size, string text, float cursor) draw_text_input =
|
|
{
|
|
sui_push_frame(pos - [6, 5], size);
|
|
sui_fill([0, 0], size, [0, 0, 0], 1.0, 0);
|
|
sui_border_box([0, 0], size, 2, [0.2, 0.2, 0.2], 0.3, 0);
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_CENTER]);
|
|
sui_text([6, 0], MENU_TEXT_SMALL, text, MENU_TEXT_1, 1, 0);
|
|
float cursor_x = getTextWidth(substring(text, 0, cursor), MENU_TEXT_SMALL.x);
|
|
if (sui_is_hovered(id))
|
|
sui_text([6 + cursor_x, 0], MENU_TEXT_SMALL, "|", [1.0, 0.25, 0.25], 1, 0);
|
|
sui_pop_frame();
|
|
};
|
|
|
|
//
|
|
// Menu_TextInput(id, order, text, cursor)
|
|
// Draws a Text Input box at the given order position
|
|
//
|
|
void(string id, float order, __inout string text, __inout float cursor) Menu_TextInput =
|
|
{
|
|
vector pos = [320, 50 + (order * 25)];
|
|
vector size = [290, 22];
|
|
|
|
handle_text_input(id, pos, size, text, cursor);
|
|
|
|
draw_text_input(id, pos, size, text, cursor);
|
|
};
|
|
|
|
//
|
|
// Menu_PasswordInput(id, order, text, cursor)
|
|
// Draws a Text Input box at the given order position (blocked out with asterisks)
|
|
//
|
|
void(string id, float order, __inout string text, __inout float cursor) Menu_PasswordInput =
|
|
{
|
|
vector pos = [320, 50 + (order * 25)];
|
|
vector size = [290, 22];
|
|
string safe = "";
|
|
|
|
for (int i = 0; i < strlen(text); i++)
|
|
safe = sprintf("%s%s", safe, "*");
|
|
|
|
handle_text_input(id, pos, size, text, cursor);
|
|
|
|
draw_text_input(id, pos, size, safe, cursor);
|
|
};
|
|
|
|
static string(string s) str2ascii =
|
|
{
|
|
for (int i = 0; i < strlen(s); i++)
|
|
{
|
|
if (s[i] < 32 || s[i] > 126)
|
|
s[i] = 63; // question mark
|
|
}
|
|
return s;
|
|
};
|
|
|
|
//
|
|
// Menu_ServerList(id, pos, size, scrollofs, num_servers)
|
|
// Draw the master server list
|
|
//
|
|
void(float type) Menu_PlaySound;
|
|
void(string id, vector pos, vector size, __inout vector scrollofs, float num_servers) Menu_ServerList =
|
|
{
|
|
vector rowsize = [size.x, 16];
|
|
vector listitem_pos = [0, 0, 0];
|
|
sui_fill(pos, size, [0, 0, 0], 0.75, 0);
|
|
sui_list_view_begin(strcat(id, "scrl"), pos, size, rowsize, num_servers, scrollofs, [0, 16]);
|
|
for (float index = sui_list_item(listitem_pos); index > -1; index = sui_list_item(listitem_pos))
|
|
{
|
|
sui_push_frame(listitem_pos, rowsize);
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_CENTER]);
|
|
|
|
string listitem_id = strcat(id, "scrl", ftos(index));
|
|
sui_action_element([0, 0], rowsize, listitem_id, sui_noop);
|
|
|
|
// bg
|
|
vector bpos = [0, 0];
|
|
vector bsize = [(rowsize.x / 8) * 5, rowsize.y];
|
|
sui_fill(bpos, rowsize, [0.25, 0.1, 0.1], 0.5, 0);
|
|
|
|
// hovered bg
|
|
if (sui_is_hovered(listitem_id))
|
|
sui_fill(bpos, rowsize, [0.25, 0.1, 0.1], 0.5, 0);
|
|
|
|
#ifdef MENU
|
|
// do it
|
|
if (sui_is_clicked(listitem_id)) {
|
|
Menu_PlaySound(MENU_SND_ENTER);
|
|
m_toggle(false);
|
|
map_name_override = gethostcachestring(gethostcacheindexforkey("map"), index);
|
|
localcmd("connect ", gethostcachestring(gethostcacheindexforkey("cname"), index), "\n");
|
|
}
|
|
#endif // MENU
|
|
|
|
// name
|
|
sui_fill(bpos, bsize, [0.25, 0.1, 0.1], 0.5, 0);
|
|
sui_text(bpos + [8, 0], MENU_TEXT_SMALL, str2ascii(gethostcachestring(gethostcacheindexforkey("name"), index)), MENU_TEXT_1, 1, 0);
|
|
|
|
// map
|
|
bsize.x = (rowsize.x / 8);
|
|
bpos.x = bsize.x * 5;
|
|
sui_text(bpos + [8, 0], MENU_TEXT_SMALL, gethostcachestring(gethostcacheindexforkey("map"), index), MENU_TEXT_1, 1, 0);
|
|
|
|
// players
|
|
bpos.x = bsize.x * 7;
|
|
string s = sprintf("%d/%d",
|
|
stof(gethostcachestring(gethostcacheindexforkey("numhumans"), index)),
|
|
stof(gethostcachestring(gethostcacheindexforkey("maxplayers"), index))
|
|
);
|
|
sui_fill(bpos, bsize, [0.25, 0.1, 0.1], 0.5, 0);
|
|
sui_text(bpos + [8, 0], MENU_TEXT_SMALL, s, MENU_TEXT_1, 1, 0);
|
|
|
|
// hovered border
|
|
bpos = [0, 0];
|
|
if (sui_is_hovered(listitem_id))
|
|
sui_border_box(bpos, rowsize, 1, [0.4, 0.4, 0], 1, 0);
|
|
|
|
sui_pop_frame();
|
|
}
|
|
sui_list_view_end();
|
|
};
|
|
|
|
void() Menu_StartCoop =
|
|
{
|
|
localcmd("sv_public 2\n");
|
|
current_menu = MENU_COOPSTOCK;
|
|
};
|
|
|
|
void() Menu_StartSolo =
|
|
{
|
|
localcmd("sv_public 0\n");
|
|
current_menu = MENU_SOLO;
|
|
};
|
|
|
|
struct name_command {
|
|
string name;
|
|
string command;
|
|
};
|
|
|
|
name_command bindlist[] =
|
|
{
|
|
{ "Forward", "+forward" },
|
|
{ "Back", "+back" },
|
|
{ "Left", "+moveleft" },
|
|
{ "Right", "+moveright" },
|
|
{ "Jump", "+jump" }
|
|
};
|
|
|
|
void(string id, vector pos, vector size, string name, string command) bind_button =
|
|
{
|
|
sui_push_frame(pos, size);
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_CENTER]);
|
|
string key = sui_binder(id, [0, 0], size, name, command);
|
|
if (sui_is_hovered(id)) sui_fill([0, 0], size, MENU_HIGHLIGHT, 0.1, 0);
|
|
sui_text([6, 0], MENU_TEXT_SMALL, name, MENU_TEXT_1, 1, 0);
|
|
sui_set_align([SUI_ALIGN_END, SUI_ALIGN_CENTER]);
|
|
sui_text([-6, 0], MENU_TEXT_SMALL, key, MENU_TEXT_1, 1, 0);
|
|
|
|
sui_pop_frame();
|
|
};
|
|
|
|
|
|
void(string id, vector pos, vector size, __inout vector scrollofs) bind_list =
|
|
{
|
|
sui_fill(pos, size, MENU_BG_DARK, 0.75, 0);
|
|
sui_list_view_begin(strcat(id, "scrl"), pos, size, [size_x - 6, 24], bindlist.length, scrollofs, [0, 6]);
|
|
vector listitem_pos = '0 0 0';
|
|
for (float index = sui_list_item(listitem_pos); index > -1; index = sui_list_item(listitem_pos))
|
|
{
|
|
sui_push_frame(listitem_pos, [size_x - 6, 24]);
|
|
bind_button(strcat(id, ftos(index)), [0, 0], [size_x - 6, 24], bindlist[index].name, bindlist[index].command);
|
|
sui_pop_frame();
|
|
}
|
|
sui_list_view_end();
|
|
};
|
|
|
|
vector binds_scroll;
|
|
void() settings_menu =
|
|
{
|
|
vector pos = [0, 0];
|
|
vector size = [360, 280];
|
|
|
|
sui_push_frame(pos, size);
|
|
|
|
sui_fill([0, 0], size, MENU_BG, 0.75, 0);
|
|
sui_border_box([0, 0], size, 2, MENU_BORDER, 0.3, 0);
|
|
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_START]);
|
|
sui_text([0, 4], MENU_TEXT_MEDIUM, "Settings", MENU_TEXT_1, 1, 0);
|
|
|
|
|
|
sui_set_align([SUI_ALIGN_START, SUI_ALIGN_START]);
|
|
|
|
float xpos = 8;
|
|
float ypos = 32;
|
|
float width = size_x * 0.5 - 8 * 2;
|
|
sui_text([xpos, ypos], MENU_TEXT_SMALL, "Controls", MENU_TEXT_1, 1, 0);
|
|
ypos += 16;
|
|
bind_list("bindlist", [xpos, ypos], [width, 160], binds_scroll);
|
|
ypos += 160 + 8;
|
|
|
|
cvar_slider([xpos, ypos], [width, 32], [0.1, 10], "sensitivity", "Sensitivity", "%.2f");
|
|
ypos += 32;
|
|
|
|
ypos = 32;
|
|
xpos = 8 + width + 8 + 8;
|
|
|
|
cvar_slider([xpos, ypos], [width, 32], [0, 1], "volume", "Volume", "%.2f");
|
|
ypos += 32 + 4;
|
|
cvar_slider([xpos, ypos], [width, 32], [0, 1], "musicvolume", "Music Volume", "%.2f");
|
|
ypos += 32 + 4 + 8;
|
|
|
|
sui_text([xpos, ypos], MENU_TEXT_SMALL, "Video", MENU_TEXT_1, 1, 0);
|
|
ypos += 16;
|
|
my_button("fs_btn", [xpos, ypos], [width, 20], "Fullscreen") ? localcmd("vid_fullscreen 2; vid_restart\n") : 0;
|
|
ypos += 24;
|
|
my_button("wn_btn", [xpos, ypos], [width, 20], "Windowed") ? localcmd("vid_fullscreen 0; vid_width 1024; vid_height 768; vid_restart\n") : 0;
|
|
ypos += 24;
|
|
sui_text([xpos, ypos], MENU_TEXT_SMALL, "Window can be resized.", MENU_TEXT_1, 0.8, 0);
|
|
ypos += 16;
|
|
sui_set_align([SUI_ALIGN_END, SUI_ALIGN_END]);
|
|
my_button("stg_back", [-8, -8], [80, 20], "Back") ? current_menu = MENU_MAIN : 0;
|
|
|
|
sui_pop_frame();
|
|
};
|
|
|
|
void(float type) Menu_PlaySound =
|
|
{
|
|
string sound = "";
|
|
|
|
if (type == MENU_SND_NAVIGATE) sound = cvar_string("menu_navigatesound");
|
|
else if (type == MENU_SND_ENTER) sound = cvar_string("menu_entersound");
|
|
|
|
localsound(sound, 0, cvar("nzp_uivolume"));
|
|
};
|
|
|
|
float last_menu;
|
|
void(vector size) root_menu =
|
|
{
|
|
sui_set_align([SUI_ALIGN_CENTER, SUI_ALIGN_CENTER]);
|
|
sui_fill([0, 0], size, '0 0 0', 0.5, 0);
|
|
switch (current_menu)
|
|
{
|
|
|
|
#ifdef MENU
|
|
|
|
case MENU_MAIN: Menu_Main(); break;
|
|
case MENU_SOLO: menu_map_mode = MAP_SOLOSTOCK; Menu_Maps(); break;
|
|
case MENU_SOLOUSER: menu_map_mode = MAP_SOLOUSER; Menu_Maps(); break;
|
|
case MENU_COOP: Menu_Coop(); break;
|
|
case MENU_COOPJOIN: Menu_Coop_Join(); break;
|
|
case MENU_COOPBROWSE: Menu_Coop_Browse(); break;
|
|
case MENU_COOPDIRECT: Menu_Coop_Direct(); break;
|
|
case MENU_COOPCREATE: Menu_Coop_Create(); break;
|
|
case MENU_COOPSTOCK: menu_map_mode = MAP_COOPSTOCK; Menu_Maps(); break;
|
|
case MENU_COOPUSER: menu_map_mode = MAP_COOPUSER; Menu_Maps(); break;
|
|
case MENU_CREDITS: Menu_Credits(); break;
|
|
|
|
#else
|
|
|
|
case MENU_PAUSE: Menu_Pause(); break;
|
|
|
|
#endif // MENU
|
|
|
|
case MENU_OPTIONS: Menu_Options(); break;
|
|
case MENU_VIDEO: Menu_Video(); break;
|
|
case MENU_AUDIO: Menu_Audio(); break;
|
|
case MENU_CONTROL: Menu_Control(); break;
|
|
case MENU_GAMEPAD: Menu_Gamepad(); break;
|
|
case MENU_BINDINGS: Menu_Bindings(); break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
// Menu enter sound
|
|
if (last_menu != current_menu) {
|
|
Menu_PlaySound(MENU_SND_ENTER);
|
|
last_menu = current_menu;
|
|
sui_reset_hover();
|
|
}
|
|
};
|