DEADSOFTWARE

game: disable gibs for server
[d2df-sdl.git] / src / game / opengl / r_game.pas
index 090f6747993d012701e4f6dee7367afb12c43b11..3a64ad534e7236e1eefcc9524d7ea8f1586e9591 100644 (file)
@@ -17,22 +17,45 @@ unit r_game;
 
 interface
 
+  procedure r_Game_Load;
+  procedure r_Game_Free;
+
+  procedure r_Game_LoadTextures;
+  procedure r_Game_FreeTextures;
+
   procedure r_Game_Draw;
   procedure r_Game_DrawLoadingStat;
   procedure r_Game_DrawMenuBackground (tex: AnsiString);
 
+  procedure r_Game_SetupScreenSize;
+
+  var
+    gStdFont: DWORD;
+    gMenuFont: DWORD;
+    gMenuSmallFont: DWORD;
+
 implementation
 
   uses
     {$INCLUDE ../nogl/noGLuses.inc}
+    {$IFDEF ENABLE_HOLMES}
+      g_holmes,
+    {$ENDIF}
+    {$IFDEF ENABLE_MENU}
+      g_gui, g_menu,
+    {$ENDIF}
+    {$IFDEF ENABLE_GFX}
+      g_gfx, r_gfx,
+    {$ENDIF}
     SysUtils, Classes, Math,
-    e_graphics,
-    g_system, g_touch,
-    MAPDEF, xprofiler, utils, wadreader,
-    g_textures, e_input, e_sound,
-    g_language, g_console, g_menu, g_triggers, g_player, g_options, g_monsters, g_map, g_panel, g_window,
-    g_items, g_weapons, g_gfx, g_phys, g_net, g_gui, g_netmaster,
-    g_game, r_console, r_gfx, r_items, r_map, r_panel, r_monsters
+    g_base, g_basic, r_graphics,
+    g_system,
+    MAPDEF, xprofiler, utils, wadreader, CONFIG,
+    e_input, e_sound,
+    g_language, g_console, g_triggers, g_player, g_options, g_monsters, g_map, g_panel,
+    g_items, g_weapons, g_phys, g_net, g_netmaster,
+    g_game, r_console, r_items, r_map, r_monsters, r_weapons, r_netmaster, r_player, r_textures,
+    r_playermodel
   ;
 
   var
@@ -41,6 +64,229 @@ implementation
     FPS: Word;
     FPSCounter: Word;
     FPSTime: LongWord;
