]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - menu.c
fixed an R_InitSky warning regarding transpix being uninitialized, added transpixunio...
[xonotic/darkplaces.git] / menu.c
diff --git a/menu.c b/menu.c
index d7fe96afd517366e8688bfb3f57a7558b3f66270..a785f554b43a73f52b0e41424dc012b43be83b95 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -168,9 +168,9 @@ void M_Print (float cx, float cy, const char *str)
        DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0);
 }
 
-void M_PrintWhite (float cx, float cy, const char *str)
+void M_PrintRed (float cx, float cy, const char *str)
 {
-       DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 1, 1, 1, 0);
+       DrawQ_String(menu_x + cx, menu_y + cy, str, 0, 8, 8, 1, 0, 0, 1, 0);
 }
 
 void M_ItemPrint (float cx, float cy, char *str, int unghosted)
@@ -327,14 +327,14 @@ void M_Demo_Key (int k)
                S_LocalSound ("misc/menu1.wav");
                demo_cursor--;
                if (demo_cursor < 0)
-                       demo_cursor = NumberOfNehahraDemos;
+                       demo_cursor = NumberOfNehahraDemos-1;
                break;
 
        case K_DOWNARROW:
        case K_RIGHTARROW:
                S_LocalSound ("misc/menu1.wav");
                demo_cursor++;
-               if (demo_cursor > NumberOfNehahraDemos)
+               if (demo_cursor >= NumberOfNehahraDemos)
                        demo_cursor = 0;
                break;
        }
@@ -576,14 +576,14 @@ void M_SinglePlayer_Draw (void)
 
                M_DrawTextBox (60, 8 * 8, 23, 4);
                if (gamemode == GAME_NEXUIZ)
-                       M_PrintWhite (95, 10 * 8, "Nexuiz is for");
+                       M_Print (95, 10 * 8, "Nexuiz is for");
                else if (gamemode == GAME_GOODVSBAD2)
-                       M_PrintWhite (95, 10 * 8, "Good Vs Bad 2 is for");
+                       M_Print (95, 10 * 8, "Good Vs Bad 2 is for");
                else if (gamemode == GAME_BATTLEMECH)
-                       M_PrintWhite (95, 10 * 8, "Battlemech is for");
+                       M_Print (95, 10 * 8, "Battlemech is for");
                else
-                       M_PrintWhite (95, 10 * 8, "Transfusion is for");
-               M_PrintWhite (83, 11 * 8, "multiplayer play only");
+                       M_Print (95, 10 * 8, "Transfusion is for");
+               M_Print (83, 11 * 8, "multiplayer play only");
        }
        else
        {
@@ -1095,7 +1095,7 @@ void M_DrawSlider (int x, int y, float num, float rangemin, float rangemax)
                M_DrawCharacter (x + i*8, y, 129);
        M_DrawCharacter (x+i*8, y, 130);
        M_DrawCharacter (x + (SLIDER_RANGE-1)*8 * range, y, 131);
-       sprintf(text, "%g", num);
+       sprintf(text, "%f", num);
        M_Print(x + (SLIDER_RANGE+2) * 8, y, text);
 }
 
@@ -1108,7 +1108,7 @@ void M_DrawCheckbox (int x, int y, int on)
 }
 
 
-#define OPTIONS_ITEMS 31
+#define OPTIONS_ITEMS 32
 
 int options_cursor;
 
@@ -1340,12 +1340,12 @@ extern cvar_t r_dlightmap;
 extern cvar_t r_modellights;
 extern cvar_t r_coronas;
 extern cvar_t gl_flashblend;
+extern cvar_t cl_particles_quality;
 extern cvar_t cl_particles_bulletimpacts;
 extern cvar_t cl_particles_smoke;
 extern cvar_t cl_particles_sparks;
 extern cvar_t cl_particles_bubbles;
 extern cvar_t cl_particles_blood;
-extern cvar_t cl_particles_blood_size;
 extern cvar_t cl_particles_blood_alpha;
 
 void M_Menu_Options_Effects_AdjustSliders (int dir)
@@ -1364,6 +1364,8 @@ void M_Menu_Options_Effects_AdjustSliders (int dir)
                Cvar_SetValueQuick (&gl_flashblend, !gl_flashblend.integer);
        else if (options_effects_cursor == optnum++)
                Cvar_SetValueQuick (&cl_particles, !cl_particles.integer);
