Continued testing

Items now render without error in the map view, and repositioning the view works.
This commit is contained in:
Kurt
2026-01-25 11:53:10 -06:00
parent db2a242d8e
commit 0a80175810
5 changed files with 81 additions and 56 deletions

View File

@@ -97,4 +97,24 @@ public bool IsCoordinateValidAbsolute(int absX, int absY)
var (relX, relY) = GetCoordinatesRelative(absX, absY);
return IsCoordinateValidRelative(relX, relY);
}
/// <summary>
/// Layer total width in tiles.
/// </summary>
public int LayerTotalWidth => CountWidth * TilesPerAcre;
/// <summary>
/// Layer total height in tiles.
/// </summary>
public int LayerTotalHeight => CountHeight * TilesPerAcre;
/// <summary>
/// Gets the total width of the map, in tiles.
/// </summary>
public int MapTotalWidth => MapAcreWidth * TilesPerAcre;
/// <summary>
/// Gets the total height of the map, in tiles.
/// </summary>
public int MapTotalHeight => MapAcreHeight * TilesPerAcre;
}

View File

@@ -21,25 +21,26 @@ public static class ItemLayerSprite
/// <param name="items">List of items from which color values are extracted. The span must contain at least width × height elements.</param>
/// <param name="bmpData">Pixel data for the bitmap. The span must have a length of at least width × height.</param>
/// <param name="cfg">Configuration for layer positioning.</param>
/// <param name="imgWidth">The number of columns in the bitmap. Must be greater than zero.</param>
/// <param name="imgHeight">The number of rows in the bitmap. Must be greater than zero.</param>
private static void LoadBitmapLayer(ReadOnlySpan<Item> items, Span<int> bmpData, in LayerPositionConfig cfg, int imgWidth, int imgHeight)
private static void LoadBitmapLayer(ReadOnlySpan<Item> items, Span<int> bmpData, in LayerPositionConfig cfg)
{
var (shiftX, shiftY) = cfg.GetCoordinatesAbsolute(0, 0);
// Iterate through the relative positions within the layer.
// Then, map to absolute positions in the bitmap with the configured shift.
for (int x = 0; x < imgWidth; x++)
var width = cfg.LayerTotalWidth;
var height = cfg.LayerTotalHeight;
var mapWidth = cfg.MapTotalWidth; // 1px scale
for (int relX = 0; relX < width; relX++)
{
var ix = x * imgHeight;
for (int y = 0; y < imgHeight; y++)
var absX = relX + shiftX;
for (int relY = 0; relY < height; relY++)
{
// Get the tile at this position.
var index = ix + y;
var tile = items[index];
var tile = items[relY + relX * height];
// Get the actual shifted position in the bitmap.
var offset = ((y + shiftY) * imgWidth) + (x + shiftX);
var absY = relY + shiftY;
var offset = (absY * mapWidth) + absX;
// Write the color to the bitmap data.
bmpData[offset] = FieldItemColor.GetItemColor(tile).ToArgb();
@@ -104,10 +105,10 @@ private static void LoadViewport(LayerItem layer, in LayerPositionConfig cfg, Sp
for (int y = 0; y < height; y++)
{
var baseIndex = (y * width);
var tileY = relY + y;
for (int x = 0; x < width; x++)
{
var tileX = relX + x;
var tileY = relY + y;
if (!cfg.IsCoordinateValidRelative(tileX, tileY))
continue;
var tile = layer.GetTile(tileX, tileY);
@@ -133,8 +134,8 @@ private static void LoadViewport(LayerItem layer, in LayerPositionConfig cfg, Sp
Span<int> data,
int absX, int absY, int imgWidth, int imgScale)
{
var width = layer.TileInfo.ViewWidth;
var height = layer.TileInfo.ViewHeight;
var width = cfg.TilesPerAcre;
var height = cfg.TilesPerAcre;
var (relX, relY) = cfg.GetCoordinatesRelative(absX, absY);
@@ -381,15 +382,15 @@ public static void DrawGrid(Span<int> data, int imgWidth, int imgHeight, int gri
}
/// <summary>
/// Loads an item layer into a viewport bitmap, drawing a view reticle over it.
/// Loads an item layer into a viewport bitmap.
/// </summary>
/// <param name="cfg">Configuration for layer positioning.</param>
/// <param name="layer">Item layer to draw from.</param>
/// <param name="data">Pixel data of the final image.</param>
/// <param name="transparency">Optional transparency override color.</param>
public static void LoadItemLayerDrawReticle(LayerPositionConfig cfg, LayerItem layer, Span<int> data, int transparency = -1)
public static void LoadItemLayer1(LayerPositionConfig cfg, LayerItem layer, Span<int> data, int transparency = -1)
{
LoadBitmapLayer(layer.Tiles, data, cfg, layer.TileInfo.TotalWidth, layer.TileInfo.TotalHeight);
LoadBitmapLayer(layer.Tiles, data, cfg);
if (transparency >>> 24 != 0xFF)
ImageUtil.ClampAllTransparencyTo(data, transparency);
}

View File

@@ -53,23 +53,27 @@ public MapRenderer(MapEditor m)
Map = m;
// Initialize cached objects based on map size
// Get tile info from layer 0 (item layer is the tiniest cell we can render)
var l1 = m.Mutator.Manager.FieldItems.Layer0;
var info = l1.TileInfo;
MapItemsReticleX = new int[info.TotalWidth * info.TotalHeight * MapScale * MapScale];
MapItemsReticleImage = new Bitmap(info.TotalWidth * MapScale, info.TotalHeight * MapScale);
// Get tile info from item layer, it's the tiniest cell we can render
var cfg = m.Mutator.Manager.ConfigItems;
var mapW = cfg.MapTotalWidth * MapScale;
var mapH = cfg.MapTotalHeight * MapScale;
MapItemsReticleImage = new Bitmap(mapW, mapH);
MapItemsReticleX = new int[mapW * mapH];
MapTerrain1 = new int[MapItemsReticleX.Length / (MapScale * MapScale)];
MapTerrainX = new int[MapItemsReticleX.Length];
MapTerrainImage = new Bitmap(MapItemsReticleImage.Width, MapItemsReticleImage.Height);
ViewportItems1 = new int[info.ViewWidth * info.ViewHeight];
// Render a single acre viewport
var tpa = cfg.TilesPerAcre;
ViewportItems1 = new int[tpa * tpa];
ViewportItemsX = new int[ViewportItems1.Length * ViewScale * ViewScale];
ViewportItemsImage = new Bitmap(info.ViewWidth * ViewScale, info.ViewHeight * ViewScale);
ViewportItemsImage = new Bitmap(tpa * ViewScale, tpa * ViewScale);
ViewportTerrain1 = new int[16*16 * 16*16]; // each terrain tile is drawn as 16px, then we upscale
ViewportTerrainX = new int[ViewportItemsX.Length]; // 2x upscale
const byte pixelsPerTerrainTile = 16;
var dimTerrain = cfg.TilesPerAcre * pixelsPerTerrainTile;
ViewportTerrain1 = new int[dimTerrain * dimTerrain]; // each terrain tile is drawn as 16px, then we upscale
ViewportTerrainX = new int[ViewportItemsX.Length]; // 2x upscale (16px -> 32px)
ViewportTerrainImage = new Bitmap(ViewportItemsImage.Width, ViewportItemsImage.Height);
}
@@ -123,7 +127,7 @@ public Bitmap UpdateViewportTerrain(Font f, byte transparencyBuilding, byte tran
private Bitmap UpdateMapItemsReticle(LayerFieldItem layer, int absX, int absY, int transparency, bool drawReticle = true)
{
var cfg = Map.Mutator.Manager.ConfigItems;
ItemLayerSprite.LoadItemLayerDrawReticle(cfg, layer, MapItemsReticleX, transparency);
ItemLayerSprite.LoadItemLayer1(cfg, layer, MapItemsReticleX, transparency);
MapItemsReticleImage.SetBitmapData(MapItemsReticleX);
if (drawReticle)
ItemLayerSprite.DrawViewReticle(MapItemsReticleImage, layer.TileInfo, absX, absY);

View File

@@ -48,7 +48,7 @@ private void InitializeComponent()
NUD_Layer = new System.Windows.Forms.NumericUpDown();
L_Layer = new System.Windows.Forms.Label();
TT_Hover = new System.Windows.Forms.ToolTip(components);
PB_Acre = new System.Windows.Forms.PictureBox();
PB_Viewport = new System.Windows.Forms.PictureBox();
TR_Transparency = new System.Windows.Forms.TrackBar();
CHK_NoOverwrite = new System.Windows.Forms.CheckBox();
CHK_AutoExtension = new System.Windows.Forms.CheckBox();
@@ -155,7 +155,7 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)PB_Map).BeginInit();
CM_Picture.SuspendLayout();
((System.ComponentModel.ISupportInitialize)NUD_Layer).BeginInit();
((System.ComponentModel.ISupportInitialize)PB_Acre).BeginInit();
((System.ComponentModel.ISupportInitialize)PB_Viewport).BeginInit();
((System.ComponentModel.ISupportInitialize)TR_Transparency).BeginInit();
CM_Remove.SuspendLayout();
TC_Editor.SuspendLayout();
@@ -384,18 +384,18 @@ private void InitializeComponent()
//
// PB_Acre
//
PB_Acre.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
PB_Acre.ContextMenuStrip = CM_Click;
PB_Acre.Location = new System.Drawing.Point(14, 16);
PB_Acre.Margin = new System.Windows.Forms.Padding(4);
PB_Acre.Name = "PB_Acre";
PB_Acre.Size = new System.Drawing.Size(514, 514);
PB_Acre.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
PB_Acre.TabIndex = 28;
PB_Acre.TabStop = false;
PB_Acre.MouseClick += PB_Acre_MouseClick;
PB_Acre.MouseDown += PB_Acre_MouseDown;
PB_Acre.MouseMove += PB_Acre_MouseMove;
PB_Viewport.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
PB_Viewport.ContextMenuStrip = CM_Click;
PB_Viewport.Location = new System.Drawing.Point(14, 16);
PB_Viewport.Margin = new System.Windows.Forms.Padding(4);
PB_Viewport.Name = "PB_Viewport";
PB_Viewport.Size = new System.Drawing.Size(514, 514);
PB_Viewport.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
PB_Viewport.TabIndex = 28;
PB_Viewport.TabStop = false;
PB_Viewport.MouseClick += ViewportMouseClick;
PB_Viewport.MouseDown += ViewportMouseDown;
PB_Viewport.MouseMove += ViewportMouseMove;
//
// TR_Transparency
//
@@ -1409,7 +1409,7 @@ private void InitializeComponent()
Controls.Add(RB_Terrain);
Controls.Add(RB_Item);
Controls.Add(TC_Editor);
Controls.Add(PB_Acre);
Controls.Add(PB_Viewport);
Controls.Add(L_Layer);
Controls.Add(NUD_Layer);
Controls.Add(L_Coordinates);
@@ -1434,7 +1434,7 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)PB_Map).EndInit();
CM_Picture.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)NUD_Layer).EndInit();
((System.ComponentModel.ISupportInitialize)PB_Acre).EndInit();
((System.ComponentModel.ISupportInitialize)PB_Viewport).EndInit();
((System.ComponentModel.ISupportInitialize)TR_Transparency).EndInit();
CM_Remove.ResumeLayout(false);
TC_Editor.ResumeLayout(false);
@@ -1490,7 +1490,7 @@ private void InitializeComponent()
private System.Windows.Forms.NumericUpDown NUD_Layer;
private System.Windows.Forms.Label L_Layer;
private System.Windows.Forms.ToolTip TT_Hover;
private System.Windows.Forms.PictureBox PB_Acre;
private System.Windows.Forms.PictureBox PB_Viewport;
private System.Windows.Forms.TrackBar TR_Transparency;
private System.Windows.Forms.CheckBox CHK_NoOverwrite;
private System.Windows.Forms.CheckBox CHK_AutoExtension;

View File

@@ -52,10 +52,10 @@ public FieldItemEditor(MainSave sav)
this.TranslateInterface(GameInfo.CurrentLanguage);
// Read the expected scale from the control.
var scale = (PB_Acre.Width - 2) / LayerFieldItem.TilesPerAcreDim; // 1px border
var scale = (PB_Viewport.Width - 2) / LayerFieldItem.TilesPerAcreDim; // 1px border
SAV = sav;
Editor = MapEditor.FromSaveFile(sav);
Editor.MapScale = scale;
Editor.MapScale = 1;
Editor.ViewScale = scale;
Renderer = new MapRenderer(Editor);
@@ -128,7 +128,7 @@ private void ChangeViewToAcre(int acre)
private void LoadItemGridAcre()
{
ReloadItems();
ReloadAcreBackground();
ReloadViewportBackground();
UpdateArrowVisibility();
}
@@ -153,26 +153,26 @@ private void SetMapForegroundImage(Bitmap img)
PB_Map.Image = img;
}
private void ReloadAcreBackground()
private void ReloadViewportBackground()
{
var tbuild = (byte)TR_BuildingTransparency.Value;
var tterrain = (byte)TR_Terrain.Value;
var img = Renderer.UpdateViewportTerrain(L_Coordinates.Font, tbuild, tterrain, SelectedBuildingIndex);
PB_Acre.BackgroundImage = img;
PB_Acre.Invalidate(); // background image reassigning to same img doesn't redraw; force it
PB_Viewport.BackgroundImage = img;
PB_Viewport.Invalidate(); // background image reassigning to same img doesn't redraw; force it
}
private void ReloadAcreItemGrid() => PB_Acre.Image = Renderer.UpdateViewportItems(GetItemTransparency());
private void ReloadViewportItems() => PB_Viewport.Image = Renderer.UpdateViewportItems(GetItemTransparency());
public void ReloadItems()
{
ReloadAcreItemGrid();
ReloadViewportItems();
ReloadMapItemGrid();
}
private void ReloadBuildingsTerrain()
{
ReloadAcreBackground();
ReloadViewportBackground();
ReloadMapBackground();
}
@@ -184,7 +184,7 @@ private void UpdateArrowVisibility()
B_Right.Enabled = View.CanRight;
}
private void PB_Acre_MouseClick(object sender, MouseEventArgs e)
private void ViewportMouseClick(object sender, MouseEventArgs e)
{
if (IsDragOperationActive)
{
@@ -370,9 +370,9 @@ private void UpdateHoveredCoordinates(MouseEventArgs e)
HoverY &= 0x1F;
}
private void PB_Acre_MouseDown(object sender, MouseEventArgs e) => ResetDrag();
private void ViewportMouseDown(object sender, MouseEventArgs e) => ResetDrag();
private void PB_Acre_MouseMove(object sender, MouseEventArgs e)
private void ViewportMouseMove(object sender, MouseEventArgs e)
{
var l = CurrentLayer;
if (e.Button == MouseButtons.Left && CHK_MoveOnDrag.Checked)
@@ -409,7 +409,7 @@ private void PB_Acre_MouseMove(object sender, MouseEventArgs e)
var isActive = flagLayer.GetIsActive(x, y);
if (isActive)
name = $"{name} [Active]";
TT_Hover.SetToolTip(PB_Acre, name);
TT_Hover.SetToolTip(PB_Viewport, name);
SetCoordinateText(x, y);
}