Skip to content

Commit bd4a139

Browse files
author
LoneWandererProductions
committed
sync back fixes
1 parent 1f8f22d commit bd4a139

8 files changed

Lines changed: 68 additions & 33 deletions

File tree

Imaging/ImageStreamMedia.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ internal static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
149149
var width = bitmap.Width;
150150
var height = bitmap.Height;
151151

152-
// 1. Memory Copy to WriteableBitmap (Your efficient logic)
152+
// 1. Direct Memory Copy to WriteableBitmap (Your efficient pointer logic)
153153
var wbmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
154154
var rect = new Rectangle(0, 0, width, height);
155155
var bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly,
@@ -169,20 +169,21 @@ internal static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
169169
var bitmapImage = new BitmapImage();
170170
using (var stream = new MemoryStream())
171171
{
172-
// BMP Encoder is leaner and faster than PNG for internal memory swaps
173-
var encoder = new BmpBitmapEncoder();
172+
// THE GRIP: Changed from BmpBitmapEncoder to PngBitmapEncoder.
173+
// PNG natively handles Bgra32 transparency channels without dropping pixel arrays.
174+
var encoder = new PngBitmapEncoder();
174175
encoder.Frames.Add(BitmapFrame.Create(wbmp));
175176
encoder.Save(stream);
176177
stream.Position = 0;
177178

178179
bitmapImage.BeginInit();
179180
bitmapImage.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
180-
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
181+
bitmapImage.CacheOption = BitmapCacheOption.OnLoad; // Forces synchronous load before stream closure
181182
bitmapImage.StreamSource = stream;
182183
bitmapImage.EndInit();
183184
}
184185

185-
bitmapImage.Freeze();
186+
bitmapImage.Freeze(); // Detach thread affinity for safe UI thread rendering
186187
return bitmapImage;
187188
}
188189

Solaris/Aurora.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,4 @@ private void Touch_MouseDown(object sender, MouseButtonEventArgs e)
488488

489489
#endregion
490490
}
491-
}
491+
}

Solaris/Box.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,4 @@ public override int GetHashCode()
7070
return HashCode.Combine(X, Y, Layer);
7171
}
7272
}
73-
}
73+
}

Solaris/Helper.cs

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
* PROGRAMMER: Peter Geinitz (Wayfarer)
77
*/
88

9+
using ExtendedSystemObjects;
10+
using Imaging;
11+
using System;
912
using System.Collections.Concurrent;
1013
using System.Collections.Generic;
1114
using System.Drawing;
1215
using System.Linq;
1316
using System.Threading.Tasks;
1417
using System.Windows.Media;
15-
using ExtendedSystemObjects;
16-
using Imaging;
1718
using Brushes = System.Drawing.Brushes;
1819

