DEADSOFTWARE

render: separate server list logic and drawing
[d2df-sdl.git] / src / game / g_netmaster.pas
index 67747595d085f70169932a4cc1c984982c3fbbb3..d9c62c9efb78ea8821016e803d929bfac3e7a4c2 100644 (file)
@@ -133,7 +133,7 @@ var
   NMASTER_FORCE_UPDATE_TIMEOUT: Integer = 0; // fuck you, fpc, and your idiotic "diagnostics"
 
 
-procedure g_Net_Slist_Set (IP: AnsiString; Port: Word; list: AnsiString='');
+procedure g_Net_Slist_Set (list: AnsiString);
 function g_Net_Slist_Fetch (var SL: TNetServerList): Boolean;
 
 // make this server private
@@ -163,17 +163,21 @@ procedure g_Net_Slist_Pulse (timeout: Integer=0);
 procedure g_Net_Slist_ShutdownAll ();
 
 procedure g_Serverlist_GenerateTable (SL: TNetServerList; var ST: TNetServerTable);
-procedure g_Serverlist_Draw (var SL: TNetServerList; var ST: TNetServerTable);
 procedure g_Serverlist_Control (var SL: TNetServerList; var ST: TNetServerTable);
 
+function GetServerFromTable (Index: Integer; SL: TNetServerList; ST: TNetServerTable): TNetServer;
+
 function GetTimerMS (): Int64;
 
+  var (* private state *)
+    slSelection: Byte = 0;
+    slReadUrgent: Boolean = False;
 
 implementation
 
 uses
   e_input, e_graphics, e_log, g_window, g_net, g_console,
-  g_map, g_game, g_sound, g_gui, g_menu, g_options, g_language, g_basic,
+  g_map, g_game, g_sound, g_gui, g_menu, g_options, g_language, g_basic, r_game,
   wadreader, g_system, utils, hashtable;
 
 
@@ -183,10 +187,8 @@ var
   NetMEvent: ENetEvent;
   mlist: array of TMasterHost = nil;
 
-  slSelection: Byte = 0;
   slFetched: Boolean = False;
   slDirPressed: Boolean = False;
-  slReadUrgent: Boolean = False;
 
   reportsEnabled: Boolean = true;
 
@@ -1053,7 +1055,7 @@ end;
 //  g_Net_Slist_Set
 //
 //==========================================================================
-procedure g_Net_Slist_Set (IP: AnsiString; Port: Word; list: AnsiString='');
+procedure g_Net_Slist_Set (list: AnsiString);
 var
   f, dest: Integer;
   sa: AnsiString;
@@ -1064,13 +1066,6 @@ begin
 
   for f := 0 to High(mlist) do mlist[f].justAdded := false;
 
-  IP := Trim(IP);
-  if (length(IP) > 0) and (Port > 0) then
-  begin
-    sa := IP+':'+IntToStr(Port);
-    if parseAddressPort(ea, sa) then addMasterRecord(ea, sa);
-  end;
-
   list := Trim(list);
   //writeln('list=[', list, ']');
   while (length(list) > 0) do
@@ -1373,6 +1368,7 @@ var
   aliveCount: Integer;
   hasUnanswered: Boolean;
   stt, ct: Int64;
+  tmpsv: TNetServer;
 begin
   result := false;
   SL := nil;
@@ -1559,32 +1555,44 @@ begin
       if InMsg.ReadChar() <> 'D' then continue;
       if InMsg.ReadChar() <> 'F' then continue;
 
+      with tmpsv do
+      begin
+        Port := InMsg.ReadWord();
+        Ping := InMsg.ReadInt64();
+        Ping := GetTimerMS() - Ping;
+        Name := InMsg.ReadString();
+        Map := InMsg.ReadString();
+        GameMode := InMsg.ReadByte();
+        Players := InMsg.ReadByte();
+        MaxPlayers := InMsg.ReadByte();
+        Protocol := InMsg.ReadByte();
+        Password := InMsg.ReadByte() = 1;
+        LocalPl := InMsg.ReadByte();
+        Bots := InMsg.ReadWord();
+        PingAddr := SvAddr;
+      end;
+
       FromSL := False;
       for I := Low(SL) to High(SL) do
         if (SL[I].PingAddr.host = SvAddr.host) and
