Minor bug fixes.

This commit is contained in:
2026-09-06 20:08:23 -04:00
parent ebcfd9cd39
commit 6e88a9e9e2
24 changed files with 126 additions and 43 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 B

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 233 B

View File

@@ -17,6 +17,7 @@ public class Game1 : Game
SpriteBatch _sb = null!;
SpriteFont _font12 = null!;
SpriteFont _font20 = null!;
RenderTarget2D _virtualScreen = null!; // fixed 800x600 scene, stretched to the window
bool _paused;
string _enteredName = "";
@@ -44,6 +45,18 @@ public class Game1 : Game
IsFixedTimeStep = true;
TargetElapsedTime = TimeSpan.FromSeconds(1 / 120.0);
Window.Title = "Freedom Fighter";
Window.AllowUserResizing = true;
Window.ClientSizeChanged += (_, _) =>
{
int w = Window.ClientBounds.Width, h = Window.ClientBounds.Height;
if (w > 0 && h > 0 &&
(w != _graphics.PreferredBackBufferWidth || h != _graphics.PreferredBackBufferHeight))
{
_graphics.PreferredBackBufferWidth = w;
_graphics.PreferredBackBufferHeight = h;
_graphics.ApplyChanges();
}
};
}
protected override void LoadContent()
@@ -51,6 +64,13 @@ public class Game1 : Game
_sb = new SpriteBatch(GraphicsDevice);
_font12 = Content.Load<SpriteFont>("Verdana12");
_font20 = Content.Load<SpriteFont>("Verdana20");
_virtualScreen = new RenderTarget2D(GraphicsDevice, G.ScreenWidth, G.ScreenHeight);
// the Delphi form's Width/Height were the OUTER window size (800x600, sizeable border);
// as a DPI-unaware app it was also stretched by Windows, so scale by the current DPI
if (System.Windows.Forms.Control.FromHandle(Window.Handle) is System.Windows.Forms.Form form)
form.Size = new System.Drawing.Size(
G.ScreenWidth * form.DeviceDpi / 96, G.ScreenHeight * form.DeviceDpi / 96);
string contentDir = Path.Combine(AppContext.BaseDirectory, "Content");
@@ -109,36 +129,45 @@ public class Game1 : Game
if (G.Input.PauseClicked)
_paused = !_paused;
if (_paused)
if (!_paused)
{
base.Draw(gameTime);
return;
GraphicsDevice.SetRenderTarget(_virtualScreen);
GraphicsDevice.Clear(Color.Black);
_sb.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp);
G.Sprites.Move(0);
switch (G.State)
{
case GameState.Intro: DoIntro(); break;
case GameState.Idle: DrawMenu(); break;
case GameState.Intermission: DoIntermission(); break;
case GameState.Playing: GameLoop(); break;
case GameState.Stats: DoStats(); break;
case GameState.Shop: DoShop(); break;
case GameState.GameOver: DoGameOver(); break;
case GameState.Credits: DoCredits(); break;
case GameState.HighScore: DoHighScore(); break;
case GameState.EnterName: DoEnterName(); break;
}
G.Sprites.Collision();
G.Sprites.RemoveDead();
G.Sprites.Draw(_sb);
_sb.End();
GraphicsDevice.SetRenderTarget(null);
}
// stretch the 800x600 scene to the window, as DirectX presentation did
GraphicsDevice.Clear(Color.Black);
_sb.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp);
G.Sprites.Move(0);
switch (G.State)
{
case GameState.Intro: DoIntro(); break;
case GameState.Idle: DrawMenu(); break;
case GameState.Intermission: DoIntermission(); break;
case GameState.Playing: GameLoop(); break;
case GameState.Stats: DoStats(); break;
case GameState.Shop: DoShop(); break;
case GameState.GameOver: DoGameOver(); break;
case GameState.Credits: DoCredits(); break;
case GameState.HighScore: DoHighScore(); break;
case GameState.EnterName: DoEnterName(); break;
}
G.Sprites.Collision();
G.Sprites.RemoveDead();
G.Sprites.Draw(_sb);
_sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.LinearClamp);
_sb.Draw(_virtualScreen, new Rectangle(0, 0,
GraphicsDevice.PresentationParameters.BackBufferWidth,
GraphicsDevice.PresentationParameters.BackBufferHeight), Color.White);
_sb.End();
base.Draw(gameTime);
if (ShotFile != null && --ShotFrames <= 0)
@@ -151,14 +180,9 @@ public class Game1 : Game
void SaveScreenshot(string file)
{
int w = GraphicsDevice.PresentationParameters.BackBufferWidth;
int h = GraphicsDevice.PresentationParameters.BackBufferHeight;
var data = new Color[w * h];
GraphicsDevice.GetBackBufferData(data);
using var tex = new Texture2D(GraphicsDevice, w, h);
tex.SetData(data);
// capture the virtual screen so debug shots are always 800x600
using var fs = File.Create(file);
tex.SaveAsPng(fs, w, h);
_virtualScreen.SaveAsPng(fs, _virtualScreen.Width, _virtualScreen.Height);
}
// ================================================================ helpers

View File

@@ -64,8 +64,10 @@ public class OmegaImage
}
/// <summary>
/// Full Omega draw. X,Y is the top-left of the pattern; rotation (degrees, clockwise)
/// pivots around (centerX, centerY) as a fraction of the pattern size.
/// Full Omega draw. X,Y is the top-left of the unscaled pattern; rotation and scale
/// are applied around the pivot (centerX, centerY), which stays at its unscaled
/// position — matching DirectX-era Draw semantics (a half-scaled 64px sprite at X
/// with center 0.5 still has its pivot at X+32).
/// </summary>
public void Draw(SpriteBatch sb, float x, float y, float rotation = 0,
float centerX = 0, float centerY = 0, float scaleX = 1, float scaleY = 1,
@@ -73,7 +75,7 @@ public class OmegaImage
{
var src = PatternRect(pattern);
var origin = new Vector2(centerX * TileWidth, centerY * TileHeight);
var pos = new Vector2(x + origin.X * scaleX, y + origin.Y * scaleY);
var pos = new Vector2(x + origin.X, y + origin.Y);
var color = new Color(red, green, blue, alpha);
sb.Draw(Texture, pos, src, color, MathHelper.ToRadians(rotation), origin,
new Vector2(scaleX, scaleY), SpriteEffects.None, 0);

View File

@@ -112,8 +112,9 @@ public class SpriteManager
public void Draw(SpriteBatch sb)
{
int n = Items.Count;
for (int i = 0; i < n; i++)
// Omega drew newest sprites first, so earlier-created sprites appear on top
// (e.g. the missile turret gun is spawned before its base and must cover it)
for (int i = Items.Count - 1; i >= 0; i--)
if (!Items[i].IsDead)
Items[i].Draw(sb);
}