DEADSOFTWARE

clean up GameCVars
[d2df-sdl.git] / src / game / g_game.pas
index 23c09434500a78b91de1423888484296164d8a95..6b1e238f6f7b5928175a440d04d9b73a1923d865 100644 (file)
@@ -290,7 +290,8 @@ var
   gMapToDelete: String;
   gTempDelete: Boolean = False;
   gLastMap: Boolean = False;
-  gWinSizeX, gWinSizeY: Integer;
+  gScreenWidth: Word;
+  gScreenHeight: Word;
   gResolutionChange: Boolean = False;
   gRC_Width, gRC_Height: Integer;
   gRC_FullScreen, gRC_Maximized: Boolean;
@@ -1064,7 +1065,7 @@ begin
 
           SortGameStat(CustomStat.PlayerStat);
 
-          if (gSaveStats or gScreenshotStats) and (Length(gPlayers) > 1) then
+          if (gSaveStats or gScreenshotStats) and (Length(CustomStat.PlayerStat) > 1) then
           begin
             t := Now;
             if g_Game_IsNet then StatFilename := NetServerName else StatFilename := 'local';
@@ -2875,7 +2876,7 @@ begin
   end;
 
   // HACK: take stats screenshot immediately after the first frame of the stats showing
-  if gScreenshotStats and not StatShotDone then
+  if gScreenshotStats and (not StatShotDone) and (Length(CustomStat.PlayerStat) > 1) then
   begin
     g_TakeScreenShot('stats/' + StatFilename);
     StatShotDone := True;
@@ -3417,7 +3418,7 @@ begin
     end
     else
     begin
-      glScissor(0, 0, gWinSizeX, gWinSizeY);
+      glScissor(0, 0, gScreenWidth, gScreenHeight);
     end;
     // no need to clear stencil buffer, light blitting will do it for us... but only for normal scale
     if (g_dbg_scale <> 1.0) then glClear(GL_STENCIL_BUFFER_BIT);
@@ -3667,67 +3668,45 @@ begin
     b := -py+(gPlayerScreenSize.Y div 2);
   end;
 
-  if p.IncCam <> 0 then
-  begin
-    if py > gMapInfo.Height-(gPlayerScreenSize.Y div 2) then
-    begin
-      if p.IncCam > 120-(py-(gMapInfo.Height-(gPlayerScreenSize.Y div 2))) then
-      begin
-        p.IncCam := 120-(py-(gMapInfo.Height-(gPlayerScreenSize.Y div 2)));
-      end;
-    end;
-
-    if py < gPlayerScreenSize.Y div 2 then
-    begin
-      if p.IncCam < -120+((gPlayerScreenSize.Y div 2)-py) then
-      begin
-        p.IncCam := -120+((gPlayerScreenSize.Y div 2)-py);
-      end;
-    end;
-
-    if p.IncCam < 0 then
-    begin
-      while (py+(gPlayerScreenSize.Y div 2)-p.IncCam > gMapInfo.Height) and (p.IncCam < 0) do p.IncCam := p.IncCam+1; //Inc(p.IncCam);
-    end;
-
-    if p.IncCam > 0 then
-    begin
-      while (py-(gPlayerScreenSize.Y div 2)-p.IncCam < 0) and (p.IncCam > 0) do p.IncCam := p.IncCam-1; //Dec(p.IncCam);
-    end;
-  end;
-
-       if (px < gPlayerScreenSize.X div 2) or (gMapInfo.Width-gPlayerScreenSize.X <= 256) then c := 0
-  else if (px > gMapInfo.Width-(gPlayerScreenSize.X div 2)) then c := gBackSize.X-gPlayerScreenSize.X
-  else c := round((px-(gPlayerScreenSize.X div 2))/(gMapInfo.Width-gPlayerScreenSize.X)*(gBackSize.X-gPlayerScreenSize.X));
-
-       if (py-p.IncCam <= gPlayerScreenSize.Y div 2) or (gMapInfo.Height-gPlayerScreenSize.Y <= 256) then d := 0
-  else if (py-p.IncCam >= gMapInfo.Height-(gPlayerScreenSize.Y div 2)) then d := gBackSize.Y-gPlayerScreenSize.Y
-  else d := round((py-p.IncCam-(gPlayerScreenSize.Y div 2))/(gMapInfo.Height-gPlayerScreenSize.Y)*(gBackSize.Y-gPlayerScreenSize.Y));
-
   sX := -a;
-  sY := -(b+p.IncCam);
+  sY := -b;
   sWidth := gPlayerScreenSize.X;
   sHeight := gPlayerScreenSize.Y;
+  fixViewportForScale();
 
-  //glTranslatef(a, b+p.IncCam, 0);
-
-  //if (p = gPlayer1) and (g_dbg_scale >= 1.0) then g_Holmes_plrViewSize(sWidth, sHeight);
+  i := py - (sY + sHeight div 2);
+  if (p.IncCam > 0) then
+  begin
+    // clamp to level bounds
+    if (sY - p.IncCam < 0) then
+      p.IncCam := nclamp(sY, 0, 120);
+    // clamp around player position
+    if (i > 0) then
+      p.IncCam := nclamp(p.IncCam, 0, max(0, 120 - i));
+  end
+  else if (p.IncCam < 0) then
+  begin
+    // clamp to level bounds
+    if (sY + sHeight - p.IncCam > gMapInfo.Height) then
+      p.IncCam := nclamp(sY + sHeight - gMapInfo.Height, -120, 0);
+    // clamp around player position
+    if (i < 0) then
+      p.IncCam := nclamp(p.IncCam, min(0, -120 - i), 0);
+  end;
 
-  //conwritefln('OLD: (%s,%s)-(%s,%s)', [sX, sY, sWidth, sHeight]);
-  fixViewportForScale();
-  //conwritefln('     (%s,%s)-(%s,%s)', [sX, sY, sWidth, sHeight]);
+  sY := sY - p.IncCam;
 
-  if (g_dbg_scale <> 1.0) and (not g_dbg_ignore_bounds) then
+  if (not g_dbg_ignore_bounds) then
   begin
     if (sX+sWidth > gMapInfo.Width) then sX := gMapInfo.Width-sWidth;
     if (sY+sHeight > gMapInfo.Height) then sY := gMapInfo.Height-sHeight;
     if (sX < 0) then sX := 0;
     if (sY < 0) then sY := 0;
-
-    if (gBackSize.X <= gPlayerScreenSize.X) or (gMapInfo.Width <= sWidth) then c := 0 else c := trunc((gBackSize.X-gPlayerScreenSize.X)*sX/(gMapInfo.Width-sWidth));
-    if (gBackSize.Y <= gPlayerScreenSize.Y) or (gMapInfo.Height <= sHeight) then d := 0 else d := trunc((gBackSize.Y-gPlayerScreenSize.Y)*sY/(gMapInfo.Height-sHeight));
   end;
 
+  if (gBackSize.X <= gPlayerScreenSize.X) or (gMapInfo.Width <= sWidth) then c := 0 else c := trunc((gBackSize.X-gPlayerScreenSize.X)*sX/(gMapInfo.Width-sWidth));
+  if (gBackSize.Y <= gPlayerScreenSize.Y) or (gMapInfo.Height <= sHeight) then d := 0 else d := trunc((gBackSize.Y-gPlayerScreenSize.Y)*sY/(gMapInfo.Height-sHeight));
+
   //r_smallmap_h: 0: left; 1: center; 2: right
   //r_smallmap_v: 0: top; 1: center; 2: bottom
   // horiz small map?
@@ -4641,7 +4620,7 @@ begin
 // Ñòàðòóåì ñåðâåð
   if not g_Net_Host(IPAddr, Port, NetMaxClients) then
   begin
-    g_FatalError(_lc[I_NET_MSG] + _lc[I_NET_ERR_HOST]);
+    g_FatalError(_lc[I_NET_MSG] + Format(_lc[I_NET_ERR_HOST], [Port]));
     Exit;
   end;
 
