Still super broken

This commit is contained in:
Kurt
2026-01-25 02:44:50 -06:00
parent 4823a45104
commit fa1f5dceeb
5 changed files with 64 additions and 52 deletions

View File

@@ -1,5 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
namespace NHSE.Core;
@@ -66,15 +65,15 @@ namespace NHSE.Core;
public (int X, int Y) GetCoordinatesAbsolute(int relX, int relY)
{
var absX = relX - ((ShiftWidth * MetaTileSize) << TileBitShift);
var absY = relY - ((ShiftHeight * MetaTileSize) << TileBitShift);
var absX = relX + ((ShiftWidth * MetaTileSize) << TileBitShift);
var absY = relY + ((ShiftHeight * MetaTileSize) << TileBitShift);
return (absX, absY);
}
public (int X, int Y) GetCoordinatesRelative(int absX, int absY)
{
var relX = absX + ((ShiftWidth * MetaTileSize) << TileBitShift);
var relY = absY + ((ShiftHeight * MetaTileSize) << TileBitShift);
var relX = absX - ((ShiftWidth * MetaTileSize) << TileBitShift);
var relY = absY - ((ShiftHeight * MetaTileSize) << TileBitShift);
return (relX, relY);
}

View File

@@ -140,25 +140,31 @@ public void SetAllRoad(TerrainTile tile, bool interiorOnly = true)
}
}
public int GetTileColor(int x, int y, int relativeX, int relativeY)
public int GetTileColor(int x, int y, int insideX, int insideY)
{
var acre = GetTileAcre(x, y);
if (acre != 0)
var acre = GetAcreTemplate(x, y);
return GetTileColor(acre, x, y, insideX, insideY);
}
public int GetTileColor(ushort acre, int x, int y, int insideX, int insideY)
{
if (acre != 0) // predefined appearance
{
var c = AcreTileColor.GetAcreTileColor(acre, x % 16, y % 16);
if (c != -0x1000000) // transparent
return c;
}
// dynamic (terrain-based) appearance
var tile = GetTile(x, y);
return TerrainTileColor.GetTileColor(tile, relativeX, relativeY).ToArgb();
return TerrainTileColor.GetTileColor(tile, insideX, insideY).ToArgb();
}
private ushort GetTileAcre(int x, int y)
public ushort GetAcreTemplate(int terrainX, int terrainY)
{
// Acres are 16x16 tiles, and the acre data has a 1-acre deep-sea border around it.
var acreX = 1 + (x / 16);
var acreY = 1 + (y / 16);
var acreX = 1 + (terrainX / 16);
var acreY = 1 + (terrainY / 16);
var acreIndex = ((CountAcreWidth + 2) * acreY) + acreX;
var ofs = acreIndex * 2;

View File

@@ -168,7 +168,7 @@ private static void LoadViewport(LayerItem layer, in LayerPositionConfig cfg, Sp
var geneValue = (genes >> (geneIndex * 2)) & 3;
if (geneValue == 0)
continue;
DrawGene(data, absX * imgScale, absY * imgScale, imgScale, imgWidth, geneValue, geneIndex);
DrawGene(data, viewX * imgScale, viewY * imgScale, imgScale, imgWidth, geneValue, geneIndex);
}
}
}

View File

@@ -68,8 +68,8 @@ public MapRenderer(MapEditor m)
ViewportItemsX = new int[ViewportItems1.Length * ViewScale * ViewScale];
ViewportItemsImage = new Bitmap(info.ViewWidth * ViewScale, info.ViewHeight * ViewScale);
ViewportTerrain1 = new int[ViewportItems1.Length];
ViewportTerrainX = new int[ViewportItemsX.Length];
ViewportTerrain1 = new int[16*16 * 16*16]; // each terrain tile is drawn as 16px, then we upscale
ViewportTerrainX = new int[ViewportItemsX.Length]; // 2x upscale
ViewportTerrainImage = new Bitmap(ViewportItemsImage.Width, ViewportItemsImage.Height);
}

View File

@@ -18,7 +18,12 @@ public static class TerrainSprite
private static readonly Color PlazaColor = Color.RosyBrown;
private static readonly StringFormat BuildingTextFormat = new() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
// 6x5 in a 16x16 acre scale. Since we are in 32x32 scale for items, double.
// 6x5 in a 16x16 acre scale. Since we are in 32x32 scale for items, our upscale is "double".
// Tiles are always rendered as 16x16 squares, to match the precomputed tile appearance bitmaps.
private const int TileScale = 16;
private const int TilesPerViewport = 16;
// To display in a 32x32 viewport from 16x16
private const int Scale = 2;
private const int PlazaWidth = 6 * Scale;
private const int PlazaHeight = 5 * Scale;
@@ -59,9 +64,12 @@ public static void GenerateMap(Bitmap map, MapMutator mut, Span<int> scale1, Spa
int selectedBuildingIndex, byte transparencyBuilding, byte transTerrain)
{
// Convert from absolute to relative.
int mx = m.X / 2;
int my = m.Y / 2;
SetAcreTerrainPixels(m.Terrain, mx, my, scale1, scaleX, m.ViewScale);
var cfg = m.Mutator.Manager.ConfigTerrain;
int absX = m.X / 2; // 32px => 16px basis
int absY = m.Y / 2; // 32px => 16px basis
var (relX, relY) = cfg.GetCoordinatesRelative(absX, absY);
SetViewTerrainPixels(m.Terrain, cfg, relX, relY, scale1, scaleX, Scale);
// Drawing building tiles currently uses the graphics API rather than writing pixels.
img.SetBitmapData(scaleX);
@@ -83,7 +91,6 @@ public static void GenerateMap(Bitmap map, MapMutator mut, Span<int> scale1, Spa
// Draw Text of Building Names
foreach (var b in m.Buildings.Buildings)
{
var type = b.BuildingType;
var (x, y) = m.GetViewCoordinatesBuilding(b.X, b.Y);
const int cellsAbove = 2; // Show label above the building, 2 cells up.
y -= (m.ViewScale * cellsAbove);
@@ -92,14 +99,15 @@ public static void GenerateMap(Bitmap map, MapMutator mut, Span<int> scale1, Spa
if (!m.Mutator.View.IsWithinView(m.ViewScale, x, y))
continue;
var name = b.BuildingType.ToString();
var type = b.BuildingType;
var name = type.ToString();
var labelPosition = new PointF(x, y - (m.ViewScale * 2));
gfx.DrawString(name, f, Text, labelPosition, BuildingTextFormat);
}
// Draw Text of Terrain Tile Names
if (transTerrain != 0)
DrawTerrainTileNames(gfx, f, mx, my, m.Terrain, m.ViewScale, transTerrain);
DrawViewTerrainTileNames(gfx, m.Terrain, cfg, f, absX, absY, m.ViewScale, transTerrain);
// Done.
}
@@ -133,7 +141,7 @@ private static void LoadTerrainPixels(LayerTerrain mgr, Span<int> pixels)
}
}
private static Bitmap DrawReticle(Bitmap map, TileGridViewport mgr, int x, int y, int scale)
private static void DrawReticle(Bitmap map, TileGridViewport mgr, int x, int y, int scale)
{
using var gfx = Graphics.FromImage(map);
using var pen = new Pen(Color.Red);
@@ -141,7 +149,6 @@ private static Bitmap DrawReticle(Bitmap map, TileGridViewport mgr, int x, int y
int w = mgr.ViewWidth * scale;
int h = mgr.ViewHeight * scale;
gfx.DrawRectangle(pen, x * scale, y * scale, w, h);
return map;
}
private static void DrawPlaza(this Graphics gfx, MapEditor map, ushort px, ushort py, int scale)
@@ -187,34 +194,30 @@ private static void DrawBuilding(this Graphics gfx, Building b, MapEditor map, B
gfx.DrawString(name, textFont, textBrush, new PointF(x, y - (imgScale * cellsAbove)), BuildingTextFormat);
}
private static void SetAcreTerrainPixels(LayerTerrain t, int relX, int relY, Span<int> data, Span<int> scaleX, int imgScale)
private static void SetViewTerrainPixels(LayerTerrain t, LayerPositionConfig cfg, int relX, int relY, Span<int> data, Span<int> scaleX, int imgScale)
{
GetAcre1(t, relX, relY, data);
ImageUtil.ScalePixelImage(data, scaleX, TilesPerViewport * imgScale, TilesPerViewport * imgScale, imgScale / TileScale);
GetViewTerrain1(t, cfg, relX, relY, data);
ImageUtil.ScalePixelImage(data, scaleX, TilesPerViewport * imgScale, TilesPerViewport * imgScale, imgScale);
}
// Tiles are always rendered as 16x16 squares, to match the precomputed tile appearance bitmaps.
private const int TileScale = 16;
private const int TilesPerViewport = 16;
private static void GetAcre1(LayerTerrain t, int relX, int relY, Span<int> data)
private static void GetViewTerrain1(LayerTerrain t, LayerPositionConfig cfg, int relX, int relY, Span<int> data)
{
const int viewWidth = 16;
const int viewHeight = 16;
int index = 0;
for (int tileY = 0; tileY < viewHeight; tileY++)
for (int tileY = 0; tileY < TilesPerViewport; tileY++)
{
var tileYIx = tileY + relY;
for (int pixelY = 0; pixelY < viewWidth; pixelY++)
var actY = tileY + relY;
for (int x = 0; x < TilesPerViewport; x++)
{
// Draw the tile row
for (int tileX = 0; tileX < TileScale; tileX++)
var actX = relX + x;
if (!cfg.IsCoordinateValidRelative(actX, actY))
continue;
var acreTemplate = t.GetAcreTemplate(actX, actY);
for (int pixelY = 0; pixelY < TileScale; pixelY++)
{
var tileXIx = tileX + relX;
for (int pixelX = 0; pixelX < TileScale; pixelX++)
{
data[index] = t.GetTileColor(tileXIx, tileYIx, pixelX, pixelY);
data[index] = t.GetTileColor(acreTemplate, actX, actY, pixelX, pixelY);
index++;
}
}
@@ -222,24 +225,28 @@ private static void GetAcre1(LayerTerrain t, int relX, int relY, Span<int> data)
}
}
private static void DrawTerrainTileNames(Graphics gfx, Font f, int topX, int topY, LayerTerrain t, int scale, byte transparency)
private static void DrawViewTerrainTileNames(Graphics gfx, LayerTerrain t, LayerPositionConfig cfg, Font f,
int relX, int relY, int scale, byte transparency)
{
var pen = Tile;
if (transparency != byte.MaxValue)
pen = new SolidBrush(Color.FromArgb(transparency, Color.Black));
for (int y = 0; y < 16; y++)
// iterate over every tile in the view
for (int y = 0; y < TilesPerViewport; y++)
{
var yi = y + topY;
int cy = (y * scale) + (scale / 2);
for (int x = 0; x < 16; x++)
var actY = relY + y;
var centerY = (y * scale) + (scale / 2);
for (int x = 0; x < TilesPerViewport; x++)
{
var xi = x + topX;
var tile = t.GetTile(xi, yi);
var actX = relX + x;
if (!cfg.IsCoordinateValidRelative(actX, actY))
continue;
int cx = (x * scale) + (scale / 2);
var tile = t.GetTile(actX, actY);
var centerX = (x * scale) + (scale / 2);
var name = TerrainTileColor.GetTileName(tile);
gfx.DrawString(name, f, pen, new PointF(cx, cy), BuildingTextFormat);
gfx.DrawString(name, f, pen, centerX, centerY, BuildingTextFormat);
}
}
}