+    hasPBarGfx: Boolean;
+
+    BackID: DWORD = DWORD(-1);
+    gBackSize: TDFPoint;
+
+procedure LoadStdFont(cfgres, texture: string; var FontID: DWORD);
+var
+  cwdt, chgt: Byte;
+  spc: ShortInt;
+  ID: DWORD;
+  wad: TWADFile;
+  cfgdata: Pointer;
+  cfglen: Integer;
+  config: TConfig;
+begin
+  cfglen := 0;
+
+  wad := TWADFile.Create;
+  if wad.ReadFile(GameWAD) then
+    wad.GetResource('FONTS/'+cfgres, cfgdata, cfglen);
+  wad.Free();
+
+  if cfglen <> 0 then
+  begin
+    g_Texture_CreateWADEx('FONT_STD', GameWAD+':FONTS\'+texture);
+
+    config := TConfig.CreateMem(cfgdata, cfglen);
+    cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
+    chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
+    spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127);
+
+    if g_Texture_Get('FONT_STD', ID) then
+      e_TextureFontBuild(ID, FontID, cwdt, chgt, spc);
+
+    config.Free();
+  end;
+
+  if cfglen <> 0 then FreeMem(cfgdata);
+end;
+
+procedure LoadFont(txtres, fntres: string; var FontID: DWORD);
+var
+  cwdt, chgt: Byte;
+  spc: ShortInt;
+  CharID: DWORD;
+  wad: TWADFile;
+  cfgdata, fntdata: Pointer;
+  cfglen, fntlen: Integer;
+  config: TConfig;
+  chrwidth: Integer;
+  a: Byte;
+begin
+  cfglen := 0;
+  fntlen := 0;
+
+  wad := TWADFile.Create;
+  if wad.ReadFile(GameWAD) then
+  begin
+    wad.GetResource('FONTS/'+txtres, cfgdata, cfglen);
+    wad.GetResource('FONTS/'+fntres, fntdata, fntlen);
+  end;
+  wad.Free();
+
+  if cfglen <> 0 then
+  begin
+    config := TConfig.CreateMem(cfgdata, cfglen);
+    cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
+    chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
+
+    spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127);
+    FontID := e_CharFont_Create(spc);
+
+    for a := 0 to 255 do
+    begin
+      chrwidth := config.ReadInt(IntToStr(a), 'Width', 0);
+      if chrwidth = 0 then Continue;
+
+      if e_CreateTextureMemEx(fntdata, fntlen, CharID, cwdt*(a mod 16), chgt*(a div 16),
+                              cwdt, chgt) then
+        e_CharFont_AddChar(FontID, CharID, Chr(a), chrwidth);
+    end;
+
+    config.Free();
+  end;
+
+  if cfglen <> 0 then FreeMem(cfgdata);
+  if fntlen <> 0 then FreeMem(fntdata);
+end;
+
+  procedure r_Game_Load;
+    var
+      wl, hl: Integer;
+      wr, hr: Integer;
+      wb, hb: Integer;
+      wm, hm: Integer;
+  begin
+    // early load
+    g_Texture_CreateWADEx('MENU_BACKGROUND', GameWAD + ':TEXTURES\TITLE', gTextureFilter);
+    g_Texture_CreateWADEx('INTER', GameWAD + ':TEXTURES\INTER', gTextureFilter);
+    g_Texture_CreateWADEx('ENDGAME_EN', GameWAD + ':TEXTURES\ENDGAME_EN', gTextureFilter);
+    g_Texture_CreateWADEx('ENDGAME_RU', GameWAD + ':TEXTURES\ENDGAME_RU', gTextureFilter);
+    LoadStdFont('STDTXT', 'STDFONT', gStdFont);
+    LoadFont('MENUTXT', 'MENUFONT', gMenuFont);
+    LoadFont('SMALLTXT', 'SMALLFONT', gMenuSmallFont);
+    // game data
+    g_Texture_CreateWADEx('NOTEXTURE', GameWAD + ':TEXTURES\NOTEXTURE');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_HUD', GameWAD + ':TEXTURES\HUD');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDAIR', GameWAD + ':TEXTURES\AIRBAR');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDJET', GameWAD + ':TEXTURES\JETBAR');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_HUDBG', GameWAD + ':TEXTURES\HUDBG');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_ARMORHUD', GameWAD + ':TEXTURES\ARMORHUD');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG', GameWAD + ':TEXTURES\FLAGHUD_R_BASE');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_S', GameWAD + ':TEXTURES\FLAGHUD_R_STOLEN');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_REDFLAG_D', GameWAD + ':TEXTURES\FLAGHUD_R_DROP');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG', GameWAD + ':TEXTURES\FLAGHUD_B_BASE');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_S', GameWAD + ':TEXTURES\FLAGHUD_B_STOLEN');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_BLUEFLAG_D', GameWAD + ':TEXTURES\FLAGHUD_B_DROP');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_TALKBUBBLE', GameWAD + ':TEXTURES\TALKBUBBLE');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_INVULPENTA', GameWAD + ':TEXTURES\PENTA');
+    g_Texture_CreateWADEx('TEXTURE_PLAYER_INDICATOR', GameWAD + ':TEXTURES\PLRIND');
+    // bar
+    hasPBarGfx := true;
+    if not g_Texture_CreateWADEx('UI_GFX_PBAR_LEFT', GameWAD+':TEXTURES\LLEFT') then hasPBarGfx := false;
+    if not g_Texture_CreateWADEx('UI_GFX_PBAR_MARKER', GameWAD+':TEXTURES\LMARKER') then hasPBarGfx := false;
+    if not g_Texture_CreateWADEx('UI_GFX_PBAR_MIDDLE', GameWAD+':TEXTURES\LMIDDLE') then hasPBarGfx := false;
+    if not g_Texture_CreateWADEx('UI_GFX_PBAR_RIGHT', GameWAD+':TEXTURES\LRIGHT') then hasPBarGfx := false;
+    if hasPBarGfx then
+    begin
+      g_Texture_GetSize('UI_GFX_PBAR_LEFT', wl, hl);
+      g_Texture_GetSize('UI_GFX_PBAR_RIGHT', wr, hr);
+      g_Texture_GetSize('UI_GFX_PBAR_MIDDLE', wb, hb);
+      g_Texture_GetSize('UI_GFX_PBAR_MARKER', wm, hm);
+      if (wl > 0) and (hl > 0) and (wr > 0) and (hr = hl) and (wb > 0) and (hb = hl) and (wm > 0) and (hm > 0) and (hm <= hl) then
+      begin
+        // yay!
+      end
+      else
+        hasPBarGfx := false;
+    end;
+  end;
+
+  procedure r_Game_Free;
+  begin
+    g_Texture_Delete('NOTEXTURE');
+    g_Texture_Delete('TEXTURE_PLAYER_HUD');
+    g_Texture_Delete('TEXTURE_PLAYER_HUDBG');
+    g_Texture_Delete('TEXTURE_PLAYER_ARMORHUD');
+    g_Texture_Delete('TEXTURE_PLAYER_REDFLAG');
+    g_Texture_Delete('TEXTURE_PLAYER_REDFLAG_S');
+    g_Texture_Delete('TEXTURE_PLAYER_REDFLAG_D');
+    g_Texture_Delete('TEXTURE_PLAYER_BLUEFLAG');
+    g_Texture_Delete('TEXTURE_PLAYER_BLUEFLAG_S');
+    g_Texture_Delete('TEXTURE_PLAYER_BLUEFLAG_D');
+    g_Texture_Delete('TEXTURE_PLAYER_TALKBUBBLE');
+    g_Texture_Delete('TEXTURE_PLAYER_INVULPENTA');
+  end;
+
+procedure r_Game_SetupScreenSize;
+const
+  RES_FACTOR = 4.0 / 3.0;
+var
+  s: Single;
+  rf: Single;
+  bw, bh: Word;
+begin
+// Размер экранов игроков:
+  gPlayerScreenSize.X := gScreenWidth-196;
+  if (gPlayer1 <> nil) and (gPlayer2 <> nil) then
+    gPlayerScreenSize.Y := gScreenHeight div 2
+  else
+    gPlayerScreenSize.Y := gScreenHeight;
+
+// Размер заднего плана:
+  if BackID <> DWORD(-1) then
+  begin
+    s := SKY_STRETCH;
+    if (gScreenWidth*s > gMapInfo.Width) or
+       (gScreenHeight*s > gMapInfo.Height) then
+    begin
+      gBackSize.X := gScreenWidth;
+      gBackSize.Y := gScreenHeight;
+    end
+    else
+    begin
+      e_GetTextureSize(BackID, @bw, @bh);
+      rf := Single(bw) / Single(bh);
+      if (rf > RES_FACTOR) then bw := Round(Single(bh) * RES_FACTOR)
+      else if (rf < RES_FACTOR) then bh := Round(Single(bw) / RES_FACTOR);
+      s := Max(gScreenWidth / bw, gScreenHeight / bh);
+      if (s < 1.0) then s := 1.0;
+      gBackSize.X := Round(bw*s);
+      gBackSize.Y := Round(bh*s);
+    end;
+  end;
+end;
+
+  procedure r_Game_LoadTextures;
+  begin
+    g_Texture_CreateWADEx('TEXTURE_endpic', EndPicPath, gTextureFilter);
+    if gMapInfo.SkyFullName <> '' then
+      g_Texture_CreateWAD(BackID, gMapInfo.SkyFullName, gTextureFilter);
+    r_Game_SetupScreenSize;
+  end;
+
+  procedure r_Game_FreeTextures;
+  begin
+    g_Texture_Delete('TEXTURE_endpic');
+    if BackID <> DWORD(-1) then
+    begin
+      gBackSize.X := 0;
+      gBackSize.Y := 0;
+      e_DeleteTexture(BackID);
+      BackID := DWORD(-1);
+    end
+  end;
+
+procedure r_Map_DrawBack(dx, dy: Integer);
+begin
+  if gDrawBackGround and (BackID <> DWORD(-1)) then
+    e_DrawSize(BackID, dx, dy, 0, False, False, gBackSize.X, gBackSize.Y)
+  else
+    e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0);
+end;
 
 function GetActivePlayer_ByID(ID: Integer): TPlayer;
 var
