mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 12:31:54 +00:00
Allow hosting and joining by IP
This commit is contained in:
parent
cbf108a627
commit
fdf778c72f
4 changed files with 407 additions and 49 deletions
27
src/k_menu.h
27
src/k_menu.h
|
|
@ -183,6 +183,12 @@ extern menu_t PLAY_TimeAttackDef;
|
||||||
extern menuitem_t PLAY_MP_OptSelect[];
|
extern menuitem_t PLAY_MP_OptSelect[];
|
||||||
extern menu_t PLAY_MP_OptSelectDef;
|
extern menu_t PLAY_MP_OptSelectDef;
|
||||||
|
|
||||||
|
extern menuitem_t PLAY_MP_Host[];
|
||||||
|
extern menu_t PLAY_MP_HostDef;
|
||||||
|
|
||||||
|
extern menuitem_t PLAY_MP_JoinIP[];
|
||||||
|
extern menu_t PLAY_MP_JoinIPDef;
|
||||||
|
|
||||||
extern menuitem_t PLAY_MP_RoomSelect[];
|
extern menuitem_t PLAY_MP_RoomSelect[];
|
||||||
extern menu_t PLAY_MP_RoomSelectDef;
|
extern menu_t PLAY_MP_RoomSelectDef;
|
||||||
|
|
||||||
|
|
@ -331,7 +337,8 @@ extern struct cupgrid_s {
|
||||||
SINT8 pageno;
|
SINT8 pageno;
|
||||||
UINT8 numpages;
|
UINT8 numpages;
|
||||||
tic_t previewanim;
|
tic_t previewanim;
|
||||||
boolean grandprix; // Setup grand prix server after picking
|
boolean grandprix; // Setup grand prix server after picking
|
||||||
|
boolean netgame; // Start the game in an actual server
|
||||||
} cupgrid;
|
} cupgrid;
|
||||||
|
|
||||||
extern struct levellist_s {
|
extern struct levellist_s {
|
||||||
|
|
@ -342,6 +349,7 @@ extern struct levellist_s {
|
||||||
INT16 choosemap;
|
INT16 choosemap;
|
||||||
UINT8 newgametype;
|
UINT8 newgametype;
|
||||||
boolean timeattack; // Setup time attack menu after picking
|
boolean timeattack; // Setup time attack menu after picking
|
||||||
|
boolean netgame; // Start the game in an actual server
|
||||||
} levellist;
|
} levellist;
|
||||||
|
|
||||||
boolean M_CanShowLevelInList(INT16 mapnum, UINT8 gt);
|
boolean M_CanShowLevelInList(INT16 mapnum, UINT8 gt);
|
||||||
|
|
@ -361,6 +369,9 @@ void M_LevelSelectTick(void);
|
||||||
|
|
||||||
extern struct mpmenu_s {
|
extern struct mpmenu_s {
|
||||||
UINT8 modechoice;
|
UINT8 modechoice;
|
||||||
|
INT16 modewinextend[3][3]; // Used to "extend" the options in the mode select screen.
|
||||||
|
// format for each option: {extended?, max extension, # lines extended}
|
||||||
|
// See M_OptSelectTick, it'll make more sense there. Sorry if this is a bit of a mess!
|
||||||
|
|
||||||
UINT8 room;
|
UINT8 room;
|
||||||
|
|
||||||
|
|
@ -371,6 +382,18 @@ extern struct mpmenu_s {
|
||||||
void M_MPOptSelect(INT32 choice);
|
void M_MPOptSelect(INT32 choice);
|
||||||
void M_MPOptSelectInit(INT32 choice);
|
void M_MPOptSelectInit(INT32 choice);
|
||||||
void M_MPOptSelectTick(void);
|
void M_MPOptSelectTick(void);
|
||||||
|
boolean M_MPResetOpts(void);
|
||||||
|
consvar_t cv_dummygametype; // lazy hack to allow us to select the GT on the server host submenu
|
||||||
|
consvar_t cv_dummyip; // I HAVE
|
||||||
|
// HAVE YOUR IP ADDRESS (This just the hack Cvar we'll type into and then it apends itself to "connect" in the console for IP join)
|
||||||
|
|
||||||
|
// MP Host
|
||||||
|
void M_MPHostInit(INT32 choice);
|
||||||
|
void M_MPSetupNetgameMapSelect(INT32 choice);
|
||||||
|
|
||||||
|
// MP join by IP
|
||||||
|
void M_MPJoinIPInit(INT32 choice);
|
||||||
|
void M_JoinIP(void);
|
||||||
|
|
||||||
// Server browser room selection
|
// Server browser room selection
|
||||||
void M_MPRoomSelect(INT32 choice);
|
void M_MPRoomSelect(INT32 choice);
|
||||||
|
|
@ -414,6 +437,8 @@ void M_DrawTimeAttack(void);
|
||||||
|
|
||||||
// Multiplayer menu stuff
|
// Multiplayer menu stuff
|
||||||
void M_DrawMPOptSelect(void);
|
void M_DrawMPOptSelect(void);
|
||||||
|
void M_DrawMPHost(void);
|
||||||
|
void M_DrawMPJoinIP(void);
|
||||||
void M_DrawMPRoomSelect(void);
|
void M_DrawMPRoomSelect(void);
|
||||||
|
|
||||||
// Replay Playback
|
// Replay Playback
|
||||||
|
|
|
||||||
|
|
@ -176,10 +176,10 @@ menuitem_t PLAY_MP_OptSelect[] =
|
||||||
{
|
{
|
||||||
//{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, M_MPOptSelect, 0, 0},
|
//{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, M_MPOptSelect, 0, 0},
|
||||||
{IT_STRING | IT_CALL, "Host Game", "Start your own online game!",
|
{IT_STRING | IT_CALL, "Host Game", "Start your own online game!",
|
||||||
NULL, NULL, 0, 0},
|
NULL, M_MPHostInit, 0, 0},
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, "Join by IP", "Join an online game by its IP address.",
|
{IT_STRING | IT_CALL, "Join by IP", "Join an online game by its IP address.",
|
||||||
NULL, NULL, 0, 0},
|
NULL, M_MPJoinIPInit, 0, 0},
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, "Server Browser", "Search for game servers to play in.",
|
{IT_STRING | IT_CALL, "Server Browser", "Search for game servers to play in.",
|
||||||
NULL, M_MPRoomSelectInit, 0, 0},
|
NULL, M_MPRoomSelectInit, 0, 0},
|
||||||
|
|
@ -191,12 +191,69 @@ menu_t PLAY_MP_OptSelectDef = {
|
||||||
0,
|
0,
|
||||||
PLAY_MP_OptSelect,
|
PLAY_MP_OptSelect,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
-1, 1,
|
||||||
M_DrawMPOptSelect,
|
M_DrawMPOptSelect,
|
||||||
M_MPOptSelectTick,
|
M_MPOptSelectTick,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// MULTIPLAYER HOST SCREEN
|
||||||
|
menuitem_t PLAY_MP_Host[] =
|
||||||
|
{
|
||||||
|
//{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, M_MPOptSelect, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR | IT_CV_STRING, "Server Name", "Display name for your game online. Other players will see this.",
|
||||||
|
NULL, &cv_servername, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR, "Public Server", "Display or not your game in the Server Browser for other players.",
|
||||||
|
NULL, &cv_advertise, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR, "Max. Players", "Set how many players can play at once. Others will spectate.",
|
||||||
|
NULL, &cv_ingamecap, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR, "Gamemode", "Are we racing? Or perhaps battling?",
|
||||||
|
NULL, &cv_dummygametype, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CALL, "GO", "Select a map with the currently selected gamemode",
|
||||||
|
NULL, M_MPSetupNetgameMapSelect, 0, 0},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
menu_t PLAY_MP_HostDef = {
|
||||||
|
sizeof (PLAY_MP_Host) / sizeof (menuitem_t),
|
||||||
|
&PLAY_MP_OptSelectDef,
|
||||||
|
0,
|
||||||
|
PLAY_MP_Host,
|
||||||
|
0, 0,
|
||||||
|
-1, 1, // 1 frame transition.... This is really just because I don't want the black fade when we press esc, hehe
|
||||||
|
M_DrawMPHost,
|
||||||
|
M_MPOptSelectTick, // This handles the unfolding options
|
||||||
|
M_MPResetOpts
|
||||||
|
};
|
||||||
|
|
||||||
|
// MULTIPLAYER JOIN BY IP
|
||||||
|
menuitem_t PLAY_MP_JoinIP[] =
|
||||||
|
{
|
||||||
|
//{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, M_MPOptSelect, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CVAR | IT_CV_STRING, "Address: ", "Type the IPv4 address of the server you wish to connect to.",
|
||||||
|
NULL, &cv_dummyip, 0, 0},
|
||||||
|
|
||||||
|
{IT_STRING | IT_CALL, "GO", "Select a map with the currently selected gamemode",
|
||||||
|
NULL, M_JoinIP, 0, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
menu_t PLAY_MP_JoinIPDef = {
|
||||||
|
sizeof (PLAY_MP_JoinIP) / sizeof (menuitem_t),
|
||||||
|
&PLAY_MP_OptSelectDef,
|
||||||
|
0,
|
||||||
|
PLAY_MP_JoinIP,
|
||||||
|
0, 0,
|
||||||
|
-1, 1, // 1 frame transition.... This is really just because I don't want the black fade when we press esc, hehe
|
||||||
|
M_DrawMPJoinIP,
|
||||||
|
M_MPOptSelectTick, // This handles the unfolding options
|
||||||
|
M_MPResetOpts
|
||||||
|
};
|
||||||
|
|
||||||
// MULTIPLAYER ROOM SELECT (CORE / MODDED)
|
// MULTIPLAYER ROOM SELECT (CORE / MODDED)
|
||||||
menuitem_t PLAY_MP_RoomSelect[] =
|
menuitem_t PLAY_MP_RoomSelect[] =
|
||||||
|
|
|
||||||
191
src/k_menudraw.c
191
src/k_menudraw.c
|
|
@ -1306,23 +1306,19 @@ void M_DrawTimeAttack(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This draws the options of a given menu in a fashion specific to the multiplayer option select screen (host game / server browser etc)
|
// This draws the options of a given menu in a fashion specific to the multiplayer option select screen (host game / server browser etc)
|
||||||
// TODO: Add 2nd argument that lets us "expand" a given option via an array
|
// First argument is the menu to draw the options from, the 2nd one is a table that contains which option is to be "extendded"
|
||||||
|
// Format for each option: {extended? (only used by the ticker), max extension (likewise), # of lines to extend}
|
||||||
|
|
||||||
static void M_MPOptDrawer(menu_t *m)
|
// NOTE: This is pretty rigid and only intended for use with the multiplayer options menu which has *3* choices.
|
||||||
|
|
||||||
|
static void M_MPOptDrawer(menu_t *m, INT16 extend[3][3])
|
||||||
{
|
{
|
||||||
// This is a copypaste of the generic gamemode menu code with a few changes.
|
// This is a copypaste of the generic gamemode menu code with a few changes.
|
||||||
// TODO: Allow specific options to "expand" into smaller ones.
|
// TODO: Allow specific options to "expand" into smaller ones.
|
||||||
|
|
||||||
patch_t *buttback = W_CachePatchName("M_PLAT2", PU_CACHE);
|
patch_t *buttback = W_CachePatchName("M_PLAT2", PU_CACHE);
|
||||||
|
|
||||||
UINT8 n = m->numitems-1;
|
|
||||||
INT32 i, x = 142, y = 32; // Dirty magic numbers for now but they work out.
|
INT32 i, x = 142, y = 32; // Dirty magic numbers for now but they work out.
|
||||||
|
|
||||||
if (menutransition.tics)
|
|
||||||
{
|
|
||||||
x += 24 * menutransition.tics;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < m->numitems; i++)
|
for (i = 0; i < m->numitems; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -1331,8 +1327,9 @@ static void M_MPOptDrawer(menu_t *m)
|
||||||
case IT_STRING:
|
case IT_STRING:
|
||||||
{
|
{
|
||||||
UINT8 *colormap = NULL;
|
UINT8 *colormap = NULL;
|
||||||
|
INT16 j = 0;
|
||||||
|
|
||||||
if (i == itemOn)
|
if ((currentMenu == m && i == itemOn) || extend[i][0]) // Selected / unfolded
|
||||||
{
|
{
|
||||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
|
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
|
||||||
}
|
}
|
||||||
|
|
@ -1341,28 +1338,184 @@ static void M_MPOptDrawer(menu_t *m)
|
||||||
colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_MOSS, GTC_CACHE);
|
colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_MOSS, GTC_CACHE);
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, buttback, colormap);
|
if (extend[i][2])
|
||||||
|
{
|
||||||
|
for (j=0; j < extend[i][2]/2; j++)
|
||||||
|
{
|
||||||
|
// Draw rectangles that look like the current selected item starting from the top of the actual selection graphic and going up to where it's supposed to go.
|
||||||
|
// With colour 169 (that's the index of the shade of black the plague colourization gives us. ...No I don't like using a magic number either.
|
||||||
|
V_DrawFill(x + (extend[i][2]/2) - j - (buttback->width/2), (y + extend[i][2]) - (2*j), 225, 2, 169);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
V_DrawFixedPatch((x + (extend[i][2]/2)) *FRACUNIT, (y + extend[i][2])*FRACUNIT, FRACUNIT, 0, buttback, colormap);
|
||||||
V_DrawCenteredGamemodeString(x, y - 3, V_ALLOWLOWERCASE, colormap, m->menuitems[i].text);
|
V_DrawCenteredGamemodeString(x, y - 3, V_ALLOWLOWERCASE, colormap, m->menuitems[i].text);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
x += GM_XOFFSET;
|
x += GM_XOFFSET;
|
||||||
y += GM_YOFFSET;
|
y += GM_YOFFSET + extend[i][2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draws the EGGA CHANNEL background.
|
||||||
|
static void M_DrawEggaChannel(void)
|
||||||
|
{
|
||||||
|
patch_t *background = W_CachePatchName("M_EGGACH", PU_CACHE);
|
||||||
|
|
||||||
|
V_DrawFill(0, 0, 999, 999, 25);
|
||||||
|
V_DrawFixedPatch(160<<FRACBITS, 104<<FRACBITS, FRACUNIT, 0, background, NULL);
|
||||||
|
V_DrawVhsEffect(false); // VHS the background! (...sorry OGL my love)
|
||||||
|
}
|
||||||
|
|
||||||
// Multiplayer mode option select
|
// Multiplayer mode option select
|
||||||
void M_DrawMPOptSelect(void)
|
void M_DrawMPOptSelect(void)
|
||||||
{
|
{
|
||||||
|
M_DrawEggaChannel();
|
||||||
patch_t *background = W_CachePatchName("M_EGGACH", PU_CACHE);
|
|
||||||
|
|
||||||
V_DrawFill(0, 0, 999, 999, 25);
|
|
||||||
V_DrawFixedPatch(160<<FRACBITS, 104<<FRACBITS, FRACUNIT, 0, background, NULL);
|
|
||||||
|
|
||||||
M_DrawMenuTooltips();
|
M_DrawMenuTooltips();
|
||||||
M_MPOptDrawer(currentMenu);
|
M_MPOptDrawer(&PLAY_MP_OptSelectDef, mpmenu.modewinextend);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplayer mode option select: HOST GAME!
|
||||||
|
// A rehash of the generic menu drawer adapted to fit into that cramped space. ...A small sacrifice for utility
|
||||||
|
void M_DrawMPHost(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
patch_t *gobutt = W_CachePatchName("M_BUTTGO", PU_CACHE); // I'm very mature
|
||||||
|
INT32 xp = 50, yp = 64, i = 0, w = 0; // Starting position for the text drawing.
|
||||||
|
M_DrawMPOptSelect(); // Draw the Multiplayer option select menu first
|
||||||
|
|
||||||
|
// Now draw our host options...
|
||||||
|
for (i = 0; i < currentMenu->numitems; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (i == currentMenu->numitems-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_MOSS, GTC_CACHE);
|
||||||
|
if (i == itemOn)
|
||||||
|
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
|
||||||
|
|
||||||
|
// Ideally we'd calculate this but it's not worth it for a 1-off menu probably.....
|
||||||
|
V_DrawFixedPatch(212<<FRACBITS, 100<<FRACBITS, FRACUNIT, 0, gobutt, colormap);
|
||||||
|
V_DrawCenteredGamemodeString(212 + (gobutt->width/2), 100 -3, V_ALLOWLOWERCASE, colormap, currentMenu->menuitems[i].text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (currentMenu->menuitems[i].status & IT_DISPLAY)
|
||||||
|
{
|
||||||
|
case IT_STRING:
|
||||||
|
{
|
||||||
|
V_DrawString(xp, yp, V_ALLOWLOWERCASE | (i == itemOn ? highlightflags : 0), 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_STRING:
|
||||||
|
V_DrawThinString(xp + 96, yp, V_ALLOWLOWERCASE, cv->string);
|
||||||
|
if (skullAnimCounter < 4 && i == itemOn)
|
||||||
|
V_DrawCharacter(xp + 93 + V_ThinStringWidth(cv->string, 0), yp +1, '_' | 0x80, false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
w = V_StringWidth(cv->string, 0);
|
||||||
|
V_DrawString(xp + 138 - w, yp, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? warningflags : highlightflags), cv->string);
|
||||||
|
if (i == itemOn)
|
||||||
|
{
|
||||||
|
V_DrawCharacter(xp + 138 - 10 - w - (skullAnimCounter/5), yp, '\x1C' | highlightflags, false); // left arrow
|
||||||
|
V_DrawCharacter(xp + 138 + 2 + (skullAnimCounter/5), yp, '\x1D' | highlightflags, false); // right arrow
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xp += 5;
|
||||||
|
yp += 11;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplayer mode option select: JOIN BY IP
|
||||||
|
// Once again we'll copypaste 1 bit of the generic menu handler we used for hosting but we only need it for IT_CV_STRING since that's all we got :)
|
||||||
|
// (I don't like duplicating code but I rather this than some horrible all-in-one function with too many options...)
|
||||||
|
void M_DrawMPJoinIP(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
patch_t *gobutt = W_CachePatchName("M_BUTTGO", PU_CACHE); // I'm very mature
|
||||||
|
INT32 xp = 70, yp = 100, i = 0; // Starting position for the text drawing.
|
||||||
|
M_DrawMPOptSelect(); // Draw the Multiplayer option select menu first
|
||||||
|
|
||||||
|
// Now draw our host options...
|
||||||
|
for (i = 0; i < currentMenu->numitems; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (i == currentMenu->numitems-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_MOSS, GTC_CACHE);
|
||||||
|
if (i == itemOn)
|
||||||
|
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
|
||||||
|
|
||||||
|
// Ideally we'd calculate this but it's not worth it for a 1-off menu probably.....
|
||||||
|
V_DrawFixedPatch(219<<FRACBITS, 114<<FRACBITS, FRACUNIT, 0, gobutt, colormap);
|
||||||
|
V_DrawCenteredGamemodeString(219 + (gobutt->width/2), 114 -3, V_ALLOWLOWERCASE, colormap, currentMenu->menuitems[i].text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (currentMenu->menuitems[i].status & IT_DISPLAY)
|
||||||
|
{
|
||||||
|
case IT_STRING:
|
||||||
|
{
|
||||||
|
V_DrawString(xp, yp, V_ALLOWLOWERCASE | (i == itemOn ? highlightflags : 0), 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_STRING:
|
||||||
|
V_DrawThinString(xp + 65, yp-1, V_ALLOWLOWERCASE, cv->string);
|
||||||
|
if (skullAnimCounter < 4 && i == itemOn)
|
||||||
|
V_DrawCharacter(xp + 65 + V_ThinStringWidth(cv->string, 0), yp, '_' | 0x80, false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xp += 5;
|
||||||
|
yp += 11;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiplayer room select
|
// Multiplayer room select
|
||||||
|
|
|
||||||
175
src/k_menufunc.c
175
src/k_menufunc.c
|
|
@ -164,12 +164,15 @@ static CV_PossibleValue_t dummyteam_cons_t[] = {{0, "Spectator"}, {1, "Red"}, {2
|
||||||
static CV_PossibleValue_t dummyspectate_cons_t[] = {{0, "Spectator"}, {1, "Playing"}, {0, NULL}};
|
static CV_PossibleValue_t dummyspectate_cons_t[] = {{0, "Spectator"}, {1, "Playing"}, {0, NULL}};
|
||||||
static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}, {0, NULL}};
|
static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}, {0, NULL}};
|
||||||
static CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {100, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {100, "MAX"}, {0, NULL}};
|
||||||
|
static CV_PossibleValue_t dummygametype_cons_t[] = {{0, "Race"}, {1, "Battle"}, {0, NULL}};
|
||||||
|
|
||||||
static consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange);
|
static consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange);
|
||||||
static consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDDEN, dummyteam_cons_t, NULL);
|
static consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDDEN, dummyteam_cons_t, NULL);
|
||||||
static consvar_t cv_dummyspectate = CVAR_INIT ("dummyspectate", "Spectator", CV_HIDDEN, dummyspectate_cons_t, NULL);
|
static consvar_t cv_dummyspectate = CVAR_INIT ("dummyspectate", "Spectator", CV_HIDDEN, dummyspectate_cons_t, NULL);
|
||||||
static consvar_t cv_dummyscramble = CVAR_INIT ("dummyscramble", "Random", CV_HIDDEN, dummyscramble_cons_t, NULL);
|
static consvar_t cv_dummyscramble = CVAR_INIT ("dummyscramble", "Random", CV_HIDDEN, dummyscramble_cons_t, NULL);
|
||||||
static consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange);
|
static consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange);
|
||||||
|
consvar_t cv_dummygametype = CVAR_INIT ("dummygametype", "Race", CV_HIDDEN, dummygametype_cons_t, NULL);
|
||||||
|
consvar_t cv_dummyip = CVAR_INIT ("dummyip", "", CV_HIDDEN, NULL, NULL);
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// CVAR ONCHANGE EVENTS GO HERE
|
// CVAR ONCHANGE EVENTS GO HERE
|
||||||
|
|
@ -1559,6 +1562,8 @@ void M_Init(void)
|
||||||
CV_RegisterVar(&cv_dummyspectate);
|
CV_RegisterVar(&cv_dummyspectate);
|
||||||
CV_RegisterVar(&cv_dummyscramble);
|
CV_RegisterVar(&cv_dummyscramble);
|
||||||
CV_RegisterVar(&cv_dummystaff);
|
CV_RegisterVar(&cv_dummystaff);
|
||||||
|
CV_RegisterVar(&cv_dummygametype);
|
||||||
|
CV_RegisterVar(&cv_dummyip);
|
||||||
|
|
||||||
M_UpdateMenuBGImage(true);
|
M_UpdateMenuBGImage(true);
|
||||||
|
|
||||||
|
|
@ -2286,30 +2291,10 @@ static void M_LevelSelectScrollDest(void)
|
||||||
levellist.dest = (6*m)-3;
|
levellist.dest = (6*m)-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_LevelSelectInit(INT32 choice)
|
// Builds the level list we'll be using from the gametype we're choosing and send us to the apropriate menu.
|
||||||
|
static void M_LevelListFromGametype(INT16 gt)
|
||||||
{
|
{
|
||||||
(void)choice;
|
levellist.newgametype = gt;
|
||||||
|
|
||||||
switch (currentMenu->menuitems[itemOn].mvar1)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
cupgrid.grandprix = false;
|
|
||||||
levellist.timeattack = false;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
cupgrid.grandprix = false;
|
|
||||||
levellist.timeattack = true;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cupgrid.grandprix = true;
|
|
||||||
levellist.timeattack = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CONS_Alert(CONS_WARNING, "Bad level select init\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
levellist.newgametype = currentMenu->menuitems[itemOn].mvar2;
|
|
||||||
PLAY_CupSelectDef.prevMenu = currentMenu;
|
PLAY_CupSelectDef.prevMenu = currentMenu;
|
||||||
|
|
||||||
// Obviously go to Cup Select in gametypes that have cups.
|
// Obviously go to Cup Select in gametypes that have cups.
|
||||||
|
|
@ -2351,6 +2336,41 @@ void M_LevelSelectInit(INT32 choice)
|
||||||
|
|
||||||
PLAY_LevelSelectDef.prevMenu = currentMenu;
|
PLAY_LevelSelectDef.prevMenu = currentMenu;
|
||||||
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
|
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init level select for use in local play using the last choice we made.
|
||||||
|
// For the online MP version, see M_MPSetupNetgameMapSelect()
|
||||||
|
|
||||||
|
void M_LevelSelectInit(INT32 choice)
|
||||||
|
{
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
|
levellist.netgame = false; // Make sure this is reset as we'll only be using this function for offline games!
|
||||||
|
cupgrid.netgame = false; // Ditto
|
||||||
|
|
||||||
|
switch (currentMenu->menuitems[itemOn].mvar1)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
cupgrid.grandprix = false;
|
||||||
|
levellist.timeattack = false;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cupgrid.grandprix = false;
|
||||||
|
levellist.timeattack = true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cupgrid.grandprix = true;
|
||||||
|
levellist.timeattack = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CONS_Alert(CONS_WARNING, "Bad level select init\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
levellist.newgametype = currentMenu->menuitems[itemOn].mvar2;
|
||||||
|
|
||||||
|
M_LevelListFromGametype(levellist.newgametype);
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_CupSelectHandler(INT32 choice)
|
void M_CupSelectHandler(INT32 choice)
|
||||||
|
|
@ -2433,6 +2453,7 @@ void M_CupSelectHandler(INT32 choice)
|
||||||
paused = false;
|
paused = false;
|
||||||
SV_StartSinglePlayerServer();
|
SV_StartSinglePlayerServer();
|
||||||
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
|
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
|
||||||
|
netgame = levellist.netgame; // ^ ditto.
|
||||||
D_MapChange(
|
D_MapChange(
|
||||||
grandprixinfo.cup->levellist[0] + 1,
|
grandprixinfo.cup->levellist[0] + 1,
|
||||||
GT_RACE,
|
GT_RACE,
|
||||||
|
|
@ -2567,6 +2588,8 @@ void M_LevelSelectHandler(INT32 choice)
|
||||||
paused = false;
|
paused = false;
|
||||||
SV_StartSinglePlayerServer();
|
SV_StartSinglePlayerServer();
|
||||||
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
|
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
|
||||||
|
netgame = levellist.netgame; // ^ ditto.
|
||||||
|
|
||||||
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
||||||
|
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
|
@ -2609,22 +2632,121 @@ void M_LevelSelectTick(void)
|
||||||
struct mpmenu_s mpmenu;
|
struct mpmenu_s mpmenu;
|
||||||
|
|
||||||
// MULTIPLAYER OPTION SELECT
|
// MULTIPLAYER OPTION SELECT
|
||||||
void M_MPOptSelect(INT32 choice)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
// Use this as a quit routine within the HOST GAME and JOIN BY IP "sub" menus
|
||||||
|
boolean M_MPResetOpts(void)
|
||||||
|
{
|
||||||
|
UINT8 i = 0;
|
||||||
|
|
||||||
|
for (; i < 3; i++)
|
||||||
|
mpmenu.modewinextend[i][0] = 0; // Undo this
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_MPOptSelectInit(INT32 chocie)
|
void M_MPOptSelectInit(INT32 choice)
|
||||||
{
|
{
|
||||||
|
INT16 arrcpy[3][3] = {{0,68,0}, {0,48,0}, {0,12,0}};
|
||||||
|
UINT8 i = 0, j = 0; // To copy the array into the struct
|
||||||
|
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
mpmenu.modechoice = 0;
|
mpmenu.modechoice = 0;
|
||||||
mpmenu.ticker = 0;
|
mpmenu.ticker = 0;
|
||||||
|
|
||||||
|
for (; i < 3; i++)
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
mpmenu.modewinextend[i][j] = arrcpy[i][j]; // I miss Lua already
|
||||||
|
|
||||||
M_SetupNextMenu(&PLAY_MP_OptSelectDef, false);
|
M_SetupNextMenu(&PLAY_MP_OptSelectDef, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_MPOptSelectTick(void)
|
void M_MPOptSelectTick(void)
|
||||||
{
|
{
|
||||||
|
UINT8 i = 0;
|
||||||
|
|
||||||
|
// 3 Because we have 3 options in the menu
|
||||||
|
for (; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (mpmenu.modewinextend[i][0])
|
||||||
|
mpmenu.modewinextend[i][2] += 8;
|
||||||
|
else
|
||||||
|
mpmenu.modewinextend[i][2] -= 8;
|
||||||
|
|
||||||
|
mpmenu.modewinextend[i][2] = min(mpmenu.modewinextend[i][1], max(0, mpmenu.modewinextend[i][2]));
|
||||||
|
//CONS_Printf("%d - %d,%d,%d\n", i, mpmenu.modewinextend[i][0], mpmenu.modewinextend[i][1], mpmenu.modewinextend[i][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MULTIPLAYER HOST
|
||||||
|
void M_MPHostInit(INT32 choice)
|
||||||
|
{
|
||||||
|
|
||||||
|
(void)choice;
|
||||||
|
mpmenu.modewinextend[0][0] = 1;
|
||||||
|
M_SetupNextMenu(&PLAY_MP_HostDef, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void M_MPSetupNetgameMapSelect(INT32 choice)
|
||||||
|
{
|
||||||
|
|
||||||
|
INT16 gt = GT_RACE;
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
|
levellist.netgame = true; // Yep, we'll be starting a netgame.
|
||||||
|
cupgrid.netgame = true; // Ditto
|
||||||
|
levellist.timeattack = false; // Make sure we reset those
|
||||||
|
cupgrid.grandprix = false; // Ditto
|
||||||
|
|
||||||
|
// In case we ever want to add new gamemodes there somehow, have at it!
|
||||||
|
switch (cv_dummygametype.value)
|
||||||
|
{
|
||||||
|
case 1: // Battle
|
||||||
|
{
|
||||||
|
gt = GT_BATTLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
gt = GT_RACE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
M_LevelListFromGametype(gt); // Setup the level select.
|
||||||
|
// (This will also automatically send us to the apropriate menu)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MULTIPLAYER JOIN BY IP
|
||||||
|
void M_MPJoinIPInit(INT32 choice)
|
||||||
|
{
|
||||||
|
|
||||||
|
(void)choice;
|
||||||
|
mpmenu.modewinextend[1][0] = 1;
|
||||||
|
M_SetupNextMenu(&PLAY_MP_JoinIPDef, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempts to join a given IP from the menu.
|
||||||
|
void M_JoinIP(void)
|
||||||
|
{
|
||||||
|
if (*(cv_dummyip.string) == '\0') // Jack shit
|
||||||
|
{
|
||||||
|
M_StartMessage("Please specify an address.\n", NULL, MM_NOTHING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
COM_BufAddText(va("connect \"%s\"\n", cv_dummyip.string));
|
||||||
|
M_ClearMenus(true);
|
||||||
|
|
||||||
|
// A little "please wait" message.
|
||||||
|
M_DrawTextBox(56, BASEVIDHEIGHT/2-12, 24, 2);
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, "Connecting to server...");
|
||||||
|
I_OsPolling();
|
||||||
|
I_UpdateNoBlit();
|
||||||
|
if (rendermode == render_soft)
|
||||||
|
I_FinishUpdate(); // page flip or blit buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// MULTIPLAYER ROOM SELECT MENU
|
// MULTIPLAYER ROOM SELECT MENU
|
||||||
|
|
@ -2664,6 +2786,7 @@ void M_MPRoomSelectTick(void)
|
||||||
|
|
||||||
void M_MPRoomSelectInit(INT32 choice)
|
void M_MPRoomSelectInit(INT32 choice)
|
||||||
{
|
{
|
||||||
|
(void)choice;
|
||||||
mpmenu.room = 0;
|
mpmenu.room = 0;
|
||||||
mpmenu.ticker = 0;
|
mpmenu.ticker = 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue