diff --git a/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs b/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs index 50a819d..5b7161e 100644 --- a/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs +++ b/src/ReactorMaintenance.Win2D/MainWindow.xaml.cs @@ -215,58 +215,93 @@ public sealed partial class MainWindow { var wallColor = ColorHelper.FromArgb(255, 54, 61, 68); var floorColor = ColorHelper.FromArgb(255, 31, 36, 40); + var wallMask = c_AllCorners ^ floorMask; - if (floorMask == 0) + drawing.FillRectangle(rect, floorColor); + DrawDualTerrainTile(drawing, rect, wallColor, floorColor, GetDualTerrainTileId(wallMask)); + } + + private static int GetDualTerrainTileId(int wallMask) + { + return wallMask; + } + + private static void DrawDualTerrainTile(CanvasDrawingSession drawing, Rect rect, Color wallColor, Color floorColor, int tileId) + { + if (tileId == 0) + return; + + if (tileId == c_AllCorners) { drawing.FillRectangle(rect, wallColor); return; } - if (floorMask == c_AllFloorCorners) + switch (tileId) { - drawing.FillRectangle(rect, floorColor); - return; + case c_TopLeftCorner: + case c_TopRightCorner: + case c_BottomLeftCorner: + case c_BottomRightCorner: + DrawTerrainCorner(drawing, rect, wallColor, tileId); + break; + case c_TopLeftCorner | c_TopRightCorner: + drawing.FillRectangle(new(rect.X, rect.Y, rect.Width, rect.Height / 2), wallColor); + break; + case c_BottomLeftCorner | c_BottomRightCorner: + drawing.FillRectangle(new(rect.X, rect.Y + rect.Height / 2, rect.Width, rect.Height / 2), wallColor); + break; + case c_TopLeftCorner | c_BottomLeftCorner: + drawing.FillRectangle(new(rect.X, rect.Y, rect.Width / 2, rect.Height), wallColor); + break; + case c_TopRightCorner | c_BottomRightCorner: + drawing.FillRectangle(new(rect.X + rect.Width / 2, rect.Y, rect.Width / 2, rect.Height), wallColor); + break; + case c_TopLeftCorner | c_BottomRightCorner: + DrawTerrainCorner(drawing, rect, wallColor, c_TopLeftCorner); + DrawTerrainCorner(drawing, rect, wallColor, c_BottomRightCorner); + break; + case c_TopRightCorner | c_BottomLeftCorner: + DrawTerrainCorner(drawing, rect, wallColor, c_TopRightCorner); + DrawTerrainCorner(drawing, rect, wallColor, c_BottomLeftCorner); + break; + default: + drawing.FillRectangle(rect, wallColor); + DrawTerrainCorner(drawing, rect, floorColor, c_AllCorners ^ tileId); + break; } - - drawing.FillRectangle(rect, floorColor); - var wallMask = c_AllFloorCorners ^ floorMask; - if ((wallMask & c_TopLeftFloor) != 0) - DrawTerrainCorner(drawing, rect, wallColor, c_TopLeftFloor); - - if ((wallMask & c_TopRightFloor) != 0) - DrawTerrainCorner(drawing, rect, wallColor, c_TopRightFloor); - - if ((wallMask & c_BottomLeftFloor) != 0) - DrawTerrainCorner(drawing, rect, wallColor, c_BottomLeftFloor); - - if ((wallMask & c_BottomRightFloor) != 0) - DrawTerrainCorner(drawing, rect, wallColor, c_BottomRightFloor); } private static void DrawTerrainCorner(CanvasDrawingSession drawing, Rect rect, Color color, int corner) { - var center = new Vector2((float)(rect.X + rect.Width / 2), (float)(rect.Y + rect.Height / 2)); var radiusX = (float)rect.Width / 2; var radiusY = (float)rect.Height / 2; + var center = corner switch { + c_TopLeftCorner => new Vector2((float)rect.X, (float)rect.Y), + c_TopRightCorner => new Vector2((float)(rect.X + rect.Width), (float)rect.Y), + c_BottomRightCorner => new Vector2((float)(rect.X + rect.Width), (float)(rect.Y + rect.Height)), + c_BottomLeftCorner => new Vector2((float)rect.X, (float)(rect.Y + rect.Height)), + _ => new Vector2((float)(rect.X + rect.Width / 2), (float)(rect.Y + rect.Height / 2)) + }; var start = corner switch { - c_TopLeftFloor => new Vector2(center.X, (float)rect.Y), - c_TopRightFloor => new Vector2((float)(rect.X + rect.Width), center.Y), - c_BottomRightFloor => new Vector2(center.X, (float)(rect.Y + rect.Height)), - c_BottomLeftFloor => new Vector2((float)rect.X, center.Y), + c_TopLeftCorner => new Vector2(center.X + radiusX, center.Y), + c_TopRightCorner => new Vector2(center.X, center.Y + radiusY), + c_BottomRightCorner => new Vector2(center.X - radiusX, center.Y), + c_BottomLeftCorner => new Vector2(center.X, center.Y - radiusY), _ => center }; var end = corner switch { - c_TopLeftFloor => new Vector2((float)rect.X, center.Y), - c_TopRightFloor => new Vector2(center.X, (float)rect.Y), - c_BottomRightFloor => new Vector2((float)(rect.X + rect.Width), center.Y), - c_BottomLeftFloor => new Vector2(center.X, (float)(rect.Y + rect.Height)), + c_TopLeftCorner => new Vector2(center.X, center.Y + radiusY), + c_TopRightCorner => new Vector2(center.X - radiusX, center.Y), + c_BottomRightCorner => new Vector2(center.X, center.Y - radiusY), + c_BottomLeftCorner => new Vector2(center.X + radiusX, center.Y), _ => center }; using var builder = new CanvasPathBuilder(drawing); builder.BeginFigure(center); builder.AddLine(start); - builder.AddArc(end, radiusX, radiusY, 0, CanvasSweepDirection.CounterClockwise, CanvasArcSize.Small); + builder.AddArc(end, radiusX, radiusY, 0, CanvasSweepDirection.Clockwise, CanvasArcSize.Small); builder.EndFigure(CanvasFigureLoop.Closed); using var geometry = CanvasGeometry.CreatePath(builder); @@ -277,16 +312,16 @@ public sealed partial class MainWindow { var mask = 0; if (GetTerrainOrWall(x - 1, y - 1) == ECellTerrain.Floor) - mask |= c_TopLeftFloor; + mask |= c_TopLeftCorner; if (GetTerrainOrWall(x, y - 1) == ECellTerrain.Floor) - mask |= c_TopRightFloor; + mask |= c_TopRightCorner; if (GetTerrainOrWall(x - 1, y) == ECellTerrain.Floor) - mask |= c_BottomLeftFloor; + mask |= c_BottomLeftCorner; if (GetTerrainOrWall(x, y) == ECellTerrain.Floor) - mask |= c_BottomRightFloor; + mask |= c_BottomRightCorner; return mask; } @@ -451,11 +486,11 @@ public sealed partial class MainWindow } private readonly SimulationEngine m_Simulation = new(); - private const int c_TopLeftFloor = 1; - private const int c_TopRightFloor = 2; - private const int c_BottomLeftFloor = 4; - private const int c_BottomRightFloor = 8; - private const int c_AllFloorCorners = c_TopLeftFloor | c_TopRightFloor | c_BottomLeftFloor | c_BottomRightFloor; + private const int c_TopLeftCorner = 1; + private const int c_TopRightCorner = 2; + private const int c_BottomLeftCorner = 4; + private const int c_BottomRightCorner = 8; + private const int c_AllCorners = c_TopLeftCorner | c_TopRightCorner | c_BottomLeftCorner | c_BottomRightCorner; private StorageFile? m_CurrentFile; private LevelState m_Level; private bool m_Painting;