@@ -557,7 +803,9 @@ begin
   // HACK: take stats screenshot immediately after the first frame of the stats showing
   if gScreenshotStats and (not StatShotDone) and (Length(CustomStat.PlayerStat) > 1) then
   begin
+{$IFNDEF HEADLESS}
     g_TakeScreenShot('stats/' + StatFilename);
+{$ENDIF}
     StatShotDone := True;
   end;
 end;
@@ -820,7 +1068,7 @@ begin
   else e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0);
 end;
 
-procedure DrawMinimap(p: TPlayer; RenderRect: e_graphics.TRect);
+procedure DrawMinimap(p: TPlayer; RenderRect: TRect);
 var
   a, aX, aY, aX2, aY2, Scale, ScaleSz: Integer;
 
@@ -1025,6 +1273,65 @@ begin
   e_AmbientQuad(sX, sY, sWidth, sHeight, ambColor.r, ambColor.g, ambColor.b, ambColor.a);
 end;
 
+// ////////////////////////////////////////////////////////////////////////// //
+var
+  ltexid: GLuint = 0;
+
+function g_Texture_Light (): Integer;
+const
+  Radius: Integer = 128;
+var
+  tex, tpp: PByte;
+  x, y, a: Integer;
+  dist: Double;
+begin
+  if ltexid = 0 then
+  begin
+    GetMem(tex, (Radius*2)*(Radius*2)*4);
+    tpp := tex;
+    for y := 0 to Radius*2-1 do
+    begin
+      for x := 0 to Radius*2-1 do
+      begin
+        dist := 1.0-sqrt((x-Radius)*(x-Radius)+(y-Radius)*(y-Radius))/Radius;
+        if (dist < 0) then
+        begin
+          tpp^ := 0; Inc(tpp);
+          tpp^ := 0; Inc(tpp);
+          tpp^ := 0; Inc(tpp);
+          tpp^ := 0; Inc(tpp);
+        end
+        else
+        begin
+          //tc.setPixel(x, y, Color(cast(int)(dist*255), cast(int)(dist*255), cast(int)(dist*255)));
+          if (dist > 0.5) then dist := 0.5;
+          a := round(dist*255);
+          if (a < 0) then a := 0 else if (a > 255) then a := 255;
+          tpp^ := 255; Inc(tpp);
+          tpp^ := 255; Inc(tpp);
+          tpp^ := 255; Inc(tpp);
+          tpp^ := Byte(a); Inc(tpp);
+        end;
+      end;
+    end;
+
+    glGenTextures(1, @ltexid);
+    //if (tid == 0) assert(0, "VGL: can't create screen texture");
+
+    glBindTexture(GL_TEXTURE_2D, ltexid);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+    //GLfloat[4] bclr = 0.0;
+    //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr);
+
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Radius*2, Radius*2, 0, GL_RGBA{gltt}, GL_UNSIGNED_BYTE, tex);
+  end;
+
+  result := ltexid;
+end;
 
 // setup sX, sY, sWidth, sHeight, and transformation matrix before calling this!
 //FIXME: broken for splitscreen mode