-           (SL[I].PingAddr.port = SvAddr.port) then
+           (SL[I].PingAddr.port = SvAddr.port) and
+           (SL[I].Port = tmpsv.Port) and
+           (SL[I].Name = tmpsv.Name) then
         begin
-          with SL[I] do
-          begin
-            Port := InMsg.ReadWord();
-            Ping := InMsg.ReadInt64();
-            Ping := GetTimerMS() - Ping;
-            Name := InMsg.ReadString();
-            Map := InMsg.ReadString();
-            GameMode := InMsg.ReadByte();
-            Players := InMsg.ReadByte();
-            MaxPlayers := InMsg.ReadByte();
-            Protocol := InMsg.ReadByte();
-            Password := InMsg.ReadByte() = 1;
-            LocalPl := InMsg.ReadByte();
-            Bots := InMsg.ReadWord();
-          end;
+          tmpsv.IP := SL[I].IP;
+          SL[I] := tmpsv;
           FromSL := True;
           Inc(Cnt);
           break;
         end;
+
       if not FromSL then
-        ProcessLocal();
+      begin
+        I := Length(SL);
+        SetLength(SL, I + 1);
+        tmpsv.IP := DecodeIPV4(SvAddr.host);
+        SL[I] := tmpsv;
+      end;
     end;
 
     InMsg.Free();
@@ -1624,158 +1632,6 @@ begin
 end;
 
 