@@ -4969,6 +4948,8 @@ begin
     ResName := Map;
   end;
 
+  gTime := 0;
+
   //writeln('********: gsw=', gGameSettings.WAD, '; rn=', ResName);
   result := false;
   if (ResName <> '') and (NewWAD <> '') then
@@ -5005,7 +4986,6 @@ begin
   gExit := 0;
   gPauseMain := false;
   gPauseHolmes := false;
-  gTime := 0;
   NetTimeToUpdate := 1;
   NetTimeToReliable := 0;
   NetTimeToMaster := NetMasterRate;
@@ -5402,7 +5382,6 @@ var
   a, b: Integer;
   stat: TPlayerStatArray;
   cmd, s: string;
-  config: TConfig;
 begin
   stat := nil;
   cmd := LowerCase(P[0]);
@@ -5572,7 +5551,6 @@ begin
         g_Console_Add(_lc[I_MSG_DMKEYS_ON])
       else
         g_Console_Add(_lc[I_MSG_DMKEYS_OFF]);
-      g_Console_Add(_lc[I_MSG_ONMAPCHANGE]);
 
       if g_Game_IsNet then MH_SEND_GameSettings;
     end;
@@ -5610,14 +5588,6 @@ begin
     if (Length(P) > 1) then
       NetInterpLevel := StrToIntDef(P[1], NetInterpLevel);
     g_Console_Add('net_interp = ' + IntToStr(NetInterpLevel));
-    s := e_GetWriteableDir(ConfigDirs);
-    if s <> '' then
-    begin
-      config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
-      config.WriteInt('Client', 'InterpolationSteps', NetInterpLevel);
-      config.SaveFile(s + '/' + CONFIG_FILENAME);
-      config.Free
-    end
   end
   else if cmd = 'net_forceplayerupdate' then
   begin
@@ -5628,15 +5598,6 @@ begin
       g_Console_Add('net_forceplayerupdate = 1')
     else
       g_Console_Add('net_forceplayerupdate = 0');
-
-    s := e_GetWriteableDir(ConfigDirs);
-    if s <> '' then
-    begin
-      config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
-      config.WriteBool('Client', 'ForcePlayerUpdate', NetForcePlayerUpdate);
-      config.SaveFile(s + '/' + CONFIG_FILENAME);
-      config.Free
-    end
   end
   else if cmd = 'net_predictself' then
   begin
@@ -5648,15 +5609,6 @@ begin
       g_Console_Add('net_predictself = 1')
     else
       g_Console_Add('net_predictself = 0');
-
-    s := e_GetWriteableDir(ConfigDirs);
-    if s <> '' then
-    begin
-      config := TConfig.CreateFile(s + '/' + CONFIG_FILENAME);
-      config.WriteBool('Client', 'PredictSelf', NetPredictSelf);
-      config.SaveFile(s + '/' + CONFIG_FILENAME);
-      config.Free
-    end
   end
   else if cmd = 'sv_name' then
   begin
@@ -5729,219 +5681,222 @@ begin
   end
   else if cmd = 'p1_name' then
   begin
-    if (Length(P) > 1) and gGameOn then
+    if (Length(P) > 1) then
     begin
+      gPlayer1Settings.Name := b_Text_Unformat(P[1]);
       if g_Game_IsClient then
+        MC_SEND_PlayerSettings
+      else if gGameOn and (gPlayer1 <> nil) then
       begin
-        gPlayer1Settings.Name := b_Text_Unformat(P[1]);
-        MC_SEND_PlayerSettings;
-      end
-      else
-        if gPlayer1 <> nil then
-        begin
-          gPlayer1.Name := b_Text_Unformat(P[1]);
-          if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer1.UID);
-        end
-        else
-          gPlayer1Settings.Name := b_Text_Unformat(P[1]);
+        gPlayer1.Name := b_Text_Unformat(P[1]);
+        if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer1.UID);
+      end;
     end;
   end
   else if cmd = 'p2_name' then
   begin
