fixed endianess issue in goat3d file reading
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 31 Mar 2023 17:37:24 +0000 (19:37 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 31 Mar 2023 17:37:24 +0000 (19:37 +0200)
libs/goat3d/Makefile
libs/goat3d/src/chunk.h
libs/goat3d/src/goat3d.c
libs/goat3d/src/read.c
libs/goat3d/src/util.c [new file with mode: 0644]
libs/goat3d/src/util.h [new file with mode: 0644]
src/scr_game.c

index 6c02b17..4917266 100644 (file)
@@ -1,8 +1,9 @@
 obj = src/aabox.o src/chunk.o src/dynarr.o src/extmesh.o src/g3danm.o \
-         src/g3dscn.o src/goat3d.o src/log.o src/read.o src/track.o src/write.o
+         src/g3dscn.o src/goat3d.o src/log.o src/read.o src/track.o src/write.o \
+         src/util.o
 alib = ../unix/goat3d.a
 
-CFLAGS = -O3 -Iinclude -I../treestor/include -I..
+CFLAGS = -O3 -g -Iinclude -I../treestor/include -I..
 
 $(alib): $(obj)
        $(AR) rcs $@ $(obj)
index 505c150..19c1bbd 100644 (file)
@@ -1,6 +1,6 @@
 /*
 goat3d - 3D scene, and animation file format library.
-Copyright (C) 2013-2018  John Tsiombikas <nuclear@member.fsf.org>
+Copyright (C) 2013-2023  John Tsiombikas <nuclear@member.fsf.org>
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
@@ -18,15 +18,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef CHUNK_H_
 #define CHUNK_H_
 
-#ifndef _MSC_VER
-#ifdef __sgi
-#include <inttypes.h>
-#else
-#include <stdint.h>
-#endif
-#else
-typedef unsigned __int32 uint32_t;
-#endif
+#include "util.h"
 
 enum {
        CNK_INVALID,            /* this shouldn't appear in files */
index 9250b3e..e62a580 100644 (file)
@@ -1,6 +1,6 @@
 /*
 goat3d - 3D scene, and animation file format library.
-Copyright (C) 2013-2018  John Tsiombikas <nuclear@member.fsf.org>
+Copyright (C) 2013-2023  John Tsiombikas <nuclear@member.fsf.org>
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
index 368ae75..cad023d 100644 (file)
@@ -22,6 +22,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "log.h"
 #include "dynarr.h"
 #include "track.h"
+#include "util.h"
 
 #if defined(__WATCOMC__) || defined(_WIN32) || defined(__DJGPP__)
 #include <malloc.h>
@@ -45,9 +46,6 @@ static int read_node(struct goat3d *g, struct goat3d_node *node, struct ts_node
 static int read_anim(struct goat3d *g, struct ts_node *tsanim);
 static struct goat3d_track *read_track(struct goat3d *g, struct ts_node *tstrk);
 
-GOAT3DAPI void *goat3d_b64decode(const char *str, void *buf, int *bufsz);
-#define b64decode goat3d_b64decode
-
 
 int g3dimpl_scnload(struct goat3d *g, struct goat3d_io *io)
 {
@@ -380,14 +378,6 @@ fail:
        return 0;
 }
 
-static int calc_b64_size(const char *s)
-{
-       int len = strlen(s);
-       const char *end = s + len;
-       while(end > s && *--end == '=') len--;
-       return len * 3 / 4;
-}
-
 static void *read_veclist(void *arr, int dim, const char *nodename, const char *attrname, struct ts_node *tslist)
 {
        int i, size, bufsz;
@@ -414,6 +404,9 @@ static void *read_veclist(void *arr, int dim, const char *nodename, const char *
 
                bufsz = size * dim * sizeof(float);
                b64decode(str, arr, &bufsz);
+#ifdef GOAT3D_BIGEND
+               goat3d_bswap32(arr, size * dim);
+#endif
        }
 
        c = tslist->child_list;
@@ -473,6 +466,9 @@ static void *read_intlist(void *arr, int dim, const char *nodename, const char *
 
                bufsz = size * dim * sizeof(int);
                b64decode(str, arr, &bufsz);
+#ifdef GOAT3D_BIGEND
+               goat3d_bswap32(arr, size * dim);
+#endif
        }
 
        c = tslist->child_list;
@@ -772,78 +768,3 @@ static struct goat3d_track *read_track(struct goat3d *g, struct ts_node *tstrk)
 
        return trk;
 }
-
-static int b64bits(int c)
-{
-       if(c >= 'A' && c <= 'Z') {
-               return c - 'A';
-       }
-       if(c >= 'a' && c <= 'z') {
-               return c - 'a' + 26;
-       }
-       if(c >= '0' && c <= '9') {
-               return c - '0' + 52;
-       }
-       if(c == '+') return 62;
-       if(c == '/') return 63;
-
-       return -1;
-}
-
-GOAT3DAPI void *goat3d_b64decode(const char *str, void *buf, int *bufsz)
-{
-       unsigned char *dest, *end;
-       unsigned char acc;
-       int bits, sz;
-       unsigned int gidx;
-
-       if(buf) {
-               sz = *bufsz;
-       } else {
-               sz = calc_b64_size(str);
-               if(!(buf = malloc(sz))) {
-                       return 0;
-               }
-               if(bufsz) *bufsz = sz;
-       }
-       dest = buf;
-       end = (unsigned char*)buf + sz;
-
-       sz = 0;
-       gidx = 0;
-       acc = 0;
-       while(*str) {
-               if((bits = b64bits(*str++)) == -1) {
-                       continue;
-               }
-
-               switch(gidx++ & 3) {
-               case 0:
-                       acc = bits << 2;
-                       break;
-               case 1:
-                       if(dest < end) *dest = acc | (bits >> 4);
-                       dest++;
-                       acc = bits << 4;
-                       break;
-               case 2:
-                       if(dest < end) *dest = acc | (bits >> 2);
-                       dest++;
-                       acc = bits << 6;
-                       break;
-               case 3:
-                       if(dest < end) *dest = acc | bits;
-                       dest++;
-               default:
-                       break;
-               }
-       }
-
-       if(gidx & 3) {
-               if(dest < end) *dest = acc;
-               dest++;
-       }
-
-       if(bufsz) *bufsz = dest - (unsigned char*)buf;
-       return buf;
-}
diff --git a/libs/goat3d/src/util.c b/libs/goat3d/src/util.c
new file mode 100644 (file)
index 0000000..ece922a
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+goat3d - 3D scene, and animation file format library.
+Copyright (C) 2013-2023  John Tsiombikas <nuclear@member.fsf.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdlib.h>
+#include "util.h"
+
+static int b64bits(int c);
+
+int calc_b64_size(const char *s)
+{
+       int len = strlen(s);
+       const char *end = s + len;
+       while(end > s && *--end == '=') len--;
+       return len * 3 / 4;
+}
+
+
+GOAT3DAPI void *goat3d_b64decode(const char *str, void *buf, int *bufsz)
+{
+       unsigned char *dest, *end;
+       unsigned char acc;
+       int bits, sz;
+       unsigned int gidx;
+
+       if(buf) {
+               sz = *bufsz;
+       } else {
+               sz = calc_b64_size(str);
+               if(!(buf = malloc(sz))) {
+                       return 0;
+               }
+               if(bufsz) *bufsz = sz;
+       }
+       dest = buf;
+       end = (unsigned char*)buf + sz;
+
+       sz = 0;
+       gidx = 0;
+       acc = 0;
+       while(*str) {
+               if((bits = b64bits(*str++)) == -1) {
+                       continue;
+               }
+
+               switch(gidx++ & 3) {
+               case 0:
+                       acc = bits << 2;
+                       break;
+               case 1:
+                       if(dest < end) *dest = acc | (bits >> 4);
+                       dest++;
+                       acc = bits << 4;
+                       break;
+               case 2:
+                       if(dest < end) *dest = acc | (bits >> 2);
+                       dest++;
+                       acc = bits << 6;
+                       break;
+               case 3:
+                       if(dest < end) *dest = acc | bits;
+                       dest++;
+               default:
+                       break;
+               }
+       }
+
+       if(gidx & 3) {
+               if(dest < end) *dest = acc;
+               dest++;
+       }
+
+       if(bufsz) *bufsz = dest - (unsigned char*)buf;
+       return buf;
+}
+
+static int b64bits(int c)
+{
+       if(c >= 'A' && c <= 'Z') {
+               return c - 'A';
+       }
+       if(c >= 'a' && c <= 'z') {
+               return c - 'a' + 26;
+       }
+       if(c >= '0' && c <= '9') {
+               return c - '0' + 52;
+       }
+       if(c == '+') return 62;
+       if(c == '/') return 63;
+
+       return -1;
+}
+
+GOAT3DAPI void goat3d_bswap32(void *buf, int count)
+{
+       int i;
+       register uint32_t x;
+       uint32_t *ptr = buf;
+
+       for(i=0; i<count; i++) {
+               x = *ptr;
+               *ptr++ = (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000);
+       }
+}
diff --git a/libs/goat3d/src/util.h b/libs/goat3d/src/util.h
new file mode 100644 (file)
index 0000000..66b9d9e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+goat3d - 3D scene, and animation file format library.
+Copyright (C) 2013-2023  John Tsiombikas <nuclear@member.fsf.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef GOAT3D_UTIL_H_
+#define GOAT3D_UTIL_H_
+
+#include "goat3d.h"
+
+#ifndef _MSC_VER
+#ifdef __sgi
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+#else
+typedef unsigned __int32 uint32_t;
+#endif
+
+#if defined(__mips)
+#define GOAT3D_BIGEND
+#endif
+
+int calc_b64_size(const char *s);
+
+GOAT3DAPI void *goat3d_b64decode(const char *str, void *buf, int *bufsz);
+#define b64decode goat3d_b64decode
+
+GOAT3DAPI void goat3d_bswap32(void *buf, int count);
+
+#endif /* GOAT3D_UTIL_H_ */
index 5b9f4bf..be0139f 100644 (file)
@@ -34,7 +34,10 @@ static int dlist;
 
 static int ginit(void)
 {
-       int i, num, nfaces;
+       int i, j, num, nfaces;
+       int *idxarr;
+       float *varr, *narr, *uvarr;
+       float xform[16];
 
        if(!(gscn = goat3d_create()) || goat3d_load(gscn, "data/track1.g3d")) {
                return -1;
@@ -48,24 +51,35 @@ static int ginit(void)
                if(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
                        struct goat3d_mesh *mesh = goat3d_get_node_object(node);
 
+                       goat3d_get_node_matrix(node, xform);
+                       glPushMatrix();
+                       glMultMatrixf(xform);
+
+                       varr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
+                       narr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
+                       uvarr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
+
                        glEnableClientState(GL_VERTEX_ARRAY);
-                       glVertexPointer(3, GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX));
+                       glVertexPointer(3, GL_FLOAT, 0, varr);
 
-                       if(goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_NORMAL)) {
+                       if(narr) {
                                glEnableClientState(GL_NORMAL_ARRAY);
-                               glNormalPointer(GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL));
+                               glNormalPointer(GL_FLOAT, 0, narr);
                        }
-                       if(goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_TEXCOORD)) {
+                       if(uvarr) {
                                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-                               glTexCoordPointer(2, GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD));
+                               glTexCoordPointer(2, GL_FLOAT, 0, uvarr);
                        }
 
-                       nfaces = goat3d_get_mesh_face_count(mesh) / 3;
-                       glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, goat3d_get_mesh_faces(mesh));
+                       nfaces = goat3d_get_mesh_face_count(mesh);
+                       idxarr = goat3d_get_mesh_faces(mesh);
+                       glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, idxarr);
 
                        glDisableClientState(GL_VERTEX_ARRAY);
                        glDisableClientState(GL_NORMAL_ARRAY);
                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+                       glPopMatrix();
                }
        }
        glEndList();