+       else if (options_effects_cursor == optnum++)
+               Cvar_SetValueQuick (&cl_particles_quality, bound(1, cl_particles_quality.value + dir * 0.5, 4));
        else if (options_effects_cursor == optnum++)
                Cvar_SetValueQuick (&cl_explosions, !cl_explosions.integer);
        else if (options_effects_cursor == optnum++)
@@ -1384,8 +1386,6 @@ void M_Menu_Options_Effects_AdjustSliders (int dir)
                Cvar_SetValueQuick (&cl_particles_bubbles, !cl_particles_bubbles.integer);
        else if (options_effects_cursor == optnum++)
                Cvar_SetValueQuick (&cl_particles_blood, !cl_particles_blood.integer);
-       else if (options_effects_cursor == optnum++)
-               Cvar_SetValueQuick (&cl_particles_blood_size, bound(2, cl_particles_blood_size.value + dir * 1, 20));
        else if (options_effects_cursor == optnum++)
                Cvar_SetValueQuick (&cl_particles_blood_alpha, bound(0.2, cl_particles_blood_alpha.value + dir * 0.1, 1));
        else if (options_effects_cursor == optnum++)
@@ -1413,6 +1413,7 @@ void M_Options_Effects_Draw (void)
        M_Print(16, y, "               Coronas");M_DrawCheckbox(220, y, r_coronas.integer);y += 8;
        M_Print(16, y, "      Use Only Coronas");M_DrawCheckbox(220, y, gl_flashblend.integer);y += 8;
        M_Print(16, y, "             Particles");M_DrawCheckbox(220, y, cl_particles.integer);y += 8;
+       M_Print(16, y, "     Particles Quality");M_DrawSlider(220, y, cl_particles_quality.value, 1, 4);y += 8;
        M_Print(16, y, "            Explosions");M_DrawCheckbox(220, y, cl_explosions.integer);y += 8;
        M_Print(16, y, "    Explosion Clipping");M_DrawCheckbox(220, y, r_explosionclip.integer);y += 8;
        M_Print(16, y, "             Stainmaps");M_DrawCheckbox(220, y, cl_stainmaps.integer);y += 8;
@@ -1423,7 +1424,6 @@ void M_Options_Effects_Draw (void)
        M_Print(16, y, "                Sparks");M_DrawCheckbox(220, y, cl_particles_sparks.integer);y += 8;
        M_Print(16, y, "               Bubbles");M_DrawCheckbox(220, y, cl_particles_bubbles.integer);y += 8;
        M_Print(16, y, "                 Blood");M_DrawCheckbox(220, y, cl_particles_blood.integer);y += 8;
-       M_Print(16, y, "            Blood Size");M_DrawSlider(220, y, cl_particles_blood_size.value, 2, 20);y += 8;
        M_Print(16, y, "         Blood Opacity");M_DrawSlider(220, y, cl_particles_blood_alpha.value, 0.2, 1);y += 8;
        M_Print(16, y, "   Model Interpolation");M_DrawCheckbox(220, y, r_lerpmodels.integer);y += 8;
        M_Print(16, y, "  Sprite Interpolation");M_DrawCheckbox(220, y, r_lerpsprites.integer);y += 8;
