From 1b12e67de2713fed255216f482995b7d740a006d Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 16 Feb 2026 13:34:20 -0600 Subject: [PATCH] Use internal endian tool --- src/asset/type/assettexture.c | 5 +-- src/asset/type/assettileset.c | 27 +++++--------- src/dusk.h | 5 --- src/util/CMakeLists.txt | 1 + src/util/endian.c | 67 +++++++++++++++++++++++++++++++++++ src/util/endian.h | 48 +++++++++++++++++++++++++ 6 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 src/util/endian.c create mode 100644 src/util/endian.h diff --git a/src/asset/type/assettexture.c b/src/asset/type/assettexture.c index c2775b5..0dbf9bc 100644 --- a/src/asset/type/assettexture.c +++ b/src/asset/type/assettexture.c @@ -9,6 +9,7 @@ #include "asset/assettype.h" #include "assert/assert.h" #include "display/texture.h" +#include "util/endian.h" errorret_t assetTextureLoad(assetentire_t entire) { assertNotNull(entire.data, "Data pointer cannot be NULL."); @@ -32,8 +33,8 @@ errorret_t assetTextureLoad(assetentire_t entire) { } // Fix endian - assetData->width = le32toh(assetData->width); - assetData->height = le32toh(assetData->height); + assetData->width = endianLittleToHost32(assetData->width); + assetData->height = endianLittleToHost32(assetData->height); // Check dimensions. if( diff --git a/src/asset/type/assettileset.c b/src/asset/type/assettileset.c index dd6ef14..f7c214a 100644 --- a/src/asset/type/assettileset.c +++ b/src/asset/type/assettileset.c @@ -9,6 +9,7 @@ #include "assert/assert.h" #include "display/tileset/tileset.h" #include "util/memory.h" +#include "util/endian.h" errorret_t assetTilesetLoad(assetentire_t entire) { assertNotNull(entire.data, "Asset data cannot be null"); @@ -30,12 +31,12 @@ errorret_t assetTilesetLoad(assetentire_t entire) { } // Fix endianness - tilesetData->tileWidth = le16toh(tilesetData->tileWidth); - tilesetData->tileHeight = le16toh(tilesetData->tileHeight); - tilesetData->columnCount = le16toh(tilesetData->columnCount); - tilesetData->rowCount = le16toh(tilesetData->rowCount); - tilesetData->right = le16toh(tilesetData->right); - tilesetData->bottom = le16toh(tilesetData->bottom); + tilesetData->tileWidth = endianLittleToHost16(tilesetData->tileWidth); + tilesetData->tileHeight = endianLittleToHost16(tilesetData->tileHeight); + tilesetData->columnCount = endianLittleToHost16(tilesetData->columnCount); + tilesetData->rowCount = endianLittleToHost16(tilesetData->rowCount); + tilesetData->right = endianLittleToHost16(tilesetData->right); + tilesetData->bottom = endianLittleToHost16(tilesetData->bottom); if(tilesetData->tileWidth == 0) { errorThrow("Tile width cannot be 0"); @@ -49,19 +50,9 @@ errorret_t assetTilesetLoad(assetentire_t entire) { if(tilesetData->rowCount == 0) { errorThrow("Row count cannot be 0"); } - - uint32_t temp; - memoryCopy(&temp, &tilesetData->u0, sizeof(float_t)); - temp = le32toh(temp); - memoryCopy(&tilesetData->u0, &temp, sizeof(float_t)); - if(tilesetData->u0 < 0.0f || tilesetData->u0 > 1.0f) { - errorThrow("Invalid u0 value in tileset"); - } - - memoryCopy(&temp, &tilesetData->v0, sizeof(float_t)); - temp = le32toh(temp); - memoryCopy(&tilesetData->v0, &temp, sizeof(float_t)); + tilesetData->u0 = endianLittleToHostFloat(tilesetData->u0); + tilesetData->v0 = endianLittleToHostFloat(tilesetData->v0); if(tilesetData->v0 < 0.0f || tilesetData->v0 > 1.0f) { errorThrow("Invalid v0 value in tileset"); diff --git a/src/dusk.h b/src/dusk.h index 601521a..0352c83 100644 --- a/src/dusk.h +++ b/src/dusk.h @@ -33,11 +33,6 @@ #include #include #include - #include -#else - #ifndef le32toh - #define le32toh(x) (x) - #endif #endif typedef bool bool_t; diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 095cfb7..304788c 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC array.c + endian.c memory.c string.c math.c diff --git a/src/util/endian.c b/src/util/endian.c new file mode 100644 index 0000000..86a096f --- /dev/null +++ b/src/util/endian.c @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "util/endian.h" +#include "util/memory.h" + +bool_t isHostLittleEndian(void) { + uint32_t value = ENDIAN_MAGIC; + uint8_t *bytePtr = (uint8_t *)&value; + return bytePtr[0] == 0x04; +} + +uint32_t endianLittleToHost32(uint32_t value) { + if(isHostLittleEndian()) { + return value; + } + + return ( + ((value & 0x000000FF) << 24) | + ((value & 0x0000FF00) << 8) | + ((value & 0x00FF0000) >> 8) | + ((value & 0xFF000000) >> 24) + ); +} + +uint16_t endianLittleToHost16(uint16_t value) { + if(isHostLittleEndian()) { + return value; + } + return (uint16_t)(((value & 0x00FF) << 8) | + ((value & 0xFF00) >> 8)); +} + +uint64_t endianLittleToHost64(uint64_t value) { + if(isHostLittleEndian()) { + return value; + } + return ( + ((value & 0x00000000000000FFULL) << 56) | + ((value & 0x000000000000FF00ULL) << 40) | + ((value & 0x0000000000FF0000ULL) << 24) | + ((value & 0x00000000FF000000ULL) << 8) | + ((value & 0x000000FF00000000ULL) >> 8) | + ((value & 0x0000FF0000000000ULL) >> 24) | + ((value & 0x00FF000000000000ULL) >> 40) | + ((value & 0xFF00000000000000ULL) >> 56) + ); +} + +float_t endianLittleToHostFloat(float_t value) { + if(isHostLittleEndian()) { + return value; + } + + uint32_t temp; + float_t result; + memoryCopy(&temp, &value, sizeof(uint32_t)); + temp = endianLittleToHost32(temp); + memoryCopy(&result, &temp, sizeof(uint32_t)); + + return result; +} + diff --git a/src/util/endian.h b/src/util/endian.h new file mode 100644 index 0000000..14a9e79 --- /dev/null +++ b/src/util/endian.h @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +static const uint32_t ENDIAN_MAGIC = 0x01020304; + +/** + * Checks if the host system is little-endian. + * + * @return true if the host is little-endian, false otherwise. + */ +bool_t isHostLittleEndian(void); + +/** + * Converts a 32-bit integer from little-endian to host byte order. + * + * @param value The little-endian value to convert. + * @return The value in host byte order. + */ +uint32_t endianLittleToHost32(uint32_t value); + +/** + * Converts a 16-bit integer from little-endian to host byte order. + * @param value The little-endian value to convert. + * @return The value in host byte order. + */ +uint16_t endianLittleToHost16(uint16_t value); + +/** + * Converts a 64-bit integer from little-endian to host byte order. + * @param value The little-endian value to convert. + * @return The value in host byte order. + */ +uint64_t endianLittleToHost64(uint64_t value); + +/** + * Converts a float from little-endian to host byte order. + * + * @param value The little-endian value to convert. + * @return The value in host byte order. + */ +float_t endianLittleToHostFloat(float_t value); \ No newline at end of file