Lobbies hold eight, and the room lays itself out to fit them
The lobby capped at four, which is half a grid. The pod hall raced eight and the egg builder already carries the owner plus maxExtraPilots, so eight members fit with room to spare. CreateLobby now asks Steam for eight and the roster arrays follow. Checked what eight has to travel through before raising it: the go roster is 43 bytes a member against an 800 byte buffer, the score sheet 41 against 600, and the pods list 21 against 512, so all three hold eight with margin. The member side parses the go string with a cursor rather than a fixed array, and RegisterRoster walks the count it is given, so neither needed touching. The layout is the part that could not just be renumbered. Rows were a fixed sixteenth of the window, and eight of those ran off the bottom of every window we support - the buttons are laid out upward from the bottom edge while the roster runs down from the top, so the two meet in the middle. The room now measures the band between the title and the topmost button and sizes its rows to it, counted in half rows as setup lines + gap + eight rows + gap + hint so the row height falls out of the space actually available. It never grows past the old sixteenth, so a two player lobby does not get circus sized rows, and when the band cannot give eight rows the room the font needs, the block is drawn in a font that does fit rather than letting rows overlap. The minimum row is the font cell plus two, not the cell plus an eighth. That sounds like a detail and is not: at 1920x1080 the generous version missed by one pixel and paid for it by dropping the conditions line out of every football lobby, which is the one thing in the room nobody can see for themselves. Verified live on hosted lobbies at 1904x1041, and modelled across every window size from 3440x1440 down to 800x480 in race and football, host and member. Race keeps both setup lines everywhere; football, which carries four stacked buttons, keeps both down to 1080 and drops to one below that. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+73
-27
@@ -36,7 +36,10 @@ void RPL4Lobby_PullRaceResults() { }
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { kMaxLobbyMembers = 4 };
|
||||
// A full grid is eight pods, as the pod hall ran it. The egg builder
|
||||
// carries the owner plus maxExtraPilots (8), so eight members fit
|
||||
// with room to spare.
|
||||
enum { kMaxLobbyMembers = 8 };
|
||||
const char kLobbyTagKey[] = "rp412";
|
||||
const char kGoKey[] = "go";
|
||||
|
||||
@@ -379,7 +382,6 @@ namespace
|
||||
-1, &title, DT_CENTER | DT_TOP | DT_SINGLELINE);
|
||||
|
||||
SelectObject(mem, room->textFont);
|
||||
int row_h = client.bottom / 16;
|
||||
// wider than the old middle-half: the right column now carries
|
||||
// full catalog names, and in football three of them
|
||||
int left = client.right / 6;
|
||||
@@ -387,23 +389,9 @@ namespace
|
||||
char text[128];
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// The host's setup, under the title: the track on its own line,
|
||||
// then the conditions. Everyone flies the owner's picks, so this
|
||||
// is the one thing in the room nobody can see for themselves.
|
||||
//
|
||||
// Drawn full width rather than the roster's middle half, because
|
||||
// track names run long ("Berserker's Bahnzai"), and the roster
|
||||
// then starts below whatever this took - two extra lines above a
|
||||
// fixed roster top would have run into the first player.
|
||||
//---------------------------------------------------------------
|
||||
int top = client.bottom / 4;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// The buttons are laid out upward from the bottom edge, so the
|
||||
// setup lines are only affordable if the roster and its hint
|
||||
// still clear the topmost one. Work out the room first and take
|
||||
// as many lines as fit - the map alone is worth more than the
|
||||
// conditions, so it goes first and drops last.
|
||||
// The buttons are laid out upward from the bottom edge while the
|
||||
// roster runs down from the top, so everything between the title
|
||||
// and the topmost button has to share one band.
|
||||
//---------------------------------------------------------------
|
||||
int ceiling = client.bottom;
|
||||
if (FootballLobby() && room->teamRect.top > 0)
|
||||
@@ -419,16 +407,67 @@ namespace
|
||||
ceiling = room->leaveRect.top;
|
||||
}
|
||||
|
||||
int setup_top = title.bottom + row_h / 4;
|
||||
// the fixed block below: four roster slots, a gap, and the hint,
|
||||
// plus the half row this block leaves above the roster
|
||||
int block = kMaxLobbyMembers * row_h + row_h / 2 + row_h;
|
||||
int setup_lines =
|
||||
(ceiling - block - setup_top - row_h / 2) / row_h;
|
||||
if (setup_lines > 2)
|
||||
//---------------------------------------------------------------
|
||||
// Size the rows to that band rather than to a fixed fraction of
|
||||
// the window: a full lobby is eight players, and eight rows at a
|
||||
// sixteenth each would run off the bottom of every window we
|
||||
// support. Counted in half rows, the band holds
|
||||
//
|
||||
// setup lines + gap + kMaxLobbyMembers rows + gap + hint
|
||||
//
|
||||
// so the row height falls out of the space actually available.
|
||||
// It never grows past the old sixteenth (a two-player lobby
|
||||
// should not have circus-sized rows) and never shrinks below the
|
||||
// font, which is what would actually break - overlapping text.
|
||||
//---------------------------------------------------------------
|
||||
// tmHeight already includes the font's own leading, so a row that
|
||||
// tall cannot clip or collide - asking for more than that just
|
||||
// costs setup lines the room would rather keep.
|
||||
TEXTMETRICA metrics;
|
||||
GetTextMetricsA(mem, &metrics);
|
||||
int min_row = metrics.tmHeight + 2;
|
||||
int max_row = client.bottom / 16;
|
||||
|
||||
int setup_top = title.bottom + client.bottom / 64;
|
||||
int band = ceiling - setup_top;
|
||||
|
||||
int setup_lines = 2;
|
||||
int row_h = 0;
|
||||
for (;;)
|
||||
{
|
||||
setup_lines = 2;
|
||||
// halves: setup, half gap, roster, half gap, hint
|
||||
int halves = 2 * setup_lines + 1 + 2 * kMaxLobbyMembers + 1 + 2;
|
||||
row_h = (2 * band) / halves;
|
||||
if (row_h >= min_row || setup_lines == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
--setup_lines; // buy room back from the setup lines
|
||||
}
|
||||
if (row_h > max_row) row_h = max_row;
|
||||
if (row_h < 12) row_h = 12;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// On a window too short to give eight rows the room the standard
|
||||
// font wants, draw this block smaller rather than letting the
|
||||
// rows overlap each other or run under the buttons. Nobody plays
|
||||
// at that size, but a squeezed roster still has to be readable.
|
||||
//---------------------------------------------------------------
|
||||
HFONT squeezed = NULL;
|
||||
HFONT previous = NULL;
|
||||
if (row_h < min_row)
|
||||
{
|
||||
squeezed = CreateFontA(-(row_h * 2 / 3), 0, 0, 0, FW_NORMAL,
|
||||
FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY,
|
||||
FIXED_PITCH | FF_MODERN, "Consolas");
|
||||
if (squeezed != NULL)
|
||||
{
|
||||
previous = (HFONT) SelectObject(mem, squeezed);
|
||||
}
|
||||
}
|
||||
|
||||
int top = setup_top;
|
||||
|
||||
const char *map_name = LobbyText(kMapKey);
|
||||
if (map_name[0] != '\0' && setup_lines > 0)
|
||||
@@ -534,6 +573,13 @@ namespace
|
||||
: "Waiting for the host to launch...",
|
||||
-1, &hint, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
|
||||
// back to the room font for the buttons, which have their own room
|
||||
if (squeezed != NULL)
|
||||
{
|
||||
SelectObject(mem, previous);
|
||||
DeleteObject(squeezed);
|
||||
}
|
||||
|
||||
HBRUSH frame = CreateSolidBrush(kGreenBright);
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user