Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
0x7c13 committed Oct 15, 2023
1 parent 09cd24d commit 01913ed
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 79 deletions.
4 changes: 2 additions & 2 deletions Assets/Scripts/Engine/DataLoader/DxtTextureLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void Load(byte[] data, out bool hasAlphaChannel)
private void LoadDxt1Texture(byte[] data)
{
_rawRgbaData = ArrayPool<byte>.Shared.Rent(_width * _height * 4);
Dxt1Decoder.ToRgba32NonAlloc(data, _width, _height, _rawRgbaData);
Dxt1Decoder.ToRgba32(data, _width, _height, _rawRgbaData);
}

// Texture2D.LoadRawTextureData does not support DXT3 format
Expand All @@ -76,7 +76,7 @@ private void LoadDxt1Texture(byte[] data)
private void LoadDxt3Texture(byte[] data)
{
_rawRgbaData = ArrayPool<byte>.Shared.Rent(_width * _height * 4);
Dxt3Decoder.ToRgba32NonAlloc(data, _width, _height, _rawRgbaData);
Dxt3Decoder.ToRgba32(data, _width, _height, _rawRgbaData);
}

public ITexture2D ToTexture()
Expand Down
45 changes: 5 additions & 40 deletions Assets/Scripts/Engine/DataLoader/TgaTextureLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Engine.DataLoader
using System;
using System.Buffers;
using Core.Abstraction;
using Pal3.Core.DataReader.Tga;

/// <summary>
/// .tga file loader and Texture2D converter.
Expand Down Expand Up @@ -38,60 +39,24 @@ public unsafe void Load(byte[] data, out bool hasAlphaChannel)
bitDepth = *(p + 4);
}

var dataStartIndex = 18;

_rawRgbaData = ArrayPool<byte>.Shared.Rent(_width * _height * 4);

switch (bitDepth)
{
case 24:
hasAlphaChannel = false;
Decode24BitDataToRgba32(data, dataStartIndex);
TgaDecoder.Decode24BitDataToRgba32(
data, _width, _height, _rawRgbaData);
break;
case 32:
Decode32BitDataToRgba32(data, dataStartIndex, out hasAlphaChannel);
TgaDecoder.Decode32BitDataToRgba32(
data, _width, _height, _rawRgbaData, out hasAlphaChannel);
break;
default:
throw new Exception("TGA texture had non 32/24 bit depth");
}
}

private unsafe void Decode24BitDataToRgba32(byte[] data, int startIndex)
{
fixed (byte* srcStart = &data[startIndex], dstStart = _rawRgbaData)
{
byte* src = srcStart, dst = dstStart;
for (var i = 0; i < _width * _height; i++, src += 3, dst += 4)
{
*dst = *(src + 2);
*(dst + 1) = *(src + 1);
*(dst + 2) = *src;
*(dst + 3) = 0; // 24-bit don't have alpha
}
}
}

private unsafe void Decode32BitDataToRgba32(byte[] data, int startIndex, out bool hasAlphaChannel)
{
hasAlphaChannel = false;
fixed (byte* srcStart = &data[startIndex], dstStart = _rawRgbaData)
{
var firstAlpha = *(srcStart + 3);
byte* src = srcStart, dst = dstStart;
for (var i = 0; i < _width * _height; i++, src += 4, dst += 4)
{
*dst = *(src + 2);
*(dst + 1) = *(src + 1);
*(dst + 2) = *src;

byte alpha = *(src + 3);
*(dst + 3) = alpha;

if (alpha != firstAlpha) hasAlphaChannel = true;
}
}
}