-//==========================================================================
-//
-//  g_Serverlist_Draw
-//
-//==========================================================================
-procedure g_Serverlist_Draw (var SL: TNetServerList; var ST: TNetServerTable);
-var
-  Srv: TNetServer;
-  sy, i, y, mw, mx, l, motdh: Integer;
-  cw: Byte = 0;
-  ch: Byte = 0;
-  ww: Word = 0;
-  hh: Word = 0;
-  ip: AnsiString;
-begin
-  ip := '';
-  sy := 0;
-
-  e_CharFont_GetSize(gMenuFont, _lc[I_NET_SLIST], ww, hh);
-  e_CharFont_Print(gMenuFont, (gScreenWidth div 2) - (ww div 2), 16, _lc[I_NET_SLIST]);
-
-  e_TextureFontGetSize(gStdFont, cw, ch);
-
-  ip := _lc[I_NET_SLIST_HELP];
-  mw := (Length(ip) * cw) div 2;
-
-  motdh := gScreenHeight - 49 - ch * b_Text_LineCount(slMOTD);
-
-  e_DrawFillQuad(16, 64, gScreenWidth-16, motdh, 64, 64, 64, 110);
-  e_DrawQuad(16, 64, gScreenWidth-16, motdh, 255, 127, 0);
-
-  e_TextureFontPrintEx(gScreenWidth div 2 - mw, gScreenHeight-24, ip, gStdFont, 225, 225, 225, 1);
-
-  // MOTD
-  if slMOTD <> '' then
-  begin
-    e_DrawFillQuad(16, motdh, gScreenWidth-16, gScreenHeight-44, 64, 64, 64, 110);
-    e_DrawQuad(16, motdh, gScreenWidth-16, gScreenHeight-44, 255, 127, 0);
-    e_TextureFontPrintFmt(20, motdh + 3, slMOTD, gStdFont, False, True);
-  end;
-
-  // Urgent message
-  if not slReadUrgent and (slUrgent <> '') then
-  begin
-    e_DrawFillQuad(17, 65, gScreenWidth-17, motdh-1, 64, 64, 64, 128);
-    e_DrawFillQuad(gScreenWidth div 2 - 256, gScreenHeight div 2 - 60,
-      gScreenWidth div 2 + 256, gScreenHeight div 2 + 60, 64, 64, 64, 128);
-    e_DrawQuad(gScreenWidth div 2 - 256, gScreenHeight div 2 - 60,
-      gScreenWidth div 2 + 256, gScreenHeight div 2 + 60, 255, 127, 0);
-    e_DrawLine(1, gScreenWidth div 2 - 256, gScreenHeight div 2 - 40,
-      gScreenWidth div 2 + 256, gScreenHeight div 2 - 40, 255, 127, 0);
-    l := Length(_lc[I_NET_SLIST_URGENT]) div 2;
-    e_TextureFontPrint(gScreenWidth div 2 - cw * l, gScreenHeight div 2 - 58,
-      _lc[I_NET_SLIST_URGENT], gStdFont);
-    l := Length(slUrgent) div 2;
-    e_TextureFontPrintFmt(gScreenWidth div 2 - 253, gScreenHeight div 2 - 38,
-      slUrgent, gStdFont, False, True);
-    l := Length(_lc[I_NET_SLIST_URGENT_CONT]) div 2;
-    e_TextureFontPrint(gScreenWidth div 2 - cw * l, gScreenHeight div 2 + 41,
-      _lc[I_NET_SLIST_URGENT_CONT], gStdFont);
-    e_DrawLine(1, gScreenWidth div 2 - 256, gScreenHeight div 2 + 40,
-      gScreenWidth div 2 + 256, gScreenHeight div 2 + 40, 255, 127, 0);
-    Exit;
-  end;
-
-  if SL = nil then
-  begin
-    l := Length(slWaitStr) div 2;
-    e_DrawFillQuad(17, 65, gScreenWidth-17, motdh-1, 64, 64, 64, 128);
-    e_DrawQuad(gScreenWidth div 2 - 192, gScreenHeight div 2 - 10,
-      gScreenWidth div 2 + 192, gScreenHeight div 2 + 11, 255, 127, 0);
-    e_TextureFontPrint(gScreenWidth div 2 - cw * l, gScreenHeight div 2 - ch div 2,
-      slWaitStr, gStdFont);
-    Exit;
-  end;
-
-  y := 90;
-  if (slSelection < Length(ST)) then
-  begin
-    I := slSelection;
-    sy := y + 42 * I - 4;
-    Srv := GetServerFromTable(I, SL, ST);
-    ip := _lc[I_NET_ADDRESS] + ' ' + Srv.IP + ':' + IntToStr(Srv.Port);
-    if Srv.Password then
-      ip := ip + '  ' + _lc[I_NET_SERVER_PASSWORD] + ' ' + _lc[I_MENU_YES]
-    else
-      ip := ip + '  ' + _lc[I_NET_SERVER_PASSWORD] + ' ' + _lc[I_MENU_NO];
-  end else
-    if Length(ST) > 0 then
-      slSelection := 0;
-
-  mw := (gScreenWidth - 188);
-  mx := 16 + mw;
-
-  e_DrawFillQuad(16 + 1, sy, gScreenWidth - 16 - 1, sy + 40, 64, 64, 64, 0);
-  e_DrawLine(1, 16 + 1, sy, gScreenWidth - 16 - 1, sy, 205, 205, 205);
-  e_DrawLine(1, 16 + 1, sy + 41, gScreenWidth - 16 - 1, sy + 41, 255, 255, 255);
-
-  e_DrawLine(1, 16, 85, gScreenWidth - 16, 85, 255, 127, 0);
-  e_DrawLine(1, 16, motdh-20, gScreenWidth-16, motdh-20, 255, 127, 0);
-
-  e_DrawLine(1, mx - 70, 64, mx - 70, motdh, 255, 127, 0);
-  e_DrawLine(1, mx, 64, mx, motdh-20, 255, 127, 0);
-  e_DrawLine(1, mx + 52, 64, mx + 52, motdh-20, 255, 127, 0);
-  e_DrawLine(1, mx + 104, 64, mx + 104, motdh-20, 255, 127, 0);
-
-  e_TextureFontPrintEx(18, 68, 'NAME/MAP', gStdFont, 255, 127, 0, 1);
-  e_TextureFontPrintEx(mx - 68, 68, 'PING', gStdFont, 255, 127, 0, 1);
-  e_TextureFontPrintEx(mx + 2, 68, 'MODE', gStdFont, 255, 127, 0, 1);
-  e_TextureFontPrintEx(mx + 54, 68, 'PLRS', gStdFont, 255, 127, 0, 1);
-  e_TextureFontPrintEx(mx + 106, 68, 'VER', gStdFont, 255, 127, 0, 1);
-
-  y := 90;
-  for I := 0 to High(ST) do
-  begin
-    Srv := GetServerFromTable(I, SL, ST);
-    // Name and map
-    e_TextureFontPrintEx(18, y, Srv.Name, gStdFont, 255, 255, 255, 1);
-    e_TextureFontPrintEx(18, y + 16, Srv.Map, gStdFont, 210, 210, 210, 1);
-
-    // Ping and similar count
-    if (Srv.Ping < 0) or (Srv.Ping > 999) then
-      e_TextureFontPrintEx(mx - 68, y, _lc[I_NET_SLIST_NO_ACCESS], gStdFont, 255, 0, 0, 1)
-    else
-      if Srv.Ping = 0 then
-        e_TextureFontPrintEx(mx - 68, y, '<1' + _lc[I_NET_SLIST_PING_MS], gStdFont, 255, 255, 255, 1)
-      else
-        e_TextureFontPrintEx(mx - 68, y, IntToStr(Srv.Ping) + _lc[I_NET_SLIST_PING_MS], gStdFont, 255, 255, 255, 1);
-
-    if Length(ST[I].Indices) > 1 then
-      e_TextureFontPrintEx(mx - 68, y + 16, '< ' + IntToStr(Length(ST[I].Indices)) + ' >', gStdFont, 210, 210, 210, 1);
-
-    // Game mode
-    e_TextureFontPrintEx(mx + 2, y, g_Game_ModeToText(Srv.GameMode), gStdFont, 255, 255, 255, 1);
-
-    // Players
-    e_TextureFontPrintEx(mx + 54, y, IntToStr(Srv.Players) + '/' + IntToStr(Srv.MaxPlayers), gStdFont, 255, 255, 255, 1);
-    e_TextureFontPrintEx(mx + 54, y + 16, IntToStr(Srv.LocalPl) + '+' + IntToStr(Srv.Bots), gStdFont, 210, 210, 210, 1);
-
-    // Version
-    e_TextureFontPrintEx(mx + 106, y, IntToStr(Srv.Protocol), gStdFont, 255, 255, 255, 1);
-
-    y := y + 42;
-  end;
-
-  e_TextureFontPrintEx(20, motdh-20+3, ip, gStdFont, 205, 205, 205, 1);
-  ip := IntToStr(Length(ST)) + _lc[I_NET_SLIST_SERVERS];
-  e_TextureFontPrintEx(gScreenWidth - 48 - (Length(ip) + 1)*cw,
-    motdh-20+3, ip, gStdFont, 205, 205, 205, 1);
-end;
-
-
 //==========================================================================
 //
 //  g_Serverlist_GenerateTable