@@ -1748,6 +1748,7 @@ char *quakebindnames[][2] =
 
 char *transfusionbindnames[][2] =
 {
+{"",                           "Movement"},            // Movement commands
 {"+forward",           "walk forward"},
 {"+back",                      "backpedal"},
 {"+left",                      "turn left"},
@@ -1756,30 +1757,40 @@ char *transfusionbindnames[][2] =
 {"+moveright",                 "step right"},
 {"+jump",                      "jump / swim up"},
 {"+movedown",          "swim down"},
-{"+attack",            "attack"},
-{"+button3",           "altfire"},
+{"",                           "Combat"},                      // Combat commands
 {"impulse 1",          "Pitch Fork"},
 {"impulse 2",          "Flare Gun"},
 {"impulse 3",          "Shotgun"},
 {"impulse 4",          "Machine Gun"},
 {"impulse 5",          "Incinerator"},
-{"impulse 6",          "Bombs"},
+{"impulse 6",          "Bombs (TNT)"},
+{"impulse 35",         "Proximity Bomb"},
+{"impulse 36",         "Remote Detonator"},
 {"impulse 7",          "Aerosol Can"},
 {"impulse 8",          "Tesla Cannon"},
 {"impulse 9",          "Life Leech"},
-{"impulse 17",         "Voodoo Doll"},
-{"impulse 11",         "previous weapon"},
-{"impulse 10",         "next weapon"},
-{"impulse 14",         "previous item"},
-{"impulse 15",         "next item"},
-{"impulse 13",         "use item"},
-{"impulse 100",                "add bot (red)"},
-{"impulse 101",                "add bot (blue)"},
-{"impulse 102",                "kick a bot"},
-{"impulse 50",         "voting menu"},
-{"impulse 141",                "identify player"},
-{"impulse 16",         "next armor type"},
-{"impulse 20",         "observer mode"}
+{"impulse 10",         "Voodoo Doll"},
+{"impulse 21",         "next weapon"},
+{"impulse 22",         "previous weapon"},
+{"+attack",            "attack"},
+{"+button3",           "altfire"},
+{"",                           "Inventory"},           // Inventory commands
+{"impulse 40",         "Dr.'s Bag"},
+{"impulse 41",         "Crystal Ball"},
+{"impulse 42",         "Beast Vision"},
+{"impulse 43",         "Jump Boots"},
+{"impulse 23",         "next item"},
+{"impulse 24",         "previous item"},
+{"impulse 25",         "use item"},
+{"",                           "Misc"},                        // Misc commands
+{"+button4",           "use"},
+{"impulse 50",         "add bot (red)"},
+{"impulse 51",         "add bot (blue)"},
+{"impulse 52",         "kick a bot"},
+{"impulse 26",         "next armor type"},
+{"impulse 27",         "identify player"},
+{"impulse 55",         "voting menu"},
+{"impulse 56",         "observer mode"}
 };
 
 char *goodvsbad2bindnames[][2] =
@@ -1960,7 +1971,7 @@ void M_Keys_Draw (void)
        cachepic_t      *p;
        char    keystring[1024];
 
-       M_Background(320, 200);
+       M_Background(320, 48 + 8 * numcommands);
 
        p = Draw_CachePic ("gfx/ttl_cstm.lmp");
        M_DrawPic ( (320-p->width)/2, 4, "gfx/ttl_cstm.lmp");