public ITexture2D ToTexture()
{
if (_rawRgbaData == null) return null;
Expand Down
36 changes: 18 additions & 18 deletions Assets/Scripts/Engine/Extensions/UnityPrimitivesConvertor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ public static UnityEngine.Vector3[] ToUnityPositions(this GameBoxVector3[] gameB
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ToUnityPositionsNonAlloc(this GameBoxVector3[] gameBoxPositions,
UnityEngine.Vector3[] unityPositions, float scale = GameBoxUnitToUnityUnit)
public static void ToUnityPositions(this GameBoxVector3[] gameBoxPositions,
UnityEngine.Vector3[] unityPositionsBuffer, float scale = GameBoxUnitToUnityUnit)
{
if (gameBoxPositions == null || unityPositions == null || unityPositions.Length != gameBoxPositions.Length)
if (gameBoxPositions == null || unityPositionsBuffer == null || unityPositionsBuffer.Length != gameBoxPositions.Length)
{
throw new ArgumentException("unityPositions and gameBoxPositions must be non-null and have the same length");
throw new ArgumentException("gameBoxPositions and unityPositionsBuffer must be non-null and have the same length");
}

for (var i = 0; i < gameBoxPositions.Length; i++)
{
unityPositions[i] = ToUnityVector3(gameBoxPositions[i], scale);
unityPositionsBuffer[i] = ToUnityVector3(gameBoxPositions[i], scale);
}
}

Expand Down Expand Up @@ -158,17 +158,17 @@ public static UnityEngine.Vector3[] ToUnityNormals(this GameBoxVector3[] gameBox
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ToUnityNormalsNonAlloc(this GameBoxVector3[] gameBoxNormals,
UnityEngine.Vector3[] unityNormals)
public static void ToUnityNormals(this GameBoxVector3[] gameBoxNormals,
UnityEngine.Vector3[] unityNormalsBuffer)
{
if (gameBoxNormals == null || unityNormals == null || gameBoxNormals.Length != unityNormals.Length)
if (gameBoxNormals == null || unityNormalsBuffer == null || gameBoxNormals.Length != unityNormalsBuffer.Length)
{
throw new ArgumentException("gameBoxNormals and unityNormals must be non-null and have the same length");
throw new ArgumentException("gameBoxNormals and unityNormalsBuffer must be non-null and have the same length");
}

for (var i = 0; i < gameBoxNormals.Length; i++)
{
unityNormals[i] = ToUnityNormal(gameBoxNormals[i]);
unityNormalsBuffer[i] = ToUnityNormal(gameBoxNormals[i]);
}
}

Expand Down Expand Up @@ -264,16 +264,16 @@ public static void ToUnityTrianglesInPlace(this int[] gameBoxTriangles)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ToUnityTrianglesNonAlloc(this int[] gameBoxTriangles, int[] unityTriangles)
public static void ToUnityTriangles(this int[] gameBoxTriangles, int[] unityTrianglesBuffer)
{
if (gameBoxTriangles == null || unityTriangles == null || gameBoxTriangles.Length != unityTriangles.Length)
if (gameBoxTriangles == null || unityTrianglesBuffer == null || gameBoxTriangles.Length != unityTrianglesBuffer.Length)
{
throw new ArgumentException("gameBoxTriangles and unityTriangles must be non-null and have the same length");
throw new ArgumentException("gameBoxTriangles and unityTrianglesBuffer must be non-null and have the same length");
}

for (var i = 0; i < gameBoxTriangles.Length; i++)
{
unityTriangles[i] = gameBoxTriangles[gameBoxTriangles.Length - 1 - i];
unityTrianglesBuffer[i] = gameBoxTriangles[gameBoxTriangles.Length - 1 - i];
}
}

Expand Down Expand Up @@ -319,16 +319,16 @@ public static UnityEngine.Vector2[] ToUnityVector2s(this GameBoxVector2[] gameBo
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ToUnityVector2sNonAlloc(this GameBoxVector2[] gameBoxVector2s, UnityEngine.Vector2[] unityVector2s)
public static void ToUnityVector2s(this GameBoxVector2[] gameBoxVector2s, UnityEngine.Vector2[] unityVector2sBuffer)
{
if (gameBoxVector2s == null || unityVector2s == null || gameBoxVector2s.Length != unityVector2s.Length)
if (gameBoxVector2s == null || unityVector2sBuffer == null || gameBoxVector2s.Length != unityVector2sBuffer.Length)
{
throw new ArgumentException("gameBoxVector2s and unityVector2s must be non-null and have the same length");
throw new ArgumentException("gameBoxVector2s and unityVector2sBuffer must be non-null and have the same length");
}

for (var i = 0; i < gameBoxVector2s.Length; i++)
{
unityVector2s[i] = gameBoxVector2s[i].ToUnityVector2();
unityVector2sBuffer[i] = gameBoxVector2s[i].ToUnityVector2();
}
}

Expand Down
5 changes: 0 additions & 5 deletions Assets/Scripts/Pal3.Core/DataReader/Cpk/CpkArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ public sealed class CpkArchive

public CpkArchive(string cpkFilePath, Crc32Hash crcHash, int codepage)
{
if (!File.Exists(cpkFilePath))
{
throw new FileNotFoundException($"游戏数据加载失败,游戏原CPK数据文件不存在: {cpkFilePath}");
}

_filePath = cpkFilePath;
_crcHash = crcHash;
_codepage = codepage;
Expand Down
2 changes: 1 addition & 1 deletion Assets/Scripts/Pal3.Core/DataReader/Cpk/CpkTableEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public enum CpkTableEntityFlag
IsDir = 0x2, // 是否是目录
IsLargeFile = 0x4, // 大文件
IsDeleted = 0x10, // 是否已删除
IsNotCompressed = 0x10000,
IsNotCompressed = 0x10000, // 是否未压缩
};

// CPK 文件表结构
Expand Down
4 changes: 2 additions & 2 deletions Assets/Scripts/Pal3.Core/DataReader/Dxt/Dxt1Decoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public static class Dxt1Decoder
public static byte[] ToRgba32(byte[] data, int width, int height)
{
byte[] buffer = new byte[width * height * 4];
ToRgba32NonAlloc(data, width, height, buffer);
ToRgba32(data, width, height, buffer);
return buffer;
}

public static unsafe void ToRgba32NonAlloc(byte[] data, int width, int height, byte[] buffer)
public static unsafe void ToRgba32(byte[] data, int width, int height, byte[] buffer)
{
if (buffer == null || buffer.Length < width * height * 4)
{
Expand Down
4 changes: 2 additions & 2 deletions Assets/Scripts/Pal3.Core/DataReader/Dxt/Dxt3Decoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public static class Dxt3Decoder
public static byte[] ToRgba32(byte[] data, int width, int height)
{
byte[] buffer = new byte[width * height * 4];
ToRgba32NonAlloc(data, width, height, buffer);
ToRgba32(data, width, height, buffer);
return buffer;
}

public static unsafe void ToRgba32NonAlloc(byte[] data, int width, int height, byte[] buffer)
public static unsafe void ToRgba32(byte[] data, int width, int height, byte[] buffer)
{
if (buffer == null || buffer.Length < width * height * 4)
{
Expand Down
3 changes: 3 additions & 0 deletions Assets/Scripts/Pal3.Core/DataReader/Tga.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 86 additions & 0 deletions Assets/Scripts/Pal3.Core/DataReader/Tga/TgaDecoder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2021-2023, Jiaqi Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------

namespace Pal3.Core.DataReader.Tga
{
using System;

public static class TgaDecoder
{
private const int TGA_FILE_HEADER_SIZE = 18;

public static byte[] Decode24BitDataToRgba32(byte[] data,
int width,
int height)
{
byte[] buffer = new byte[width * height * 4];
Decode24BitDataToRgba32(data, width, height, buffer);
return buffer;
}

public static unsafe void Decode24BitDataToRgba32(byte[] data,
int width,
int height,
byte[] buffer)
{
if (buffer == null || buffer.Length < width * height * 4)
{
throw new ArgumentException("buffer is null or too small");
}

fixed (byte* srcStart = &data[TGA_FILE_HEADER_SIZE], dstStart = buffer)
{
byte* src = srcStart, dst = dstStart;
for (var i = 0; i < width * height; i++, src += 3, dst += 4)
{
*dst = *(src + 2);
*(dst + 1) = *(src + 1);
*(dst + 2) = *src;
*(dst + 3) = 0; // 24-bit don't have alpha
}
}
}

public static byte[] Decode32BitDataToRgba32(byte[] data,
int width,
int height,
out bool hasAlphaChannel)
{
byte[] buffer = new byte[width * height * 4];
Decode32BitDataToRgba32(data, width, height, buffer, out hasAlphaChannel);
return buffer;
}

public static unsafe void Decode32BitDataToRgba32(byte[] data,
int width,
int height,
byte[] buffer,
out bool hasAlphaChannel)
{
if (buffer == null || buffer.Length < width * height * 4)
{
throw new ArgumentException("buffer is null or too small");
}

hasAlphaChannel = false;
fixed (byte* srcStart = &data[TGA_FILE_HEADER_SIZE], dstStart = buffer)
{
var firstAlpha = *(srcStart + 3);
byte* src = srcStart, dst = dstStart;
for (var i = 0; i < width * height; i++, src += 4, dst += 4)
{
*dst = *(src + 2);
*(dst + 1) = *(src + 1);
*(dst + 2) = *src;

byte alpha = *(src + 3);
*(dst + 3) = alpha;

if (alpha != firstAlpha) hasAlphaChannel = true;
}
}
}
}
}
3 changes: 3 additions & 0 deletions Assets/Scripts/Pal3.Core/DataReader/Tga/TgaDecoder.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions Assets/Scripts/Pal3.Core/FileSystem/CpkFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public CpkFileSystem(string rootPath, Crc32Hash crcHash)

if (!Directory.Exists(rootPath))
{
throw new DirectoryNotFoundException($"游戏数据加载失败,原始游戏数据根目录不存在: {rootPath}");
throw new DirectoryNotFoundException(rootPath);
}

_rootPath = rootPath;
Expand All @@ -51,14 +51,21 @@ public string GetRootPath()
/// <param name="codepage">Codepage CPK file uses for encoding text info</param>
public void Mount(string cpkFileRelativePath, int codepage)
{
var cpkFileName = CoreUtility.GetFileName(cpkFileRelativePath, Path.DirectorySeparatorChar).ToLower();
string cpkFileName = CoreUtility.GetFileName(cpkFileRelativePath, Path.DirectorySeparatorChar).ToLower();

if (_cpkArchives.ContainsKey(cpkFileName))
{
return;
}

var cpkArchive = new CpkArchive(_rootPath + cpkFileRelativePath, _crcHash, codepage);
string cpkFilePath = _rootPath + cpkFileRelativePath;

if (!File.Exists(cpkFilePath))
{
throw new FileNotFoundException(cpkFilePath);
}

var cpkArchive = new CpkArchive(cpkFilePath, _crcHash, codepage);
cpkArchive.Init();
_cpkArchives[cpkFileName] = cpkArchive;
}
Expand Down
10 changes: 9 additions & 1 deletion Assets/Scripts/Pal3.Game/GameResourceInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,15 @@ private IEnumerator InitResourceAsync()
}
else
{
loadingText.text = exception == null ? "游戏数据加载失败,未能找到原游戏数据文件" : $"{exception.Message}";
string errorMessage = exception switch
{
null => "游戏数据加载失败,未能找到原游戏数据文件",
DirectoryNotFoundException => $"游戏数据加载失败,原始游戏数据根目录不存在: {exception.Message}",
FileNotFoundException => $"游戏数据加载失败,游戏原CPK数据文件不存在: {exception.Message}",
_ => $"游戏数据加载失败,错误信息:{exception}"
};

loadingText.text = errorMessage;
yield break; // Stop initialization if failed to init file system
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ private void RenderMeshInternal(
meshSection.GameBoxTriangles.Length);

// Triangles are the same for all frames, so we can just copy them once.
meshSection.GameBoxTriangles.ToUnityTrianglesNonAlloc(meshDataBuffer.TriangleBuffer);
meshSection.GameBoxTriangles.ToUnityTriangles(meshDataBuffer.TriangleBuffer);

UpdateMeshDataBuffer(ref meshDataBuffer,
meshSection,
Expand Down
Loading

0 comments on commit 01913ed

Please sign in to comment.