Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/NesTiler.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2022-10-25 17:16:48 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2022-10-25 17:16:48 +0300
commit2f99d859a6e19a17ad155b7d4522ce1cc388c2b2 (patch)
tree500a4594ba06e07abbf4b5cd806169559f1d1a53
parentcb5930b4118b976f0134f9d2ca8e55332b976c6c (diff)
Fixed sprites 8x16 processing
-rw-r--r--NesTiler/Program.cs37
-rw-r--r--NesTiler/Tile.cs31
2 files changed, 45 insertions, 23 deletions
diff --git a/NesTiler/Program.cs b/NesTiler/Program.cs
index a31e833..604695f 100644
--- a/NesTiler/Program.cs
+++ b/NesTiler/Program.cs
@@ -84,6 +84,8 @@ namespace com.clusterrr.Famicom.NesTiler
var paletteEnabled = new bool[4] { true, true, true, true };
var fixedPalettes = new Palette[4] { null, null, null, null };
var mode = TilesMode.Backgrounds;
+ int tileWidth = 8;
+ int tileHeight = 8;
int tilePalWidth = 16;
int tilePalHeight = 16;
bool sharePatternTable = false;
@@ -149,12 +151,16 @@ namespace com.clusterrr.Famicom.NesTiler
case "sprites":
case "sprites8x8":
mode = TilesMode.Sprites;
+ tileWidth = 8;
+ tileHeight = 8;
tilePalWidth = 8;
tilePalHeight = 8;
break;
case "sprite8x16":
case "sprites8x16":
mode = TilesMode.Sprites;
+ tileWidth = 8;
+ tileHeight = 16;
tilePalWidth = 8;
tilePalHeight = 16;
break;
@@ -162,6 +168,8 @@ namespace com.clusterrr.Famicom.NesTiler
case "background":
case "backgrounds":
mode = TilesMode.Backgrounds;
+ tileWidth = 8;
+ tileHeight = 8;
tilePalWidth = 16;
tilePalHeight = 16;
break;
@@ -285,6 +293,14 @@ namespace com.clusterrr.Famicom.NesTiler
// Stop if there are no images
if (!imageFiles.Any()) return 0;
+ switch (mode)
+ {
+ case TilesMode.Sprites:
+ case TilesMode.Sprites8x16:
+ if (!bgColor.HasValue) throw new InvalidDataException("You must specify background color for sprites");
+ break;
+ }
+
// Change the fixed palettes to colors from the NES palette
for (int i = 0; i < fixedPalettes.Length; i++)
{
@@ -332,8 +348,15 @@ namespace com.clusterrr.Famicom.NesTiler
for (int x = 0; x < image.Width; x++)
{
var color = image.GetPixelColor(x, y);
- var similarColor = nesColors[FindSimilarColor(nesColors, color, nesColorsCache)];
- image.SetPixelColor(x, y, similarColor);
+ if (color.A >= 0x80 || mode == TilesMode.Backgrounds)
+ {
+ var similarColor = nesColors[FindSimilarColor(nesColors, color, nesColorsCache)];
+ image.SetPixelColor(x, y, similarColor);
+ } else
+ {
+ if (!bgColor.HasValue) throw new InvalidDataException("You must specify background color for images with transparency");
+ image.SetPixelColor(x, y, bgColor.Value);
+ }
}
}
}
@@ -587,9 +610,6 @@ namespace com.clusterrr.Famicom.NesTiler
patternTableStartOffsets[imageNum] = tileID;
}
- var tileWidth = 8;
- var tileHeight = mode == TilesMode.Sprites8x16 ? 16 : 8;
-
outTilesCsvLines?.Add("image_id,image_file,line,column,tile_x,tile_y,tile_width,tile_height,tile_id,palette_id");
for (int tileY = 0; tileY < image.Height / tileHeight; tileY++)
{
@@ -611,7 +631,7 @@ namespace com.clusterrr.Famicom.NesTiler
}
tileData[(y * tileWidth) + x] = colorIndex;
}
- var tile = new Tile(tileData, tileWidth, tileHeight);
+ var tile = new Tile(tileData, tileHeight);
int currentTileID, id;
if (patternTable.TryGetValue(tile, out id))
{
@@ -625,6 +645,7 @@ namespace com.clusterrr.Famicom.NesTiler
currentTileID = tileID;
tileID++;
}
+ currentTileID = ((currentTileID & 0x7F) << 1) | ((currentTileID & 0x80) >> 7);
// Write CSV if required
outTilesCsvLines?.Add($"{imageNum},{imageFiles[imageNum]},{tileY},{tileX},{tileX * tileWidth},{tileY * tileHeight},{tileWidth},{tileHeight},{currentTileID},{paletteID}");
@@ -646,7 +667,7 @@ namespace com.clusterrr.Famicom.NesTiler
var patternTableRaw = new List<byte>();
for (int t = patternTableStartOffsets[imageNum]; t < tileID; t++)
{
- var raw = patternTableReversed[t].GetAsTileData();
+ var raw = patternTableReversed[t].GetAsPatternData();
patternTableRaw.AddRange(raw);
}
File.WriteAllBytes(outPatternTable[imageNum], patternTableRaw.ToArray());
@@ -670,7 +691,7 @@ namespace com.clusterrr.Famicom.NesTiler
var patternTableRaw = new List<byte>();
for (int t = patternTableStartOffsetShared; t < tileID; t++)
{
- var raw = patternTableReversed[t].GetAsTileData();
+ var raw = patternTableReversed[t].GetAsPatternData();
patternTableRaw.AddRange(raw);
}
File.WriteAllBytes(outPatternTableShared, patternTableRaw.ToArray());
diff --git a/NesTiler/Tile.cs b/NesTiler/Tile.cs
index e20d81d..f77352a 100644
--- a/NesTiler/Tile.cs
+++ b/NesTiler/Tile.cs
@@ -7,34 +7,35 @@ namespace com.clusterrr.Famicom.NesTiler
sealed record Tile : IEquatable<Tile>
{
public readonly byte[] Pixels;
- public readonly int Width;
+ public const int Width = 8;
public readonly int Height;
private int? hash;
private byte[] data = null;
- public Tile(byte[] data, int width, int height)
+ public Tile(byte[] data, int height)
{
- (Pixels, Width, Height) = (data, width, height);
+ (Pixels, Height) = (data, height);
}
- public byte[] GetAsTileData()
+ public byte[] GetAsPatternData()
{
if (data != null) return data;
- data = new byte[Width * Height / 8 * 2];
+ data = new byte[Height * 2]; // two bits per pixel
lock (data)
{
- int pixel = 0;
- byte bit = 7;
+ int pixel = 0; // total pixels counter
+ byte bit = 7; // bit number
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
- if ((Pixels[(y * Width) + x] & 1) != 0)
- data[(pixel / 64 * 2) + y] |= (byte)(1 << bit);
- if ((Pixels[(y * Width) + x] & 2) != 0)
- data[(pixel / 64 * 2) + y + 8] |= (byte)(1 << bit);
+ // for each pixel
+ if ((Pixels[(y * Width) + x] & 1) != 0) // check bit 0
+ data[y / 8 * 16 + (y % 8)] |= (byte)(1 << bit);
+ if ((Pixels[(y * Width) + x] & 2) != 0) // check bit 1
+ data[y / 8 * 16 + (y % 8) + 8] |= (byte)(1 << bit);
pixel++;
- bit = (byte)((byte)(bit - 1) % 8);
+ bit = (byte)((byte)(bit - 1) % 8); // decrease bit number, wrap around if need
}
}
}
@@ -43,8 +44,8 @@ namespace com.clusterrr.Famicom.NesTiler
public bool Equals(Tile other)
{
- var data1 = GetAsTileData();
- var data2 = other.GetAsTileData();
+ var data1 = GetAsPatternData();
+ var data2 = other.GetAsPatternData();
return Enumerable.SequenceEqual(data1, data2);
}
@@ -52,7 +53,7 @@ namespace com.clusterrr.Famicom.NesTiler
{
if (hash != null) return hash.Value;
var crc = new Crc32();
- crc.Append(GetAsTileData());
+ crc.Append(GetAsPatternData());
var hashBytes = crc.GetCurrentHash();
hash = BitConverter.ToInt32(hashBytes, 0);
return hash.Value;