commit fc46d8ef0a0bd57ee5b45f5d4b66ad9538633f34
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu Dec 4 00:24:39 2025 +0100

    get rid of java.nio stuff from Mesh reading/writing

diff --git a/src/main/java/org/distorted/library/mesh/MeshBase.kt b/src/main/java/org/distorted/library/mesh/MeshBase.kt
index e6ddbd7..d4a0949 100644
--- a/src/main/java/org/distorted/library/mesh/MeshBase.kt
+++ b/src/main/java/org/distorted/library/mesh/MeshBase.kt
@@ -33,7 +33,6 @@ import org.distorted.library.type.Static4D
 import org.distorted.library.uniformblock.UniformBlockAssociation
 import org.distorted.library.uniformblock.UniformBlockCenter
 
-import java.nio.ByteBuffer
 import java.nio.ByteOrder
 
 import kotlin.math.min
@@ -911,6 +910,57 @@ abstract class MeshBase
         GLES.glBindBuffer(GLES.GL_ARRAY_BUFFER, 0)
     }
 
+    ///////////////////////////////////////////////////////////////////////////////////////////////////
+    // for writing FloatArrays. Big-endian.
+    fun FloatArray.toByteArrayBE(): ByteArray
+    {
+        val result = ByteArray(size*4)
+        var i = 0
+
+        for (f in this)
+        {
+            val bits = f.toBits()
+            result[i++] = (bits shr 24 and 0xFF).toByte()
+            result[i++] = (bits shr 16 and 0xFF).toByte()
+            result[i++] = (bits shr  8 and 0xFF).toByte()
+            result[i++] = (bits        and 0xFF).toByte()
+        }
+
+        return result
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////////
+    // meshes are big-endian
+    fun ByteArray.getIntAt(offset: Int): Int
+    {
+        val v0 = (this[offset+3].toInt() and 0xFF)
+        val v1 = (this[offset+2].toInt() and 0xFF)
+        val v2 = (this[offset+1].toInt() and 0xFF)
+        val v3 = (this[offset  ].toInt() and 0xFF)
+
+        return v0 or (v1 shl 8) or (v2 shl 16) or (v3 shl 24)
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////////////////////
+    fun ByteArray.getFloatAt(offset: Int): Float
+    {
+        return Float.fromBits(getIntAt(offset))
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////////
+    fun ByteArray.readFloatArray(offsetFloats: Int, count: Int): FloatArray
+    {
+        val result = FloatArray(count)
+        var byteOffset = 4*offsetFloats
+
+        for (i in 0 until count)
+        {
+            result[i] = getFloatAt(byteOffset)
+            byteOffset += 4
+        }
+        return result
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////////////////////
     // Return the number of bytes read.
     fun read(reader: FileReader): Int
@@ -926,15 +976,19 @@ abstract class MeshBase
         try
         {
             reader.read(buffer)
-            val byteBuf = ByteBuffer.wrap(buffer)
+            version = buffer.getIntAt(0)
 
-            version = byteBuf.getInt(0)
-
-            if (version==1||version==2)
+            if( version==2 )
             {
-                numVertices = byteBuf.getInt(4)
-                numTex = byteBuf.getInt(8)
-                numEff = byteBuf.getInt(12)
+                numVertices = buffer.getIntAt(4)
+                numTex = buffer.getIntAt(8)
+                numEff = buffer.getIntAt(12)
+
+                if( numVertices<=0 || numEff<=0 || numTex<=0 )
+                {
+                    DistortedLibrary.logMessage("MeshBase: Error: numVertices: $numVertices numEff: $numEff numTex: $numTex")
+                    return 0
+                }
             }
             else
             {
@@ -951,115 +1005,70 @@ abstract class MeshBase
         //////////////////////////////////////////////////////////////////////////////////////////
         // read contents of all texture and effect components
         //////////////////////////////////////////////////////////////////////////////////////////
-        if (numVertices>0&&numEff>0&&numTex>0)
-        {
-            val size = numEff+TEX_COMP_SIZE*numTex
-            val tmp = FloatArray(size)
-            mVertAttribs1 = FloatArray(VERT1_ATTRIBS*numVertices)
-            mVertAttribs2 = FloatArray(VERT2_ATTRIBS*numVertices)
-
-            // version 1 had extra 3 floats (the 'inflate' vector) in its vert1 array
-            val vert1InFile = if (version==2) VERT1_ATTRIBS else VERT1_ATTRIBS+3
-            // ... and there was no center.
-            val centerSize = if (version==2) 3*numEff else 0
+        val size = numEff+TEX_COMP_SIZE*numTex
+        buffer = ByteArray(BYTES_PER_FLOAT*(size + 3*numEff + numVertices*(VERT1_ATTRIBS+VERT2_ATTRIBS)) )
 
-            buffer = ByteArray(BYTES_PER_FLOAT*(size+centerSize+numVertices*(vert1InFile+VERT2_ATTRIBS)))
-
-            try
-            {
-                reader.read(buffer)
-            }
-            catch (e: Exception)
-            {
-                DistortedLibrary.logMessage("MeshBase: Exception2 trying to read file: $e")
-                return 0
-            }
-
-            val byteBuf = ByteBuffer.wrap(buffer)
-            val floatBuf = byteBuf.asFloatBuffer()
+        try
+        {
+            reader.read(buffer)
+        }
+        catch (e: Exception)
+        {
+            DistortedLibrary.logMessage("MeshBase: Exception2 trying to read file: $e")
+            return 0
+        }
 
-            floatBuf[tmp, 0, size]
+        var tex: TexComponent
+        var index: Int
+        var x: Float
+        var y: Float
+        var z: Float
+        var w: Float
 
-            var tex: TexComponent
-            var index: Int
-            var x: Float
-            var y: Float
-            var z: Float
-            var w: Float
+        var texComp = 0
+        while (texComp<numTex)
+        {
+            index = buffer.getIntAt(TEX_COMP_SIZE*texComp)
 
-            var texComp = 0
-            while (texComp<numTex)
-            {
-                index = tmp[TEX_COMP_SIZE*texComp].toInt()
+            x = buffer.getFloatAt(TEX_COMP_SIZE*texComp+1)
+            y = buffer.getFloatAt(TEX_COMP_SIZE*texComp+2)
+            z = buffer.getFloatAt(TEX_COMP_SIZE*texComp+3)
+            w = buffer.getFloatAt(TEX_COMP_SIZE*texComp+4)
 
-                x = tmp[TEX_COMP_SIZE*texComp+1]
-                y = tmp[TEX_COMP_SIZE*texComp+2]
-                z = tmp[TEX_COMP_SIZE*texComp+3]
-                w = tmp[TEX_COMP_SIZE*texComp+4]
+            tex = TexComponent(index)
+            tex.setMap(Static4D(x, y, z, w))
 
-                tex = TexComponent(index)
-                tex.setMap(Static4D(x, y, z, w))
+            mTexComponent.add(tex)
+            texComp++
+        }
 
-                mTexComponent.add(tex)
-                texComp++
-            }
+        for (effComp in 0 until numEff)
+        {
+            index = buffer.getIntAt(TEX_COMP_SIZE*texComp+effComp)
+            mEffComponent.add(index)
+        }
 
-            for (effComp in 0 until numEff)
-            {
-                index = tmp[TEX_COMP_SIZE*texComp+effComp].toInt()
-                mEffComponent.add(index)
-            }
+        //////////////////////////////////////////////////////////////////////////////////////////
+        // read vert1 array, vert2 array and the component centers.
+        //////////////////////////////////////////////////////////////////////////////////////////
+        var start = size
+        var count = 3*numEff
+        val centers = buffer.readFloatArray(start,count )
+        start += count
+        count = VERT1_ATTRIBS*numVertices
+        mVertAttribs1 = buffer.readFloatArray( start,count )
+        start += count
+        count = VERT2_ATTRIBS*numVertices
+        mVertAttribs2 = buffer.readFloatArray( start,count )
 
-            //////////////////////////////////////////////////////////////////////////////////////////
-            // read vert1 array, vert2 array and (if version>1) the component centers.
-            //////////////////////////////////////////////////////////////////////////////////////////
-            when (version)
+        if (useCenters)
+        {
+            var eff = 0
+            while (eff<numEff)
             {
-                1 ->
-                {
-                    index = floatBuf.position()
-
-                    var vert = 0
-                    while (vert<numVertices)
-                    {
-                        mVertAttribs1!![VERT1_ATTRIBS*vert+POS_ATTRIB  ] = floatBuf[index+POS_ATTRIB  ]
-                        mVertAttribs1!![VERT1_ATTRIBS*vert+POS_ATTRIB+1] = floatBuf[index+POS_ATTRIB+1]
-                        mVertAttribs1!![VERT1_ATTRIBS*vert+POS_ATTRIB+2] = floatBuf[index+POS_ATTRIB+2]
-                        mVertAttribs1!![VERT1_ATTRIBS*vert+NOR_ATTRIB  ] = floatBuf[index+NOR_ATTRIB  ]
-                        mVertAttribs1!![VERT1_ATTRIBS*vert+NOR_ATTRIB+1] = floatBuf[index+NOR_ATTRIB+1]
-                        mVertAttribs1!![VERT1_ATTRIBS*vert+NOR_ATTRIB+2] = floatBuf[index+NOR_ATTRIB+2]
-                        index += vert1InFile
-                        vert++
-                    }
-                    floatBuf.position(index)
-                }
-
-                2 ->
-                {
-                    val centers = FloatArray(3*numEff)
-                    floatBuf[centers, 0, 3*numEff]
-
-                    if (useCenters)
-                    {
-                        var eff = 0
-                        while (eff<numEff)
-                        {
-                            mUBC!!.setEffectCenterNow(eff, centers[3*eff], centers[3*eff+1], centers[3*eff+2])
-                            eff++
-                        }
-                    }
-
-                    floatBuf[mVertAttribs1, 0, VERT1_ATTRIBS*numVertices]
-                }
-
-                else ->
-                {
-                    DistortedLibrary.logMessage("MeshBase: Error: unknown mesh file version "+String.format("0x%08X", version))
-                    return 0
-                }
+                mUBC!!.setEffectCenterNow(eff, centers[3*eff], centers[3*eff+1], centers[3*eff+2])
+                eff++
             }
-
-            floatBuf[mVertAttribs2, 0, VERT2_ATTRIBS*numVertices]
         }
 
         return BYTES_PER_FLOAT*(4+numEff+TEX_COMP_SIZE*numTex+VERT1_ATTRIBS*numVertices+VERT2_ATTRIBS*numVertices)
@@ -1130,13 +1139,8 @@ abstract class MeshBase
             writer.writeFloat(centers[4*i+2])
         }
 
-        val vertBuf1 = ByteBuffer.allocate(VERT1_SIZE*numVertices)
-        vertBuf1.asFloatBuffer().put(mVertAttribs1)
-        val vertBuf2 = ByteBuffer.allocate(VERT2_SIZE*numVertices)
-        vertBuf2.asFloatBuffer().put(mVertAttribs2)
-
-        writer.write(vertBuf1.array())
-        writer.write(vertBuf2.array())
+        writer.write( mVertAttribs1!!.toByteArrayBE() )
+        writer.write( mVertAttribs2!!.toByteArrayBE() )
     }
 
     ///////////////////////////////////////////////////////////////////////////////////////////////////