-    if (Length(P) > 1) and gGameOn then
+    if (Length(P) > 1) then
     begin
+      gPlayer2Settings.Name := b_Text_Unformat(P[1]);
       if g_Game_IsClient then
+        MC_SEND_PlayerSettings
+      else if gGameOn and (gPlayer2 <> nil) then
       begin
-        gPlayer2Settings.Name := b_Text_Unformat(P[1]);
-        MC_SEND_PlayerSettings;
-      end
-      else
-        if gPlayer2 <> nil then
-        begin
-          gPlayer2.Name := b_Text_Unformat(P[1]);
-          if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer2.UID);
-        end
-        else
-          gPlayer2Settings.Name := b_Text_Unformat(P[1]);
+        gPlayer2.Name := b_Text_Unformat(P[1]);
+        if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer2.UID);
+      end;
     end;
   end
   else if cmd = 'p1_color' then
   begin
     if Length(P) > 3 then
+    begin
+      gPlayer1Settings.Color := _RGB(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
+                                     EnsureRange(StrToIntDef(P[2], 0), 0, 255),
+                                     EnsureRange(StrToIntDef(P[3], 0), 0, 255));
       if g_Game_IsClient then
+        MC_SEND_PlayerSettings
+      else if gGameOn and (gPlayer1 <> nil) then
       begin
-        gPlayer1Settings.Color := _RGB(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
-                                       EnsureRange(StrToIntDef(P[2], 0), 0, 255),
-                                       EnsureRange(StrToIntDef(P[3], 0), 0, 255));
-        MC_SEND_PlayerSettings;
-      end
-      else
-        if gPlayer1 <> nil then
-        begin
-          gPlayer1.Model.SetColor(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
-                                  EnsureRange(StrToIntDef(P[2], 0), 0, 255),
-                                  EnsureRange(StrToIntDef(P[3], 0), 0, 255));
-          if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer1.UID);
-        end
-        else
-          gPlayer1Settings.Color := _RGB(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
-                                         EnsureRange(StrToIntDef(P[2], 0), 0, 255),
-                                         EnsureRange(StrToIntDef(P[3], 0), 0, 255));
+        gPlayer1.SetColor(gPlayer1Settings.Color);
+        if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer1.UID);
+      end;
+    end;
   end
-  else if (cmd = 'p2_color') and not g_Game_IsNet then
+  else if cmd = 'p2_color' then
   begin
     if Length(P) > 3 then
+    begin
+      gPlayer2Settings.Color := _RGB(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
+                                     EnsureRange(StrToIntDef(P[2], 0), 0, 255),
+                                     EnsureRange(StrToIntDef(P[3], 0), 0, 255));
       if g_Game_IsClient then
+        MC_SEND_PlayerSettings
+      else if gGameOn and (gPlayer2 <> nil) then
       begin
-        gPlayer2Settings.Color := _RGB(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
-                                       EnsureRange(StrToIntDef(P[2], 0), 0, 255),
-                                       EnsureRange(StrToIntDef(P[3], 0), 0, 255));
-        MC_SEND_PlayerSettings;
-      end
-      else
-        if gPlayer2 <> nil then
-        begin
-          gPlayer2.Model.SetColor(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
-                                  EnsureRange(StrToIntDef(P[2], 0), 0, 255),
-                                  EnsureRange(StrToIntDef(P[3], 0), 0, 255));
-          if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer2.UID);
-        end
-        else
-          gPlayer2Settings.Color := _RGB(EnsureRange(StrToIntDef(P[1], 0), 0, 255),
-                                         EnsureRange(StrToIntDef(P[2], 0), 0, 255),
-                                         EnsureRange(StrToIntDef(P[3], 0), 0, 255));
+        gPlayer2.SetColor(gPlayer2Settings.Color);
+        if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer2.UID);
+      end;
+    end;
   end
-  else if gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT] then
+  else if cmd = 'p1_model' then
   begin
-    if cmd = 'r_showscore' then
+    if (Length(P) > 1) then
     begin