@@ -1239,15 +1546,20 @@ begin
   drawPanelType('*back', PANEL_BACK, g_rlayer_back);
   drawPanelType('*step', PANEL_STEP, g_rlayer_step);
   drawOther('items', @r_Items_Draw);
-  drawOther('weapons', @g_Weapon_Draw);
-  drawOther('shells', @g_Player_DrawShells);
-  drawOther('drawall', @g_Player_DrawAll);
-  drawOther('corpses', @g_Player_DrawCorpses);
+  drawOther('weapons', @r_Weapon_Draw);
+  drawOther('shells', @r_Player_DrawShells);
+  drawOther('drawall', @r_Player_DrawAll);
+  {$IFDEF ENABLE_GIBS}
+    drawOther('gibs', @r_PlayerModel_DrawGibs);
+  {$ENDIF}
+  drawOther('corpses', @r_Player_DrawCorpses);
   drawPanelType('*wall', PANEL_WALL, g_rlayer_wall);
   drawOther('monsters', @r_Monsters_Draw);
   drawOther('itemdrop', @r_Items_DrawDrop);
   drawPanelType('*door', PANEL_CLOSEDOOR, g_rlayer_door);
-  drawOther('gfx', @r_GFX_Draw);
+  {$IFDEF ENABLE_GFX}
+    drawOther('gfx', @r_GFX_Draw);
+  {$ENDIF}
   drawOther('flags', @r_Map_DrawFlags);
   drawPanelType('*acid1', PANEL_ACID1, g_rlayer_acid1);
   drawPanelType('*acid2', PANEL_ACID2, g_rlayer_acid2);
