From daa3eec27ad985852bbbb5121c9e329081b8784b Mon Sep 17 00:00:00 2001 From: admin_d Date: Thu, 17 Sep 2026 18:38:58 +0500 Subject: [PATCH] Complete BigTask --- config/extra-paths.json | 3 +- .../kam_remake/src/utils/io/KM_IoPNG.pas | 101 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 port-source/kam_remake/src/utils/io/KM_IoPNG.pas diff --git a/config/extra-paths.json b/config/extra-paths.json index 905bc1e..61278af 100755 --- a/config/extra-paths.json +++ b/config/extra-paths.json @@ -8,7 +8,8 @@ "src/utils/KromUtils.pas", "src/utils/KM_Utils.pas", "src/terrain/KM_TerrainUtils.pas", - "src/res/KM_ResSprites.pas" + "src/res/KM_ResSprites.pas", + "src/utils/io/KM_IoPNG.pas" ], "source_paths": [ "code/resource" diff --git a/port-source/kam_remake/src/utils/io/KM_IoPNG.pas b/port-source/kam_remake/src/utils/io/KM_IoPNG.pas new file mode 100644 index 0000000..c50f744 --- /dev/null +++ b/port-source/kam_remake/src/utils/io/KM_IoPNG.pas @@ -0,0 +1,101 @@ +unit KM_IoPNG; +{$I KaM_Remake.inc} +interface +uses + KM_CommonTypes; + + +procedure SaveToPng(aWidth, aHeight: Word; const aPixelData: TKMCardinalArray; const aFilename: UnicodeString); +procedure LoadFromPng(const aFile: UnicodeString; var aWidth, aHeight: Word; var aPixelData: TKMCardinalArray); + + +implementation +uses + SysUtils, + Classes, + CastleImages, + CastleVectors, + CastleDownload, + CastleStringUtils; + + +procedure SaveToPng(aWidth, aHeight: Word; const aPixelData: TKMCardinalArray; const aFilename: UnicodeString); +var + ConvertedFilename: String; + Image: TRGBAlphaImage; + Stream: TStream; + X, Y: Integer; + CastleY: Cardinal; + KaMIndex: SizeInt; + T: Cardinal; + Pixel: PVector4Byte; +begin + ForceDirectories(ExtractFilePath(aFilename)); + ConvertedFilename := Utf16ToString(aFilename); + Image := TRGBAlphaImage.Create(aWidth, aHeight); + try + for Y := 0 to Integer(aHeight) - 1 do + for X := 0 to Integer(aWidth) - 1 do + begin + KaMIndex := SizeInt(Y) * SizeInt(aWidth) + X; + CastleY := Cardinal(aHeight - 1 - Y); + T := aPixelData[KaMIndex]; + Pixel := Image.PixelPtr(Cardinal(X), CastleY); + Pixel^.X := Byte(T and $FF); + Pixel^.Y := Byte((T shr 8) and $FF); + Pixel^.Z := Byte((T shr 16) and $FF); + Pixel^.W := Byte((T shr 24) and $FF); + end; + + Stream := UrlSaveStream(ConvertedFilename); + try + SaveImage(Image, 'image/png', Stream); + finally + Stream.Free; + end; + finally + Image.Free; + end; +end; + + +procedure LoadFromPng(const aFile: UnicodeString; var aWidth, aHeight: Word; var aPixelData: TKMCardinalArray); +var + ConvertedFilename: String; + Stream: TStream; + Image: TRGBAlphaImage; + X, Y: Integer; + CastleY: Cardinal; + KaMIndex: SizeInt; + Pixel: PVector4Byte; +begin + ConvertedFilename := Utf16ToString(aFile); + Stream := Download(ConvertedFilename); + try + Image := TRGBAlphaImage(LoadImage(Stream, 'image/png', [TRGBAlphaImage])); + try + aWidth := Image.Width; + aHeight := Image.Height; + SetLength(aPixelData, SizeInt(Image.Width) * SizeInt(Image.Height)); + + for Y := 0 to Integer(Image.Height) - 1 do + for X := 0 to Integer(Image.Width) - 1 do + begin + CastleY := Image.Height - 1 - Cardinal(Y); + KaMIndex := SizeInt(Y) * SizeInt(Image.Width) + X; + Pixel := Image.PixelPtr(Cardinal(X), CastleY); + aPixelData[KaMIndex] := Cardinal(Pixel^.X) or + (Cardinal(Pixel^.Y) shl 8) or + (Cardinal(Pixel^.Z) shl 16) or + (Cardinal(Pixel^.W) shl 24); + end; + finally + Image.Free; + end; + finally + Stream.Free; + end; +end; + + +end.