-      if (Length(P) > 1) and
-         ((P[1] = '1') or (P[1] = '0')) then
-        gShowGoals := (P[1][1] = '1');
-
-      if gShowGoals then
-        g_Console_Add(_lc[I_MSG_SCORE_ON])
-      else
-        g_Console_Add(_lc[I_MSG_SCORE_OFF]);
-    end
-    else if cmd = 'r_showstat' then
+      gPlayer1Settings.Model := P[1];
+      if g_Game_IsClient then
+        MC_SEND_PlayerSettings
+      else if gGameOn and (gPlayer1 <> nil) then
+      begin
+        gPlayer1.FActualModelName := gPlayer1Settings.Model;
+        gPlayer1.SetModel(gPlayer1Settings.Model);
+        if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer1.UID);
+      end;
+    end;
+  end
+  else if cmd = 'p2_model' then
+  begin
+    if (Length(P) > 1) then
     begin
-      if (Length(P) > 1) and
-         ((P[1] = '1') or (P[1] = '0')) then
-        gShowStat := (P[1][1] = '1');
+      gPlayer2Settings.Model := P[1];
+      if g_Game_IsClient then
+        MC_SEND_PlayerSettings
+      else if gGameOn and (gPlayer2 <> nil) then
+      begin
+        gPlayer2.FActualModelName := gPlayer2Settings.Model;
+        gPlayer2.SetModel(gPlayer2Settings.Model);
+        if g_Game_IsNet then MH_SEND_PlayerSettings(gPlayer2.UID);
+      end;
+    end;
+  end
+  else if cmd = 'r_showscore' then
+  begin
+    if (Length(P) > 1) and
+       ((P[1] = '1') or (P[1] = '0')) then
+      gShowGoals := (P[1][1] = '1');
 
-      if gShowStat then
-        g_Console_Add(_lc[I_MSG_STATS_ON])
-      else
-        g_Console_Add(_lc[I_MSG_STATS_OFF]);
-    end
-    else if cmd = 'r_showkillmsg' then
-    begin
-      if (Length(P) > 1) and
-         ((P[1] = '1') or (P[1] = '0')) then
-        gShowKillMsg := (P[1][1] = '1');
+    if gShowGoals then
+      g_Console_Add(_lc[I_MSG_SCORE_ON])
+    else
+      g_Console_Add(_lc[I_MSG_SCORE_OFF]);
+  end
+  else if cmd = 'r_showstat' then
+  begin
+    if (Length(P) > 1) and
+       ((P[1] = '1') or (P[1] = '0')) then
+      gShowStat := (P[1][1] = '1');
 
-      if gShowKillMsg then
-        g_Console_Add(_lc[I_MSG_KILL_MSGS_ON])
-      else
-        g_Console_Add(_lc[I_MSG_KILL_MSGS_OFF]);
-    end
-    else if cmd = 'r_showlives' then
-    begin
-      if (Length(P) > 1) and
-         ((P[1] = '1') or (P[1] = '0')) then
-        gShowLives := (P[1][1] = '1');
+    if gShowStat then
+      g_Console_Add(_lc[I_MSG_STATS_ON])
+    else
+      g_Console_Add(_lc[I_MSG_STATS_OFF]);
+  end
+  else if cmd = 'r_showkillmsg' then
+  begin
+    if (Length(P) > 1) and
+       ((P[1] = '1') or (P[1] = '0')) then
+      gShowKillMsg := (P[1][1] = '1');
 
-      if gShowLives then
-        g_Console_Add(_lc[I_MSG_LIVES_ON])
-      else
-        g_Console_Add(_lc[I_MSG_LIVES_OFF]);
-    end
-    else if cmd = 'r_showspect' then
-    begin
-      if (Length(P) > 1) and
-         ((P[1] = '1') or (P[1] = '0')) then
-        gSpectHUD := (P[1][1] = '1');
+    if gShowKillMsg then
+      g_Console_Add(_lc[I_MSG_KILL_MSGS_ON])
+    else
+      g_Console_Add(_lc[I_MSG_KILL_MSGS_OFF]);
+  end
+  else if cmd = 'r_showlives' then
+  begin
+    if (Length(P) > 1) and
+       ((P[1] = '1') or (P[1] = '0')) then
+      gShowLives := (P[1][1] = '1');
 