@@ -1975,7 +1986,15 @@ void M_Keys_Draw (void)
        {
                y = 48 + 8*i;
 
-               M_Print (16, y, bindnames[i][1]);
+               // If there's no command, it's just a section
+               if (bindnames[i][0][0] == '\0')
+               {
+                       M_PrintRed (4, y, "\x0D");  // #13 is the little arrow pointing to the right
+                       M_PrintRed (16, y, bindnames[i][1]);
+                       continue;
+               }
+               else
+                       M_Print (16, y, bindnames[i][1]);
 
                M_FindKeysForCommand (bindnames[i][0], keys);
 
@@ -2036,17 +2055,25 @@ void M_Keys_Key (int k)
        case K_LEFTARROW:
        case K_UPARROW:
                S_LocalSound ("misc/menu1.wav");
-               keys_cursor--;
-               if (keys_cursor < 0)
-                       keys_cursor = numcommands-1;
+               do
+               {
+                       keys_cursor--;
+                       if (keys_cursor < 0)
+                               keys_cursor = numcommands-1;
+               }
+               while (bindnames[keys_cursor][0][0] == '\0');  // skip sections
                break;
 
        case K_DOWNARROW:
        case K_RIGHTARROW:
                S_LocalSound ("misc/menu1.wav");
-               keys_cursor++;
-               if (keys_cursor >= numcommands)
-                       keys_cursor = 0;
+               do
+               {
+                       keys_cursor++;
+                       if (keys_cursor >= numcommands)
+                               keys_cursor = 0;
+               }
+               while (bindnames[keys_cursor][0][0] == '\0');  // skip sections
                break;
 
        case K_ENTER:           // go into bind mode
@@ -2337,11 +2364,13 @@ int M_ChooseQuitMessage(int request)
                if (request-- == 0) return M_QuitMessage("Please stop playing","this stupid game",NULL,NULL,NULL,NULL,NULL,NULL);
                break;
        case GAME_BATTLEMECH:
-               if (request-- == 0) return M_QuitMessage("WHY","?",NULL,NULL,NULL,NULL,NULL,NULL);
-               if (request-- == 0) return M_QuitMessage("Leave now and your mech","is scrap!",NULL,NULL,NULL,NULL,NULL,NULL);
-               if (request-- == 0) return M_QuitMessage("Accept Defeat?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-               if (request-- == 0) return M_QuitMessage("Wait!","There are more mechs to","destroy!",NULL,NULL,NULL,NULL,NULL);
-               if (request-- == 0) return M_QuitMessage("Where's your bloodlust?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("? WHY ?","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("Leave now and your mech is scrap!","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("Accept Defeat?","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("Wait! There are more mechs to destroy!","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("Where's your bloodlust?","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("Your mech here is way more impressive","than your car out there...","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL);
+               if (request-- == 0) return M_QuitMessage("Quitting won't reduce your debt","Press Y to quit, N to keep fraggin'",NULL,NULL,NULL,NULL,NULL,NULL);
                break;
        default:
                if (request-- == 0) return M_QuitMessage("Tired of fragging already?",NULL,NULL,NULL,NULL,NULL,NULL,NULL);
@@ -2499,7 +2528,7 @@ void M_LanConfig_Draw (void)
                M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [2], 10+((int)(realtime*4)&1));
 
        if (*m_return_reason)
-               M_PrintWhite (basex, 168, m_return_reason);
+               M_Print (basex, 168, m_return_reason);
 }
 
 
@@ -2941,9 +2970,9 @@ void M_Menu_GameOptions_f (void)
        m_state = m_gameoptions;
        m_entersound = true;
        if (maxplayers == 0)
-               maxplayers = sv_maxplayers.integer;
+               maxplayers = svs.maxclients;
        if (maxplayers < 2)
-               maxplayers = MAX_SCOREBOARD;
+               maxplayers = min(8, MAX_SCOREBOARD);
 }
 
 
@@ -2981,6 +3010,15 @@ void M_GameOptions_Draw (void)
                        else
                                M_Print (160, 64, "Blood Bath");
                }
+               else if (gamemode == GAME_BATTLEMECH)
+               {
+                       if (!deathmatch.integer)
+                               Cvar_SetValue("deathmatch", 1);
+                       if (deathmatch.integer == 2)
+                               M_Print (160, 64, "Rambo Match");
+                       else
+                               M_Print (160, 64, "Deathmatch");
+               }
                else
                {
                        if (!coop.integer && !deathmatch.integer)
@@ -3116,6 +3154,13 @@ void M_NetStart_Change (int dir)
                        else // changing from BloodBath to CTF
                                Cvar_SetValueQuick (&deathmatch, 2);
                }
+               else if (gamemode == GAME_BATTLEMECH)
+               {
+                       if (deathmatch.integer == 2) // changing from Rambo to Deathmatch
+                               Cvar_SetValueQuick (&deathmatch, 0);
+                       else // changing from Deathmatch to Rambo
+                               Cvar_SetValueQuick (&deathmatch, 2);
+               }
                else
                {
                        if (deathmatch.integer) // changing from deathmatch to coop
@@ -3337,7 +3382,7 @@ void M_ServerList_Draw (void)
        M_DrawCharacter(0, 32 + (slist_cursor - start) * 16, 12+((int)(realtime*4)&1));
 
        if (*m_return_reason)
-               M_PrintWhite(16, vid.conheight - 8, m_return_reason);
+               M_Print(16, vid.conheight - 8, m_return_reason);
 }
 
 
@@ -3423,6 +3468,18 @@ void M_Init (void)
                bindnames = quakebindnames;
        }
 
+       // Make sure "keys_cursor" doesn't start on a section in the binding list
+       keys_cursor = 0;
+       while (bindnames[keys_cursor][0][0] == '\0')
+       {
+               keys_cursor++;
+
+               // Only sections? There may be a problem somewhere...
+               if (keys_cursor >= numcommands)
+                       Sys_Error ("M_Init: The key binding list only contains sections");
+       }
+
+
        if (gamemode == GAME_NEHAHRA)
        {
                if (FS_FileExists("maps/neh1m4.bsp"))