Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[*.{cs,vb}]
indent_style = tab

# IDE0040: Add accessibility modifiers
dotnet_style_require_accessibility_modifiers = always
98 changes: 51 additions & 47 deletions OpenLocoToolGui/MainForm.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using OpenLocoTool.DatFileParsing;
using OpenLocoTool.Headers;
using OpenLocoToolCommon;
using System;
using System.Drawing.Imaging;
using System.Text.Json;
using System.Text.Json.Serialization;
Expand Down Expand Up @@ -178,9 +177,10 @@ private void CreateImages(ILocoObject obj)
for (var i = 0; i < obj.G1Elements.Count; ++i)
{
var currElement = obj.G1Elements[i];
byte[] imageData = currElement.ImageData;
if (currElement.flags.HasFlag(G1ElementFlags.IsRLECompressed))
{
currElement.ImageData = DecodeRLEImageData(currElement);
imageData = DecodeRLEImageData(currElement);
}
if (currElement.ImageData.Length == 0 || currElement.flags.HasFlag(G1ElementFlags.IsR8G8B8Palette))
{
Expand All @@ -194,7 +194,7 @@ private void CreateImages(ILocoObject obj)
{
for (var x = 0; x < currElement.width; ++x)
{
var paletteIndex = currElement.ImageData[(y * currElement.width) + x];
var paletteIndex = imageData[(y * currElement.width) + x];

// the issue with greyscale here is it isn't normalised so all heightmaps are really dark and hard to see
//var colour = obj.Object is HillShapesObject
Expand All @@ -221,73 +221,77 @@ private void CreateImages(ILocoObject obj)
flpImageTable.ResumeLayout(true);
}

byte[] DecodeRLEImageData(G1Element32 img)
public byte[] DecodeRLEImageData(G1Element32 img)
{
var newData = new List<byte>();
var zoom = 1;
var src0 = img.ImageData;
var srcX = 0;
var width = img.width;
var height = img.height;

for (var i = 0; i < img.height; i += zoom)
var dstLineWidth = img.width;
var dst0Index = 0; // dstLineWidth * img.yOffset + img.xOffset;

byte[] srcBuf = img.ImageData;
byte[] dstBuf = new byte[img.width * img.height]; // Assuming a single byte per pixel

var srcY = 0;

if (srcY < 0)
{
var y = i;
var lineOffset = src0[y * 2] | (src0[y * 2 + 1] << 8);
var nextRun = lineOffset;
srcY++;
height--;
dst0Index += dstLineWidth;
}

for (int i = 0; i < height; i++)
{
var y = srcY + i;

var lineOffset = srcBuf[y * 2] | (srcBuf[y * 2 + 1] << 8);

var endOfLine = false;
while (!endOfLine)
var nextRunIndex = lineOffset;
var dstLineStartIndex = dst0Index + dstLineWidth * i;

while (true)
{
var srcPtr = nextRun;
var dataSize = src0[srcPtr++];
var firstPixelX = src0[srcPtr++];
endOfLine = (dataSize & 0x80) != 0;
dataSize &= 0x7F;
var srcIndex = nextRunIndex;

var rleInfoByte = srcBuf[srcIndex++];
var dataSize = rleInfoByte & 0x7F;
var isEndOfLine = (rleInfoByte & 0x80) != 0;

nextRun = srcPtr + dataSize;
var x = firstPixelX - srcX;
int numPixels = dataSize;
var firstPixelX = srcBuf[srcIndex++];
nextRunIndex = srcIndex + dataSize;

var x = firstPixelX - 0; // img.xOffset;
var numPixels = dataSize;

if (x > 0)
{
// If x is not a multiple of zoom, round it up to a multiple
var mod = x & (zoom - 1);
if (mod != 0)
{
var offset = zoom - mod;
x += offset;
srcPtr += offset;
numPixels -= offset;
}
x++;
srcIndex++;
numPixels--;
}
else if (x < 0)
{
// Clamp x to zero if negative
srcPtr += -x;
srcIndex += -x;
numPixels += x;
x = 0;
}

numPixels = (byte)Math.Min(numPixels, img.width - x);
numPixels = Math.Min(numPixels, width - x);

var sizePre = newData.Count;
newData.AddRange(Enumerable.Repeat((byte)0, firstPixelX)); // pre-pad with transparent
newData.AddRange(src0[srcPtr..(srcPtr + numPixels)]);
var remaining = img.width - firstPixelX - numPixels;
newData.AddRange(Enumerable.Repeat((byte)0, remaining)); // post-pad with transparent
var dstIndex = dstLineStartIndex + x;

if (newData.Count != img.width * (i + 1))
if (numPixels > 0)
{
throw new ArgumentException("image size wrong");
Array.Copy(srcBuf, srcIndex, dstBuf, dstIndex, numPixels);
}
}
}

if (newData.Count != img.width * img.height)
{
throw new ArgumentException("image size wrong");
if (isEndOfLine)
break;
}
}

return newData.ToArray();
return dstBuf;
}

ILocoObject? LoadAndCacheObject(string filename)
Expand Down