-      if gSpectHUD then
-        g_Console_Add(_lc[I_MSG_SPECT_HUD_ON])
-      else
-        g_Console_Add(_lc[I_MSG_SPECT_HUD_OFF]);
-    end
-    else if cmd = 'r_showping' then
-    begin
-      if (Length(P) > 1) and
-         ((P[1] = '1') or (P[1] = '0')) then
-        gShowPing := (P[1][1] = '1');
+    if gShowLives then
+      g_Console_Add(_lc[I_MSG_LIVES_ON])
+    else
+      g_Console_Add(_lc[I_MSG_LIVES_OFF]);
+  end
+  else if cmd = 'r_showspect' then
+  begin
+    if (Length(P) > 1) and
+       ((P[1] = '1') or (P[1] = '0')) then
+      gSpectHUD := (P[1][1] = '1');
 
-      if gShowPing then
-        g_Console_Add(_lc[I_MSG_PING_ON])
-      else
-        g_Console_Add(_lc[I_MSG_PING_OFF]);
-    end
-    else if (cmd = 'g_scorelimit') and not g_Game_IsClient then
-    begin
-      if Length(P) > 1 then
-      begin
-        if StrToIntDef(P[1], gGameSettings.GoalLimit) = 0 then
-          gGameSettings.GoalLimit := 0
-        else
-          begin
-            b := 0;
-
-            if gGameSettings.GameMode = GM_DM then
-              begin // DM
-                stat := g_Player_GetStats();
-                if stat <> nil then
-                  for a := 0 to High(stat) do
-                    if stat[a].Frags > b then
-                      b := stat[a].Frags;
-              end
-            else // TDM/CTF
-              b := Max(gTeamStat[TEAM_RED].Goals, gTeamStat[TEAM_BLUE].Goals);
+    if gSpectHUD then
+      g_Console_Add(_lc[I_MSG_SPECT_HUD_ON])
+    else
+      g_Console_Add(_lc[I_MSG_SPECT_HUD_OFF]);
+  end
+  else if cmd = 'r_showping' then
+  begin
+    if (Length(P) > 1) and
+       ((P[1] = '1') or (P[1] = '0')) then
+      gShowPing := (P[1][1] = '1');
 
-            gGameSettings.GoalLimit := Max(StrToIntDef(P[1], gGameSettings.GoalLimit), b);
-          end;
+    if gShowPing then
+      g_Console_Add(_lc[I_MSG_PING_ON])
+    else
+      g_Console_Add(_lc[I_MSG_PING_OFF]);
+  end
+  else if (cmd = 'g_scorelimit') and not g_Game_IsClient then
+  begin
+    if Length(P) > 1 then
+    begin
+      if StrToIntDef(P[1], gGameSettings.GoalLimit) = 0 then
+        gGameSettings.GoalLimit := 0
+      else
+        begin
+          b := 0;
 
-        if g_Game_IsNet then MH_SEND_GameSettings;
-      end;
+          if gGameSettings.GameMode = GM_DM then
+            begin // DM
+              stat := g_Player_GetStats();
+              if stat <> nil then
+                for a := 0 to High(stat) do
+                  if stat[a].Frags > b then
+                    b := stat[a].Frags;
+            end
+          else // TDM/CTF
+            b := Max(gTeamStat[TEAM_RED].Goals, gTeamStat[TEAM_BLUE].Goals);
 
-      g_Console_Add(Format(_lc[I_MSG_SCORE_LIMIT], [gGameSettings.GoalLimit]));
-    end
-    else if (cmd = 'g_timelimit') and not g_Game_IsClient then
-    begin
-      if (Length(P) > 1) and (StrToIntDef(P[1], -1) >= 0) then
-        gGameSettings.TimeLimit := StrToIntDef(P[1], -1);
+          gGameSettings.GoalLimit := Max(StrToIntDef(P[1], gGameSettings.GoalLimit), b);
+        end;
 