1920
namespace Solaris
@@ -46,48 +47,83 @@ internal static Bitmap GenerateImage(
4647
{
4748
var background = new Bitmap(width * textureSize, height * textureSize);
4849

49-
if (map == null)
50+
if (map == null || textures == null)
5051
{
5152
return background;
5253
}
5354

54-
// Using ConcurrentBag removes the need for thread blocking (locking)
55+
// 1. Safe Sequential Cache Hydration Pass (File I/O)
56+
foreach (var texture in textures.Values)
57+
{
58+
if (string.IsNullOrWhiteSpace(texture.Path)) continue;
59+
60+
if (!ImageCache.ContainsKey(texture.Path))
61+
{
62+
try
63+
{
64+
var loadedBmp = Render.GetBitmapFile(texture.Path);
65+
if (loadedBmp != null)
66+
{
67+
ImageCache[texture.Path] = loadedBmp;
68+
}
69+
}
70+
catch (Exception ex)
71+
{
72+
System.Diagnostics.Trace.WriteLine($"[CRITICAL] Failed to decode asset {texture.Path}: {ex.Message}");
73+
}
74+
}
75+
}
76+
77+
// 2. High-Speed Memory Map Translation Pass
5578
var tiles = new ConcurrentBag<Box>();
5679

5780
Parallel.ForEach(map, tile =>
5881
{
5982
if (tile.Value is not { Count: > 0 }) return;
6083

61-
var x = tile.Key % width * textureSize;
62-
var y = tile.Key / width * textureSize;
84+
var x = (tile.Key % width) * textureSize;
85+
var y = (tile.Key / width) * textureSize;
6386

6487
foreach (var textureId in tile.Value)
6588
{
66-
var texture = textures[textureId];
67-
var image = ImageCache.GetOrAdd(texture.Path, path => Render.GetBitmapFile(path));
68-
tiles.Add(new Box { X = x, Y = y, Layer = texture.Layer, Image = image });
89+
if (!textures.TryGetValue(textureId, out var texture)) continue;
90+
91+
if (ImageCache.TryGetValue(texture.Path, out var cachedImage))
92+
{
93+
tiles.Add(new Box { X = x, Y = y, Layer = texture.Layer, Image = cachedImage });
94+
}
6995
}
7096
});
7197

72-
// Convert to a list to sort by layer (so top layers render last)
7398
var sortedTiles = tiles.ToList();
7499
sortedTiles.Sort((a, b) => a.Layer.CompareTo(b.Layer));
75100

76-
foreach (var slice in sortedTiles)
101+
// 3. THE GRAPHICS FIX: Open the graphics envelope ONCE for the whole map sheet
102+
using (var graph = Graphics.FromImage(background))
77103
{
78-
Render.CombineBitmap(background, slice.Image, slice.X, slice.Y);
79-
}
104+
// Optional: Ensure a clean alpha base line across the canvas space
105+
graph.Clear(System.Drawing.Color.Transparent);
106+
107+
// Blit all 100 tiles rapidly into the open graphics pipeline context
108+
foreach (var slice in sortedTiles)
109+
{
110+
if (slice.Image != null)
111+
{
112+
graph.DrawImage(slice.Image,
113+
new Rectangle(slice.X, slice.Y, slice.Image.Width, slice.Image.Height));
114+
}
115+
}
116+
} // GDI+ flushes all operations to system memory and closes cleanly here ONCE
80117

81118
return background;
82119
}
83-
84120
/// <summary>
85121
/// Generates a grid overlay.
86122
/// </summary>
87123
/// <param name="width">The width.</param>
88124
/// <param name="height">The height.</param>
89125
/// <param name="textureSize">Size of the texture.</param>
90-
/// <returns></returns>
126+
/// <returns>ImageSource representing the grid overlay.</returns>
91127
internal static ImageSource GenerateGrid(int width, int height, int textureSize)
92128
{
93129
using var bitmap = new Bitmap(width * textureSize, height * textureSize);
@@ -109,7 +145,7 @@ internal static ImageSource GenerateGrid(int width, int height, int textureSize)
109145
/// <param name="height">The height.</param>
110146
/// <param name="textureSize">Size of the texture.</param>
111147
/// <param name="padding">The padding.</param>
112-
/// <returns></returns>
148+
/// <returns>ImageSource representing the number overlay.</returns>
113149
internal static ImageSource GenerateNumbers(int width, int height, int textureSize, int padding = 2)
114150
{
115151
using var bitmap = new Bitmap(width * textureSize, height * textureSize);
@@ -139,7 +175,7 @@ internal static ImageSource GenerateNumbers(int width, int height, int textureSi
139175
/// </summary>
140176
/// <param name="map">The map.</param>
141177
/// <param name="idTexture">The identifier texture.</param>
142-
/// <returns></returns>
178+
/// <returns>MapChangeResult representing the result of the operation.</returns>
143179
internal static MapChangeResult AddTile(
144180
Dictionary<int, List<int>>? map, KeyValuePair<int, int> idTexture)
145181
{
@@ -155,7 +191,7 @@ internal static MapChangeResult AddTile(
155191
/// <param name="map">The map.</param>
156192
/// <param name="textures">The textures.</param>
157193
/// <param name="idLayer">The identifier layer.</param>
158-
/// <returns></returns>
194+
/// <returns>MapChangeResult representing the result of the operation.</returns>
159195
internal static MapChangeResult RemoveTile(
160196
Dictionary<int, List<int>>? map, Dictionary<int, Texture> textures, KeyValuePair<int, int> idLayer)
161197
{
@@ -194,7 +230,7 @@ internal static MapChangeResult RemoveTile(
194230
/// <param name="layer">The layer.</param>
195231
/// <param name="idTile">The identifier tile.</param>
196232
/// <returns>Image on screen</returns>
197-
public static Bitmap? AddDisplay(
233+
public static Bitmap AddDisplay(
198234
int width, int textureSize, Dictionary<int, Texture> textures, Bitmap? layer,
199235
KeyValuePair<int, int> idTile)
200236
{
@@ -231,7 +267,7 @@ public static Bitmap RemoveDisplay(int width, int textureSize, Bitmap? layer, in
231267
/// <param name="width">The width.</param>
232268
/// <param name="height">The height.</param>
233269
/// <param name="textureSize">Size of the texture.</param>
234-
/// <returns>Movement animation</returns>
270+
/// <returns>Task representing the asynchronous operation.</returns>
235271
internal static async Task DisplayMovement(Aurora aurora, IEnumerable<int> steps, Bitmap? avatar,
236272
int width, int height, int textureSize)
237273
{

Solaris/MapChangeResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ namespace Solaris
1515
/// Return type for map manipulation methods.
1616
/// </summary>
1717
internal readonly record struct MapChangeResult(bool Changed, Dictionary<int, List<int>>? Map);
18-
}
18+
}

Solaris/Polaris.xaml.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ private void Touch_MouseDown(object sender, MouseButtonEventArgs e)
434434
{
435435
var position = e.GetPosition(Touch);
436436

437-
// 1. Calculate the values first.
438-
// Integer division naturally handles the 0 case for us!
439437
var gridX = (int)position.X / PolarisTextureSize;
440438
var gridY = (int)position.Y / PolarisTextureSize;
441439

@@ -447,4 +445,4 @@ private void Touch_MouseDown(object sender, MouseButtonEventArgs e)
447445

448446
#endregion
449447
}
450-
}
448+
}

Solaris/Resources.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ internal static class Resources
3030
/// </summary>
3131
internal const string Font = "Tahoma";
3232
}
33-
}
33+
}

Solaris/Texture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ public sealed class Texture
4343
/// </value>
4444
public int Id { get; init; }
4545
}
46-
}
46+
}

0 commit comments

Comments
 (0)