@@ -1785,7 +1641,7 @@ procedure g_Serverlist_GenerateTable (SL: TNetServerList; var ST: TNetServerTabl
 var
   i, j: Integer;
 
-  function FindServerInTable(Name: AnsiString): Integer;
+  function FindServerInTable(Name: AnsiString; Port: Word): Integer;
   var
     i: Integer;
   begin
@@ -1796,7 +1652,7 @@ var
     begin
       if Length(ST[i].Indices) = 0 then
         continue;
-      if SL[ST[i].Indices[0]].Name = Name then
+      if (SL[ST[i].Indices[0]].Name = Name) and (SL[ST[i].Indices[0]].Port = Port) then
       begin
         Result := i;
         Exit;
@@ -1845,9 +1701,10 @@ begin
   ST := nil;
   if SL = nil then
     Exit;
+
   for i := Low(SL) to High(SL) do
   begin
-    j := FindServerInTable(SL[i].Name);
+    j := FindServerInTable(SL[i].Name, SL[i].Port);
     if j = -1 then
     begin
       j := Length(ST);
@@ -1917,7 +1774,7 @@ begin
     begin
       slWaitStr := _lc[I_NET_SLIST_WAIT];
 
-      g_Game_Draw;
+      r_Game_Draw;
       sys_Repaint;
 
       if g_Net_Slist_Fetch(SL) then