@@ -1266,7 +1578,7 @@ begin
   if g_debug_HealthBar then
   begin
     r_Monsters_DrawHealth();
-    g_Player_DrawHealth();
+    r_Player_DrawHealth();
   end;
 
   if (profileFrameDraw <> nil) then profileFrameDraw.mainEnd(); // map rendering
@@ -1436,16 +1748,18 @@ begin
   if (gGameSettings.GameMode <> GM_SINGLE) and (gPlayerIndicator > 0) then
     case gPlayerIndicator of
       1:
-        p.DrawIndicator(_RGB(255, 255, 255));
+        r_Player_DrawIndicator(p, _RGB(255, 255, 255));
 
       2:
         for i := 0 to High(gPlayers) do
           if gPlayers[i] <> nil then
-            if gPlayers[i] = p then p.DrawIndicator(_RGB(255, 255, 255))
+            if gPlayers[i] = p then
+              r_Player_DrawIndicator(p, _RGB(255, 255, 255))
             else if (gPlayers[i].Team = p.Team) and (gPlayers[i].Team <> TEAM_NONE) then
               if gPlayerIndicatorStyle = 1 then
-                gPlayers[i].DrawIndicator(_RGB(192, 192, 192))
-              else gPlayers[i].DrawIndicator(gPlayers[i].GetColor);
+                r_Player_DrawIndicator(gPlayers[i], _RGB(192, 192, 192))
+              else
+                r_Player_DrawIndicator(gPlayers[i], gPlayers[i].GetColor);
     end;
 
   {
@@ -1468,13 +1782,13 @@ begin
 
   glPopMatrix();
 
-  p.DrawPain();
-  p.DrawPickup();
-  p.DrawRulez();
+  r_Player_DrawPain(p);
+  r_Player_DrawPickup(p);
+  r_Player_DrawRulez(p);
   if gShowMap then DrawMinimap(p, _TRect(0, 0, 128, 128));
   if g_Debug_Player then
-    g_Player_DrawDebug(p);
-  p.DrawGUI();
+    r_Player_DrawDebug(p);
+  r_Player_DrawGUI(p);
 end;
 
 procedure drawProfilers ();
@@ -1496,10 +1810,12 @@ var
   back: string;
   plView1, plView2: TPlayer;
   Split: Boolean;
+  MsgLineLength: Integer;
+  MsgText: String;
 begin
   if gExit = EXIT_QUIT then Exit;
 
-  Time := sys_GetTicks() {div 1000};
+  Time := GetTickCount64() {div 1000};
   FPSCounter := FPSCounter+1;
   if Time - FPSTime >= 1000 then
   begin
@@ -1643,12 +1959,14 @@ begin
       w := 0;
       h := 0;
       e_CharFont_GetSizeFmt(gMenuFont, MessageText, w, h);
+      MsgLineLength := (gScreenWidth - 204) div e_CharFont_GetMaxWidth(gMenuFont);
+      MsgText := b_Text_Wrap(b_Text_Format(MessageText), MsgLineLength);
       if Split then
         e_CharFont_PrintFmt(gMenuFont, (gScreenWidth div 2)-(w div 2),
-                        (gScreenHeight div 2)-(h div 2), MessageText)
+                        (gScreenHeight div 2)-(h div 2), MsgText)
       else
         e_CharFont_PrintFmt(gMenuFont, (gScreenWidth div 2)-(w div 2),
-                  Round(gScreenHeight / 2.75)-(h div 2), MessageText);
+                  Round(gScreenHeight / 2.75)-(h div 2), MsgText);
     end;
 
     if IsDrawStat or (gSpectMode = SPECT_STATS) then
@@ -1702,7 +2020,11 @@ begin
     end;
   end;
 
+{$IFDEF ENABLE_MENU}
   if gPauseMain and gGameOn and (g_ActiveWindow = nil) then
+{$ELSE}
+  if gPauseMain and gGameOn then
+{$ENDIF}
   begin
     //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
     e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