-      g_Console_Add(Format(_lc[I_MSG_TIME_LIMIT],
-                           [gGameSettings.TimeLimit div 3600,
-                           (gGameSettings.TimeLimit div 60) mod 60,
-                            gGameSettings.TimeLimit mod 60]));
       if g_Game_IsNet then MH_SEND_GameSettings;
-    end
-    else if (cmd = 'g_maxlives') and not g_Game_IsClient then
+    end;
+
+    g_Console_Add(Format(_lc[I_MSG_SCORE_LIMIT], [gGameSettings.GoalLimit]));
+  end
+  else if (cmd = 'g_timelimit') and not g_Game_IsClient then
+  begin
+    if (Length(P) > 1) and (StrToIntDef(P[1], -1) >= 0) then
+      gGameSettings.TimeLimit := StrToIntDef(P[1], -1);
+
+    g_Console_Add(Format(_lc[I_MSG_TIME_LIMIT],
+                         [gGameSettings.TimeLimit div 3600,
+                         (gGameSettings.TimeLimit div 60) mod 60,
+                          gGameSettings.TimeLimit mod 60]));
+    if g_Game_IsNet then MH_SEND_GameSettings;
+  end
+  else if (cmd = 'g_maxlives') and not g_Game_IsClient then
+  begin
+    if Length(P) > 1 then
     begin
-      if Length(P) > 1 then
+      if StrToIntDef(P[1], gGameSettings.MaxLives) = 0 then
+        gGameSettings.MaxLives := 0
+      else
       begin
-        if StrToIntDef(P[1], gGameSettings.MaxLives) = 0 then
-          gGameSettings.MaxLives := 0
-        else
-        begin
-          b := 0;
-          stat := g_Player_GetStats();
-          if stat <> nil then
-            for a := 0 to High(stat) do
-              if stat[a].Lives > b then
-                b := stat[a].Lives;
-          gGameSettings.MaxLives :=
-            Max(StrToIntDef(P[1], gGameSettings.MaxLives), b);
-        end;
+        b := 0;
+        stat := g_Player_GetStats();
+        if stat <> nil then
+          for a := 0 to High(stat) do
+            if stat[a].Lives > b then
+              b := stat[a].Lives;
+        gGameSettings.MaxLives :=
+          Max(StrToIntDef(P[1], gGameSettings.MaxLives), b);
       end;
-
-      g_Console_Add(Format(_lc[I_MSG_LIVES],
-                           [gGameSettings.MaxLives]));
-      if g_Game_IsNet then MH_SEND_GameSettings;
     end;
+
+    g_Console_Add(Format(_lc[I_MSG_LIVES],
+                         [gGameSettings.MaxLives]));
+    if g_Game_IsNet then MH_SEND_GameSettings;
   end;
 end;
 
@@ -5973,7 +5928,7 @@ begin
     if cmd = 'd_window' then
     begin
       g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
-      g_Console_Add(Format('gWinSizeX = %d, gWinSizeY = %d', [gWinSizeX, gWinSizeY]));
+      g_Console_Add(Format('gScreenWidth = %d, gScreenHeight = %d', [gScreenWidth, gScreenHeight]));
     end
     else if cmd = 'd_sounds' then
     begin
@@ -8182,6 +8137,7 @@ begin
   conRegVar('dbg_ignore_level_bounds', @g_dbg_ignore_bounds, 'ignore level bounds', '',  false);
 
   conRegVar('r_scale', @g_dbg_scale, 0.01, 100.0, 'render scale', '',  false);
+  conRegVar('r_resolution_scale', @r_pixel_scale, 0.01, 100.0, 'upscale factor', '', false);
 
   conRegVar('light_enabled', @gwin_k8_enable_light_experiments, 'enable/disable dynamic lighting', 'lighting');
   conRegVar('light_player_halo', @g_playerLight, 'enable/disable player halo', 'player light halo');