@@ -1714,26 +2036,30 @@ begin
 
   if not gGameOn then
   begin
-    if (gState = STATE_MENU) then
-    begin
-      if (g_ActiveWindow = nil) or (g_ActiveWindow.BackTexture = '') then r_Game_DrawMenuBackground('MENU_BACKGROUND');
-      // F3 at menu will show game loading dialog
-      if e_KeyPressed(IK_F3) then g_Menu_Show_LoadMenu(true);
-      if (g_ActiveWindow <> nil) then
+    {$IFDEF ENABLE_MENU}
+      if (gState = STATE_MENU) then
       begin
-        //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
-        e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
-      end
-      else
-      begin
-        // F3 at titlepic will show game loading dialog
-        if e_KeyPressed(IK_F3) then
+        if (g_ActiveWindow = nil) or (g_ActiveWindow.BackTexture = '') then r_Game_DrawMenuBackground('MENU_BACKGROUND');
+        // F3 at menu will show game loading dialog
+        if e_KeyPressed(IK_F3) then g_Menu_Show_LoadMenu(true);
+        if (g_ActiveWindow <> nil) then
         begin
-          g_Menu_Show_LoadMenu(true);
-          if (g_ActiveWindow <> nil) then e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
+          //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
+          e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
+        end
+        else
+        begin
+          // F3 at titlepic will show game loading dialog
+          if e_KeyPressed(IK_F3) then
+          begin
+            g_Menu_Show_LoadMenu(true);
+            if (g_ActiveWindow <> nil) then e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
+          end;
         end;
       end;
-    end;
+    {$ELSE}
+      r_Game_DrawMenuBackground('MENU_BACKGROUND');
+    {$ENDIF}
 
     if gState = STATE_FOLD then
     begin
@@ -1755,11 +2081,13 @@ begin
 
       DrawCustomStat();
 
-      if g_ActiveWindow <> nil then
-      begin
-        //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
-        e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
-      end;
+      {$IFDEF ENABLE_MENU}
+        if g_ActiveWindow <> nil then
+        begin
+          //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
+          e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
+        end;
+      {$ENDIF}
     end;
 
     if gState = STATE_INTERSINGLE then
@@ -1776,11 +2104,13 @@ begin
 
         DrawSingleStat();
 
-        if g_ActiveWindow <> nil then
-        begin
-          //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
-          e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
-        end;
+        {$IFDEF ENABLE_MENU}
+          if g_ActiveWindow <> nil then
+          begin
+            //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
+            e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
+          end;
+        {$ENDIF}
       end;
     end;
 
@@ -1790,11 +2120,13 @@ begin
       if g_Texture_Get('TEXTURE_endpic', ID) then r_Game_DrawMenuBackground('TEXTURE_endpic')
       else r_Game_DrawMenuBackground(_lc[I_TEXTURE_ENDPIC]);
 
-      if g_ActiveWindow <> nil then
-      begin
-        //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
-        e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
-      end;
+      {$IFDEF ENABLE_MENU}
+        if g_ActiveWindow <> nil then
+        begin
+          //e_DrawFillQuad(0, 0, gScreenWidth-1, gScreenHeight-1, 48, 48, 48, 180);
+          e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
+        end;
+      {$ENDIF}
     end;
 
     if gState = STATE_SLIST then
@@ -1806,10 +2138,11 @@ begin
 //      end;
       r_Game_DrawMenuBackground('MENU_BACKGROUND');
       e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
-      g_Serverlist_Draw(slCurrent, slTable);
+      r_Serverlist_Draw(slCurrent, slTable);
     end;
   end;
 
+{$IFDEF ENABLE_MENU}
   if g_ActiveWindow <> nil then
   begin
     if gGameOn then
@@ -1819,6 +2152,7 @@ begin
     end;
     g_ActiveWindow.Draw();
   end;
+{$ENDIF}
 
 {$IFNDEF HEADLESS}
   r_Console_Draw();
@@ -1853,10 +2187,6 @@ begin
   e_SetRendertarget(False);
   e_SetViewPort(0, 0, gWinSizeX, gWinSizeY);
   e_BlitFramebuffer(gWinSizeX, gWinSizeY);
-
-  // draw the overlay stuff on top of it
-
-  g_Touch_Draw;
 end;
 
 end.