From 5b749ebf19baa36e2243f9dd3f9c8382ac261025 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 27 Aug 2019 21:19:57 -0500 Subject: [PATCH] New J3D binary file format. New crash bug. --- .gitignore | 4 +- BuildTables/.gitignore | 73 ++++++ BuildTables/BuildTables.pro | 7 + BuildTables/main.c | 94 +++++++ j3d/LICENSE | 20 ++ j3d/README.md | 4 + build-All.sh => j3d/build-All.sh | 4 +- cube.obj => j3d/cube.obj | 0 font.xcf => j3d/font.xcf | 0 j3d.c => j3d/j3d.c | 236 +++++++++-------- j3d.h => j3d/j3d.h | 11 +- j3d.pro => j3d/j3d.pro | 4 +- j3d/j3dtbls.h | 156 +++++++++++ j3d/main.c | 141 ++++++++++ j3d/notes.txt | 11 + postlink.sh => j3d/postlink.sh | 4 +- main.c | 103 -------- obj2j3d/main.c | 166 ++++++++++++ obj2j3d/obj2j3d.pro | 17 ++ .../stretchy_buffer.h | 0 utarray.h | 247 ------------------ 21 files changed, 834 insertions(+), 468 deletions(-) create mode 100644 BuildTables/.gitignore create mode 100644 BuildTables/BuildTables.pro create mode 100644 BuildTables/main.c create mode 100644 j3d/LICENSE create mode 100644 j3d/README.md rename build-All.sh => j3d/build-All.sh (82%) rename cube.obj => j3d/cube.obj (100%) rename font.xcf => j3d/font.xcf (100%) rename j3d.c => j3d/j3d.c (76%) rename j3d.h => j3d/j3d.h (91%) rename j3d.pro => j3d/j3d.pro (89%) create mode 100644 j3d/j3dtbls.h create mode 100644 j3d/main.c create mode 100644 j3d/notes.txt rename postlink.sh => j3d/postlink.sh (68%) delete mode 100644 main.c create mode 100644 obj2j3d/main.c create mode 100644 obj2j3d/obj2j3d.pro rename stretchy_buffer.h => obj2j3d/stretchy_buffer.h (100%) delete mode 100644 utarray.h diff --git a/.gitignore b/.gitignore index 8766f23..279526d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ -*.~ +*~ *.user *.sta *.dis *.lnk *.map *.sym +*.j3d +build-* diff --git a/BuildTables/.gitignore b/BuildTables/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/BuildTables/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/BuildTables/BuildTables.pro b/BuildTables/BuildTables.pro new file mode 100644 index 0000000..8b6e209 --- /dev/null +++ b/BuildTables/BuildTables.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + main.c diff --git a/BuildTables/main.c b/BuildTables/main.c new file mode 100644 index 0000000..9d6ac6b --- /dev/null +++ b/BuildTables/main.c @@ -0,0 +1,94 @@ +/* + * JoeyLib 3D + * Copyright (C) 2019 Scott Duensing + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include + + +#define J3D_M_PI 3.1415926 + + +int main(void) { + int pass; + int count; + int euler; + float radian; + FILE *out; + + out = fopen("j3dtbls.h", "wt"); + if (!out) { + printf("Unable to create output file!\n"); + return 1; + } + + fprintf(out, \ + "/*\n" \ + " * JoeyLib 3D\n" \ + " * Copyright (C) 2019 Scott Duensing \n" \ + " *\n" \ + " * This software is provided 'as-is', without any express or implied\n" \ + " * warranty. In no event will the authors be held liable for any damages\n" \ + " * arising from the use of this software.\n" \ + " *\n" \ + " * Permission is granted to anyone to use this software for any purpose,\n" \ + " * including commercial applications, and to alter it and redistribute it\n" \ + " * freely, subject to the following restrictions:\n" \ + " *\n" \ + " * 1. The origin of this software must not be misrepresented; you must not\n" \ + " * claim that you wrote the original software. If you use this software\n" \ + " * in a product, an acknowledgment in the product documentation would be\n" \ + " * appreciated but is not required.\n" \ + " * 2. Altered source versions must be plainly marked as such, and must not be\n" \ + " * misrepresented as being the original software.\n" \ + " * 3. This notice may not be removed or altered from any source distribution.\n" \ + "*/\n\n\n" \ + "#ifndef H_J3DTBLS_\n" \ + "#define H_J3DTBLS_\n\n\nstatic float sin_table[] = {\n\t" \ + ); + + // Build look-up tables for speed later + for (pass=0; pass<2; pass++) { + count = 0; + for (euler=0; euler<361; euler++) { + radian = ((float)J3D_M_PI * (float)euler / (float)180); + if (euler != 0) { + fprintf(out, ", "); + } + if (count > 5) { + count = 0; + fprintf(out, "\n\t"); + } + fprintf(out, "%10.7f", pass == 0 ? sin((double)radian) : cos((double)radian)); + count++; + } + fprintf(out, "\n};\n\n"); + if (pass == 0) { + fprintf(out, "static float cos_table[] = {\n\t"); + } + } + + fprintf(out, "\n#endif // H_J3DTBLS_\n"); + + fclose(out); + + return 0; +} diff --git a/j3d/LICENSE b/j3d/LICENSE new file mode 100644 index 0000000..e41bd59 --- /dev/null +++ b/j3d/LICENSE @@ -0,0 +1,20 @@ +/* + * JoeyLib3D + * Copyright (C) 2019 Scott Duensing + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +*/ \ No newline at end of file diff --git a/j3d/README.md b/j3d/README.md new file mode 100644 index 0000000..f623792 --- /dev/null +++ b/j3d/README.md @@ -0,0 +1,4 @@ +Basic 3D Library for JoeyLib + +https://skunkworks.kangaroopunch.com/skunkworks/joeylib3d +https://skunkworks.kangaroopunch.com/skunkworks/joeylib diff --git a/build-All.sh b/j3d/build-All.sh similarity index 82% rename from build-All.sh rename to j3d/build-All.sh index 290ba36..854ac30 100755 --- a/build-All.sh +++ b/j3d/build-All.sh @@ -2,10 +2,12 @@ PROJECT=j3d GAME=${JOEY}/j3d/j3d -DATA=(${GAME}/cube.obj ${GAME}/font.sta) +DATA=(${GAME}/cube.j3d ${GAME}/font.sta) #SOURCE=(*.c *.h) SOURCE=() +# ***TODO*** Automatically convert OBJ to J3D + pushd "${GAME}" find . -type f -name "*.xcf" -exec ${JOEY}/utils/xcf2sta.sh {} \; popd diff --git a/cube.obj b/j3d/cube.obj similarity index 100% rename from cube.obj rename to j3d/cube.obj diff --git a/font.xcf b/j3d/font.xcf similarity index 100% rename from font.xcf rename to j3d/font.xcf diff --git a/j3d.c b/j3d/j3d.c similarity index 76% rename from j3d.c rename to j3d/j3d.c index 9395677..d35f1a9 100644 --- a/j3d.c +++ b/j3d/j3d.c @@ -30,9 +30,8 @@ #include #include -#include "stretchy_buffer.h" - #include "j3d.h" +#include "j3dtbls.h" #ifdef JOEY_IIGS @@ -50,13 +49,11 @@ segment "j3d"; // Module global data -static float sin_table[361]; -static float cos_table[361]; -static int clipMinX = 0; -static int clipMinY = 0; -static int clipMaxX = 319; -static int clipMaxY = 199; -static int viewDistance = 250; +static jint16 clipMinX = 0; +static jint16 clipMinY = 0; +static jint16 clipMaxX = 319; +static jint16 clipMaxY = 199; +static jint16 viewDistance = 250; #define ASPECT_RATIO (float)0.8 @@ -66,17 +63,17 @@ static int viewDistance = 250; #define HALF_SCREEN_HEIGHT 100 -void _j3DrawWireframePair(j3ObjectT *o, int v1, int v2) { +void _j3DrawWireframePair(j3ObjectT *o, juint16 v1, juint16 v2) { float x1; float y1; float z1; float x2; float y2; float z2; - int ix1; - int iy1; - int ix2; - int iy2; + jint16 ix1; + jint16 iy1; + jint16 ix2; + jint16 iy2; j3VertexT v; v = o->verticies[v1].camera; @@ -95,19 +92,19 @@ void _j3DrawWireframePair(j3ObjectT *o, int v1, int v2) { x2 = HALF_SCREEN_WIDTH + x2 * viewDistance / z2; y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * viewDistance / z2; - ix1 = (int)x1; - iy1 = (int)y1; - ix2 = (int)x2; - iy2 = (int)y2; + ix1 = (jint16)x1; + iy1 = (jint16)y1; + ix2 = (jint16)x2; + iy2 = (jint16)y2; if (_j3UtilClipLine(&ix1, &iy1, &ix2, &iy2)) { - jlDrawLine((jint16)ix1, (jint16)iy1, (jint16)ix2, (jint16)iy2); + jlDrawLine(ix1, iy1, ix2, iy2); } } void _j3DrawWireframe(j3ObjectT *o) { - int t; // Current triangle + jint16 t; // Current triangle for (t=0; ttriangleCount; t++) { _j3DrawWireframePair(o, o->triangles[t].index[0], o->triangles[t].index[1]); @@ -164,11 +161,11 @@ void _j3ObjectReset(j3ObjectT *o) { void _j3ObjectUpdate(j3ObjectT *o) { - int x; - int y; - int z; - int i; - int axis = 0; + jint16 x; + jint16 y; + jint16 z; + jint16 i; + byte axis = 0; j3Matrix4x4T rotateX; j3Matrix4x4T rotateY; j3Matrix4x4T rotateZ; @@ -177,9 +174,9 @@ void _j3ObjectUpdate(j3ObjectT *o) { // === ROTATION === - x = (int)o->rotation.x; - y = (int)o->rotation.y; - z = (int)o->rotation.z; + x = (jint16)o->rotation.x; + y = (jint16)o->rotation.y; + z = (jint16)o->rotation.z; j3MathMatrix4x4Identity(final); @@ -332,18 +329,18 @@ void _j3ObjectUpdate(j3ObjectT *o) { } -bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { - int xi; - int yi; - float dx; - float dy; - bool point1 = false; // End points visible? - bool point2 = false; - bool rightEdge = false; // Which edges are the endpoints beyond? - bool leftEdge = false; - bool topEdge = false; - bool bottomEdge = false; - bool success = false; // Did we successfully clip this line? +bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) { + jint16 xi; + jint16 yi; + float dx; + float dy; + bool point1 = false; // End points visible? + bool point2 = false; + bool rightEdge = false; // Which edges are the endpoints beyond? + bool leftEdge = false; + bool topEdge = false; + bool bottomEdge = false; + bool success = false; // Did we successfully clip this line? // Is the line completely visible? point1 = ((*x1 >= clipMinX) && (*x1 <= clipMaxX) && (*y1 >= clipMinY) && (*y1 <= clipMaxY)); @@ -380,7 +377,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { rightEdge = true; // Find intersection with right edge if (fabsf(dx) > FLT_EPSILON) { // dx != 0 - yi = (int)((float)0.5 + (dy / dx) * (clipMaxX - *x1) + *y1); + yi = (jint16)((float)0.5 + (dy / dx) * (clipMaxX - *x1) + *y1); } else { yi = -1; // Invalidate intersection } @@ -389,7 +386,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { leftEdge = true; // Find intersection with left edge if (fabsf(dx) > FLT_EPSILON) { // dx != 0 - yi = (int)((float)0.5 + (dy / dx) * (clipMinX - *x1) + *y1); + yi = (jint16)((float)0.5 + (dy / dx) * (clipMinX - *x1) + *y1); } else { yi = -1; // Invalidate intersection } @@ -400,7 +397,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { bottomEdge = true; // Find intersection with right edge if (fabsf(dy) > FLT_EPSILON) { // dy != 0 - xi = (int)((float)0.5 + (dx / dy) * (clipMaxY - *y1) + *x1); + xi = (jint16)((float)0.5 + (dx / dy) * (clipMaxY - *y1) + *x1); } else { xi = -1; // Invalidate inntersection } @@ -409,7 +406,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { topEdge = true; // Find intersection with top edge if (fabsf(dy) > FLT_EPSILON) { // dy != 0 - xi = (int)((float)0.5 + (dx / dy) * (clipMinY - *y1) + *x1); + xi = (jint16)((float)0.5 + (dx / dy) * (clipMinY - *y1) + *x1); } else { xi = -1; // Invalidate intersection } @@ -458,7 +455,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { rightEdge = true; // Find intersection with right edge if (fabsf(dx) > FLT_EPSILON) { // dx != 0 - yi = (int)((float)0.5 + (dy / dx) * (clipMaxX - *x2) + *y2); + yi = (jint16)((float)0.5 + (dy / dx) * (clipMaxX - *x2) + *y2); } else { yi = -1; // Invalidate inntersection } @@ -467,7 +464,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { leftEdge = true; // Find intersection with left edge if (fabsf(dx) > FLT_EPSILON) { // dx != 0 - yi = (int)((float)0.5 + (dy / dx) * (clipMinX - *x2) + *y2); + yi = (jint16)((float)0.5 + (dy / dx) * (clipMinX - *x2) + *y2); } else { yi = -1; // Invalidate intersection } @@ -478,7 +475,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { bottomEdge = true; // Find intersection with right edge if (fabsf(dy) > FLT_EPSILON) { // dy != 0 - xi = (int)((float)0.5 + (dx / dy) * (clipMaxY - *y2) + *x2); + xi = (jint16)((float)0.5 + (dx / dy) * (clipMaxY - *y2) + *x2); } else { xi = -1; // invalidate inntersection } @@ -487,7 +484,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { topEdge = true; // Find intersection with top edge if (fabsf(dy) > FLT_EPSILON) { // dy != 0 - xi = (int)((float)0.5 + (dx / dy) * (clipMinY - *y2) + *x2); + xi = (jint16)((float)0.5 + (dx / dy) * (clipMinY - *y2) + *x2); } else { xi = -1; // invalidate inntersection } @@ -527,41 +524,39 @@ void j3UtilShutdown(void) { void j3UtilStartup(void) { - int euler; - float radian; - - // Build look-up tables for speed later - for (euler=0; euler<361; euler++) { - radian = ((float)M_PI * (float)euler / (float)180); - sin_table[euler] = (float)sin((double)radian); - cos_table[euler] = (float)cos((double)radian); - } + // Nothing yet } void _j3WorldFree(j3WorldT **world) { int x; - for (x=0; xobjects); x++) { - sb_free((*world)->objects[x].triangles); - sb_free((*world)->objects[x].verticies); + if ((*world)) { + for (x=0; x<(*world)->objectCount; x++) { + if ((*world)->objects[x].triangles) { + jlFree((*world)->objects[x].triangles); + } + if ((*world)->objects[x].verticies) { + jlFree((*world)->objects[x].verticies); + } + } + if ((*world)->objects) { + jlFree((*world)->objects); + } + jlFree(*world); } - sb_free((*world)->objects); - jlFree(*world); } bool _j3WorldLoad(j3WorldT **world, char *file) { - int r; - int x; - char token[1024]; - char *c; + jint16 x; + jint16 y; + jint16 z; + byte buffer[4]; FILE *in; - j3CoordinatesT v; - j3ObjectT o; - j3TriangleT t; + bool failed = false; - in = fopen(jlUtilMakePathname(file, "obj"), "rt"); + in = fopen(jlUtilMakePathname(file, "j3d"), "rb"); // Did we find the file? if (in == NULL) { @@ -577,56 +572,81 @@ bool _j3WorldLoad(j3WorldT **world, char *file) { // Allocate world object *world = (j3WorldT *)jlMalloc(sizeof(j3WorldT)); + if (*world) { + // Initialize world object & create an initial object to read data into + (*world)->objectCount = 0;; + (*world)->objects = NULL; - // Initialize world object & create an initial object to read data into - (*world)->objects = NULL; - o.vertexCount = 0; - o.triangleCount = 0; - o.verticies = NULL; - o.triangles = NULL; + // Is this a valid world file? + if (fread(buffer, sizeof(byte), 4, in) == 4) { + if ((buffer[0] == 'J') && (buffer[1] == '3') && (buffer[2] == 'D') && (buffer[3] <= 0)) { - _j3ObjectReset(&o); + // Get object count + if (fread(&(*world)->objectCount, sizeof(juint16), 1, in) == 1) { - while (true) { + // Allocate memory for objects + (*world)->objects = (j3ObjectT *)jlMalloc(sizeof(j3ObjectT)); + if ((*world)->objects) { - // Read next token - r = fscanf(in, "%s", token); + // Iterate across objects in file + for (x=0; x<(*world)->objectCount; x++) { - // End of file? - if (r == EOF) { - break; - } + // Allocate memory for object elements + (*world)->objects->verticies = (j3CoordinatesT *)jlMalloc(sizeof(j3CoordinatesT)); + (*world)->objects->triangles = (j3TriangleT *)jlMalloc(sizeof(j3TriangleT)); + if ((*world)->objects->verticies && (*world)->objects->triangles) { - // Vertex? - if (strcmp(token, "v" ) == 0) { - r = fscanf(in, "%f %f %f\n", &v.local.x, &v.local.y, &v.local.z); - sb_push(o.verticies, v); - o.vertexCount++; - } + _j3ObjectReset(&(*world)->objects[x]); - // Face? - if (strcmp(token, "f" ) == 0) { - for (x=0; x<3; x++) { - // Fetch 'x'th vertex index - r = fscanf(in, "%s", token); - c = strstr(token, "/"); - if (c) c[0] = 0; - r = atoi(token); - t.index[x] = r - 1; - } - fscanf(in, "\n"); - sb_push(o.triangles, t); - o.triangleCount++; - } - } + // Get vertex count + if (fread(&(*world)->objects[x].vertexCount, sizeof(juint16), 1, in) == 1) { + // Iterate and read verticies + for (y=0; y<(*world)->objects[x].vertexCount; y++) { + // Read one at a time in case the struct gets padded + if (fread(&(*world)->objects[x].verticies[y].local.x, sizeof(float), 1, in) != 1) { + failed = true; + break; + } + if (fread(&(*world)->objects[x].verticies[y].local.y, sizeof(float), 1, in) != 1) { + failed = true; + break; + } + if (fread(&(*world)->objects[x].verticies[y].local.z, sizeof(float), 1, in) != 1) { + failed = true; + break; + } + } + } - //***TODO*** support multiple objects - not sure how I want to do this yet - sb_push((*world)->objects, o); + if (!failed) { + // Get triangle count + if (fread(&(*world)->objects[x].triangleCount, sizeof(juint16), 1, in) == 1) { + // Iterate and read triangles + for (y=0; y<(*world)->objects[x].triangleCount; y++) { + // Read one at a time in case the struct gets padded + for (z=0; z<3; z++) { + if (fread(&(*world)->objects[x].triangles[y].index[z], sizeof(juint16), 1, in) != 1) { + failed = true; + break; + } + } + if (failed) break; + } + } + } + + } // vertex & triangle alloc + } // object iterator + } // objects alloc + } // Object count + } // Valid file + } // Read header + } // world alloc // Finished! Clean up. fclose(in); - return true; + return !failed; } #ifndef JOEY_IIGS diff --git a/j3d.h b/j3d/j3d.h similarity index 91% rename from j3d.h rename to j3d/j3d.h index 57d11ea..8e1fc99 100644 --- a/j3d.h +++ b/j3d/j3d.h @@ -42,12 +42,12 @@ typedef struct { } j3CoordinatesT; typedef struct { - int index[3]; // We do this instead of just a typedef so it works with stretch_buffer + juint16 index[3]; // We do this instead of just a typedef so it works with stretch_buffer } j3TriangleT; typedef struct { - int vertexCount; // How many verticies are in the list - int triangleCount; // How many triangles are in the list + juint16 vertexCount; // How many verticies are in the list + juint16 triangleCount; // How many triangles are in the list j3CoordinatesT *verticies; // List of verticies as loaded from disk (more v1, v2, v3 than x, y, z) j3TriangleT *triangles; // Triangles built from vertex list j3VertexT position; // Position of object in world @@ -56,6 +56,7 @@ typedef struct { } j3ObjectT; typedef struct { + juint16 objectCount; j3ObjectT *objects; } j3WorldT; @@ -121,11 +122,11 @@ void j3UtilStartup(void); // Private Prototypes -void _j3DrawWireframePair(j3ObjectT *o, int v1, int v2); +void _j3DrawWireframePair(j3ObjectT *o, juint16 v1, juint16 v2); void _j3DrawWireframe(j3ObjectT *o); void _j3ObjectReset(j3ObjectT *o); void _j3ObjectUpdate(j3ObjectT *o); -bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2); +bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2); void _j3WorldFree(j3WorldT **world); bool _j3WorldLoad(j3WorldT **world, char *file); diff --git a/j3d.pro b/j3d/j3d.pro similarity index 89% rename from j3d.pro rename to j3d/j3d.pro index 4d7dfb0..6dc5068 100644 --- a/j3d.pro +++ b/j3d/j3d.pro @@ -2,8 +2,8 @@ JOEY = /home/scott/joey include($$JOEY/dist/joey.pri) HEADERS += \ - stretchy_buffer.h \ - j3d.h + j3d.h \ + j3dtbls.h SOURCES += \ main.c \ diff --git a/j3d/j3dtbls.h b/j3d/j3dtbls.h new file mode 100644 index 0000000..1efd044 --- /dev/null +++ b/j3d/j3dtbls.h @@ -0,0 +1,156 @@ +/* + * JoeyLib 3D + * Copyright (C) 2019 Scott Duensing + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef H_J3DTBLS_ +#define H_J3DTBLS_ + + +static float sin_table[] = { + 0.0000000, 0.0174524, 0.0348995, 0.0523360, 0.0697565, 0.0871557, + 0.1045285, 0.1218693, 0.1391731, 0.1564345, 0.1736482, 0.1908090, + 0.2079117, 0.2249510, 0.2419219, 0.2588190, 0.2756374, 0.2923717, + 0.3090170, 0.3255682, 0.3420201, 0.3583679, 0.3746066, 0.3907311, + 0.4067367, 0.4226182, 0.4383711, 0.4539905, 0.4694715, 0.4848096, + 0.5000000, 0.5150381, 0.5299193, 0.5446390, 0.5591929, 0.5735764, + 0.5877852, 0.6018150, 0.6156615, 0.6293204, 0.6427875, 0.6560590, + 0.6691306, 0.6819983, 0.6946584, 0.7071068, 0.7193398, 0.7313537, + 0.7431448, 0.7547096, 0.7660444, 0.7771459, 0.7880107, 0.7986355, + 0.8090170, 0.8191520, 0.8290375, 0.8386706, 0.8480481, 0.8571673, + 0.8660254, 0.8746197, 0.8829476, 0.8910065, 0.8987940, 0.9063077, + 0.9135454, 0.9205048, 0.9271838, 0.9335804, 0.9396926, 0.9455185, + 0.9510565, 0.9563047, 0.9612617, 0.9659258, 0.9702957, 0.9743700, + 0.9781476, 0.9816272, 0.9848077, 0.9876883, 0.9902681, 0.9925461, + 0.9945219, 0.9961947, 0.9975640, 0.9986295, 0.9993908, 0.9998477, + 1.0000000, 0.9998477, 0.9993908, 0.9986295, 0.9975641, 0.9961947, + 0.9945219, 0.9925462, 0.9902681, 0.9876883, 0.9848078, 0.9816272, + 0.9781476, 0.9743701, 0.9702958, 0.9659258, 0.9612617, 0.9563048, + 0.9510565, 0.9455186, 0.9396927, 0.9335805, 0.9271839, 0.9205049, + 0.9135455, 0.9063079, 0.8987941, 0.8910066, 0.8829476, 0.8746197, + 0.8660255, 0.8571673, 0.8480482, 0.8386707, 0.8290376, 0.8191522, + 0.8090170, 0.7986356, 0.7880108, 0.7771460, 0.7660446, 0.7547096, + 0.7431449, 0.7313537, 0.7193399, 0.7071068, 0.6946584, 0.6819985, + 0.6691306, 0.6560591, 0.6427878, 0.6293205, 0.6156616, 0.6018151, + 0.5877854, 0.5735765, 0.5591930, 0.5446392, 0.5299193, 0.5150382, + 0.5000002, 0.4848097, 0.4694716, 0.4539906, 0.4383713, 0.4226183, + 0.4067368, 0.3907314, 0.3746067, 0.3583679, 0.3420204, 0.3255683, + 0.3090170, 0.2923718, 0.2756374, 0.2588189, 0.2419221, 0.2249513, + 0.2079118, 0.1908090, 0.1736483, 0.1564344, 0.1391734, 0.1218695, + 0.1045287, 0.0871559, 0.0697565, 0.0523360, 0.0348995, 0.0174527, + 0.0000002, -0.0174522, -0.0348994, -0.0523357, -0.0697564, -0.0871558, + -0.1045282, -0.1218692, -0.1391729, -0.1564344, -0.1736480, -0.1908089, + -0.2079118, -0.2249508, -0.2419216, -0.2588188, -0.2756373, -0.2923715, + -0.3090170, -0.3255678, -0.3420199, -0.3583677, -0.3746064, -0.3907311, + -0.4067365, -0.4226183, -0.4383708, -0.4539903, -0.4694713, -0.4848095, + -0.5000000, -0.5150380, -0.5299193, -0.5446388, -0.5591928, -0.5735762, + -0.5877851, -0.6018150, -0.6156614, -0.6293201, -0.6427874, -0.6560589, + -0.6691304, -0.6819983, -0.6946582, -0.7071067, -0.7193395, -0.7313535, + -0.7431447, -0.7547094, -0.7660442, -0.7771460, -0.7880107, -0.7986354, + -0.8090169, -0.8191518, -0.8290376, -0.8386705, -0.8480480, -0.8571672, + -0.8660252, -0.8746195, -0.8829476, -0.8910064, -0.8987939, -0.9063078, + -0.9135453, -0.9205048, -0.9271838, -0.9335803, -0.9396925, -0.9455186, + -0.9510565, -0.9563047, -0.9612616, -0.9659257, -0.9702957, -0.9743700, + -0.9781476, -0.9816272, -0.9848077, -0.9876883, -0.9902680, -0.9925461, + -0.9945219, -0.9961947, -0.9975640, -0.9986295, -0.9993908, -0.9998477, + -1.0000000, -0.9998477, -0.9993908, -0.9986295, -0.9975641, -0.9961947, + -0.9945219, -0.9925462, -0.9902681, -0.9876883, -0.9848078, -0.9816272, + -0.9781476, -0.9743701, -0.9702958, -0.9659258, -0.9612617, -0.9563048, + -0.9510566, -0.9455187, -0.9396926, -0.9335805, -0.9271840, -0.9205048, + -0.9135456, -0.9063080, -0.8987941, -0.8910066, -0.8829478, -0.8746197, + -0.8660257, -0.8571674, -0.8480483, -0.8386708, -0.8290376, -0.8191521, + -0.8090171, -0.7986357, -0.7880110, -0.7771463, -0.7660445, -0.7547097, + -0.7431450, -0.7313537, -0.7193402, -0.7071069, -0.6946585, -0.6819986, + -0.6691306, -0.6560591, -0.6427881, -0.6293206, -0.6156618, -0.6018154, + -0.5877853, -0.5735766, -0.5591931, -0.5446390, -0.5299193, -0.5150382, + -0.4999998, -0.4848103, -0.4694719, -0.4539909, -0.4383717, -0.4226185, + -0.4067369, -0.3907315, -0.3746066, -0.3583681, -0.3420204, -0.3255680, + -0.3090169, -0.2923718, -0.2756380, -0.2588197, -0.2419222, -0.2249515, + -0.2079122, -0.1908092, -0.1736484, -0.1564348, -0.1391731, -0.1218694, + -0.1045286, -0.0871560, -0.0697564, -0.0523360, -0.0349001, -0.0174531, + -0.0000003 +}; + +static float cos_table[] = { + 1.0000000, 0.9998477, 0.9993908, 0.9986295, 0.9975641, 0.9961947, + 0.9945219, 0.9925462, 0.9902681, 0.9876883, 0.9848078, 0.9816272, + 0.9781476, 0.9743701, 0.9702957, 0.9659258, 0.9612617, 0.9563048, + 0.9510565, 0.9455186, 0.9396926, 0.9335804, 0.9271839, 0.9205049, + 0.9135455, 0.9063078, 0.8987941, 0.8910065, 0.8829476, 0.8746197, + 0.8660254, 0.8571673, 0.8480481, 0.8386706, 0.8290376, 0.8191521, + 0.8090170, 0.7986355, 0.7880108, 0.7771460, 0.7660445, 0.7547096, + 0.7431449, 0.7313538, 0.7193398, 0.7071068, 0.6946584, 0.6819984, + 0.6691306, 0.6560590, 0.6427877, 0.6293204, 0.6156615, 0.6018150, + 0.5877853, 0.5735765, 0.5591929, 0.5446391, 0.5299193, 0.5150381, + 0.5000001, 0.4848097, 0.4694716, 0.4539905, 0.4383712, 0.4226184, + 0.4067367, 0.3907312, 0.3746066, 0.3583680, 0.3420203, 0.3255683, + 0.3090171, 0.2923718, 0.2756374, 0.2588192, 0.2419219, 0.2249512, + 0.2079118, 0.1908091, 0.1736483, 0.1564345, 0.1391731, 0.1218694, + 0.1045285, 0.0871558, 0.0697566, 0.0523361, 0.0348995, 0.0174524, + 0.0000001, -0.0174524, -0.0348995, -0.0523358, -0.0697564, -0.0871557, + -0.1045285, -0.1218692, -0.1391731, -0.1564345, -0.1736481, -0.1908089, + -0.2079116, -0.2249509, -0.2419218, -0.2588190, -0.2756374, -0.2923716, + -0.3090169, -0.3255681, -0.3420200, -0.3583678, -0.3746065, -0.3907309, + -0.4067366, -0.4226181, -0.4383711, -0.4539904, -0.4694716, -0.4848095, + -0.4999998, -0.5150380, -0.5299191, -0.5446388, -0.5591928, -0.5735763, + -0.5877852, -0.6018149, -0.6156615, -0.6293203, -0.6427874, -0.6560590, + -0.6691305, -0.6819983, -0.6946583, -0.7071068, -0.7193397, -0.7313536, + -0.7431448, -0.7547095, -0.7660443, -0.7771459, -0.7880106, -0.7986355, + -0.8090169, -0.8191520, -0.8290375, -0.8386704, -0.8480481, -0.8571672, + -0.8660253, -0.8746196, -0.8829476, -0.8910065, -0.8987940, -0.9063078, + -0.9135454, -0.9205048, -0.9271838, -0.9335804, -0.9396925, -0.9455185, + -0.9510565, -0.9563047, -0.9612617, -0.9659259, -0.9702957, -0.9743700, + -0.9781476, -0.9816272, -0.9848077, -0.9876883, -0.9902680, -0.9925461, + -0.9945219, -0.9961947, -0.9975641, -0.9986295, -0.9993908, -0.9998477, + -1.0000000, -0.9998477, -0.9993908, -0.9986295, -0.9975641, -0.9961947, + -0.9945219, -0.9925462, -0.9902681, -0.9876884, -0.9848078, -0.9816272, + -0.9781476, -0.9743701, -0.9702958, -0.9659259, -0.9612617, -0.9563048, + -0.9510565, -0.9455187, -0.9396927, -0.9335805, -0.9271839, -0.9205049, + -0.9135455, -0.9063078, -0.8987942, -0.8910066, -0.8829477, -0.8746198, + -0.8660254, -0.8571674, -0.8480481, -0.8386707, -0.8290377, -0.8191522, + -0.8090171, -0.7986355, -0.7880108, -0.7771462, -0.7660446, -0.7547097, + -0.7431450, -0.7313538, -0.7193399, -0.7071068, -0.6946587, -0.6819986, + -0.6691307, -0.6560592, -0.6427879, -0.6293204, -0.6156615, -0.6018151, + -0.5877854, -0.5735767, -0.5591929, -0.5446391, -0.5299194, -0.5150383, + -0.5000003, -0.4848100, -0.4694716, -0.4539907, -0.4383714, -0.4226182, + -0.4067371, -0.3907312, -0.3746068, -0.3583682, -0.3420205, -0.3255682, + -0.3090171, -0.2923719, -0.2756377, -0.2588194, -0.2419219, -0.2249512, + -0.2079119, -0.1908089, -0.1736486, -0.1564350, -0.1391733, -0.1218696, + -0.1045288, -0.0871557, -0.0697565, -0.0523361, -0.0348998, -0.0174528, + 0.0000000, 0.0174523, 0.0348993, 0.0523357, 0.0697561, 0.0871553, + 0.1045284, 0.1218691, 0.1391728, 0.1564345, 0.1736477, 0.1908089, + 0.2079115, 0.2249507, 0.2419215, 0.2588190, 0.2756372, 0.2923715, + 0.3090167, 0.3255677, 0.3420201, 0.3583678, 0.3746064, 0.3907312, + 0.4067362, 0.4226178, 0.4383710, 0.4539903, 0.4694712, 0.4848096, + 0.4999995, 0.5150379, 0.5299190, 0.5446387, 0.5591929, 0.5735763, + 0.5877851, 0.6018148, 0.6156612, 0.6293200, 0.6427875, 0.6560589, + 0.6691304, 0.6819984, 0.6946580, 0.7071067, 0.7193396, 0.7313535, + 0.7431448, 0.7547095, 0.7660440, 0.7771458, 0.7880105, 0.7986352, + 0.8090169, 0.8191519, 0.8290374, 0.8386706, 0.8480481, 0.8571672, + 0.8660255, 0.8746193, 0.8829474, 0.8910063, 0.8987938, 0.9063077, + 0.9135453, 0.9205047, 0.9271838, 0.9335804, 0.9396925, 0.9455186, + 0.9510565, 0.9563047, 0.9612615, 0.9659256, 0.9702956, 0.9743700, + 0.9781475, 0.9816272, 0.9848077, 0.9876883, 0.9902681, 0.9925461, + 0.9945219, 0.9961947, 0.9975641, 0.9986295, 0.9993908, 0.9998477, + 1.0000000 +}; + + +#endif // H_J3DTBLS_ diff --git a/j3d/main.c b/j3d/main.c new file mode 100644 index 0000000..2fcc3c6 --- /dev/null +++ b/j3d/main.c @@ -0,0 +1,141 @@ +/* + * JoeyLib 3D + * Copyright (C) 2019 Scott Duensing + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include +#include + +#define JOEY_MAIN +#include "joey.h" + +#ifdef JOEY_IIGS +segment "j3dTest"; +#endif + +#include "j3d.h" + + +void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...); + + +__attribute__((__format__ (__printf__, 4, 0))) +void printAt(jlStaT *font, jint16 cx, jint16 cy, const char *what, ...) { + jint16 x; + jint16 y; + jint16 counter; + char msg[40]; // Very short messages (screen width). Be careful! + va_list va; + + va_start(va, what); + vsprintf(msg, what, va); + va_end(va); + + for (counter=0; counter<(int)strlen(msg); counter++) { + x = msg[counter] % 40; + y = msg[counter] / 40; + jlDrawBlit8x8(font, x, y, counter + cx, cy); + } +} + + +int main(void) { + jint16 x; + jlStaT *font = NULL; + j3WorldT *world = NULL; + bool r; + + jlUtilStartup("JoeyLib 3D"); + jlStaLoad(font, "font"); + + printAt(font, 1, 1, "Starting JoeyLib3D..."); + jlDisplayPresent(); + j3UtilStartup(); + + printAt(font, 1, 1, "Loading object... "); + jlDisplayPresent(); + r = j3WorldLoad(world, "cube"); + if (!r) { + printAt(font, 1, 1, "Object loading: Failed."); + jlDisplayPresent(); + jlKeyWaitForAny(); + } else { + printAt(font, 1, 1, "Object loading: Success!"); + jlDisplayPresent(); + +#ifdef JOEY_LINUX + jint16 y; + printf("Objects: %d\n", world->objectCount); + for (x=0; xobjectCount; x++) { + printf("Object %d:\n", x); + printf(" Verticies: %d\n", world->objects[x].vertexCount); + for (y=0; yobjects[x].vertexCount; y++) { + printf(" Vertex %d: %f %f %f\n", + y, + (double)world->objects[x].verticies[y].local.x, + (double)world->objects[x].verticies[y].local.y, + (double)world->objects[x].verticies[y].local.z + ); + } + printf(" Triangles: %d\n", world->objects[x].triangleCount); + for (y=0; yobjects[x].triangleCount; y++) { + printf(" Triangle %d: %d %d %d\n", + y, + world->objects[x].triangles[y].index[0], + world->objects[x].triangles[y].index[1], + world->objects[x].triangles[y].index[2] + ); + } + } +#endif + + for (x=0; xobjectCount; x++) { + j3ObjectMoveTo(world->objects[x], 0, 0, 300); // Matching values in code I'm studying + j3ObjectScaleTo(world->objects[x], 30, 30, 30); // Matching values in code I'm studying + } + + while (!jlKeyPressed() && !jlUtilMustExit()) { + jlDrawColor(0); + jlDrawClear(); + jlDrawColor(15); + jlDrawBox(0, 0, 319, 199); + + for (x=0; xobjectCount; x++) { + j3ObjectRotate(world->objects[x], 2, 4, 6); // Matching values in code I'm studying + j3ObjectUpdate(world->objects[x]); + j3DrawWireframe(world->objects[x]); + } + + printAt(font, 1, 1, "Verticies: %d", world->objects[0].vertexCount); + printAt(font, 1, 2, "Triangles: %d", world->objects[0].triangleCount); + + jlDisplayPresent(); + } + jlKeyRead(); + } + + j3WorldFree(world); + jlStaFree(font); + + j3UtilShutdown(); + jlUtilShutdown(); +} + diff --git a/j3d/notes.txt b/j3d/notes.txt new file mode 100644 index 0000000..de300ae --- /dev/null +++ b/j3d/notes.txt @@ -0,0 +1,11 @@ +typedef jint32 jfixed; + +#define J_FIXED_FRACTION_BITS 16 +#define J_FIXED_WHOLE_BITS (32 - J_FIXED_FRACTION_BITS) +#define jfixedToFloat(F) ((float)((F) * ((float)(1) / (float)(1 << J_FIXED_FRACTION_BITS)))) +#define floatToJfixed(F) ((jfixed)((F) * (1 << J_FIXED_FRACTION_BITS))) +#define fAdd(A,B) ((A) + (B)) +#define fSub(A,B) ((A) - (B)) +#define fMul(A,B) ((jfixed)(((jfixed)(A) * (jfixed)(B)) >> J_FIXED_FRACTION_BITS)) +#define fDiv(A,B) ((jfixed)(((jfixed)(A) << J_FIXED_FRACTION_BITS) / (jfixed)(B))) + diff --git a/postlink.sh b/j3d/postlink.sh similarity index 68% rename from postlink.sh rename to j3d/postlink.sh index 755d756..0a67c87 100755 --- a/postlink.sh +++ b/j3d/postlink.sh @@ -3,10 +3,12 @@ GAME=$1 export JOEY=$2 +# ***TODO*** Automatically convert OBJ to J3D + pushd "${GAME}" find . -type f -name "*.xcf" -exec ${JOEY}/utils/xcf2sta.sh {} \; popd mkdir -p data cp -f "${GAME}"/*.sta data/. -cp -f "${GAME}"/*.obj data/. +cp -f "${GAME}"/*.j3d data/. diff --git a/main.c b/main.c deleted file mode 100644 index 9b300cd..0000000 --- a/main.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * JoeyLib 3D - * Copyright (C) 2019 Scott Duensing - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. -*/ - - -#include -#include - -#define JOEY_MAIN -#include "joey.h" - -#ifdef JOEY_IIGS -segment "j3dTest"; -#endif - -#include "j3d.h" - - -void printAt(jlStaT *font, jint16 x, jint16 y, char *string) { - juint16 i; - byte c; - jint16 sx = x; - jint16 tx; - jint16 ty; - - for (i=0; iobjects[0].verticies)); - //printf("Triangles: %d\n", sb_count(world->objects[0].triangles)); - - j3ObjectMoveTo(world->objects[0], 0, 0, 300); // Matching values in code I'm studying - j3ObjectScaleTo(world->objects[0], 30, 30, 30); // Matching values in code I'm studying - - while (!jlKeyPressed() && !jlUtilMustExit()) { - j3ObjectRotate(world->objects[0], 2, 4, 6); // Matching values in code I'm studying - j3ObjectUpdate(world->objects[0]); - - jlDrawColor(0); - jlDrawClear(); - - jlDrawColor(15); - jlDrawBox(0, 0, 319, 199); - j3DrawWireframe(world->objects[0]); - - jlDisplayPresent(); - } - jlKeyRead(); - - j3WorldFree(world); - jlStaFree(font); - - j3UtilShutdown(); - jlUtilShutdown(); -} - diff --git a/obj2j3d/main.c b/obj2j3d/main.c new file mode 100644 index 0000000..3274bb7 --- /dev/null +++ b/obj2j3d/main.c @@ -0,0 +1,166 @@ +/* + * JoeyLib 3D + * Copyright (C) 2019 Scott Duensing + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +*/ + + +// OBJ format: http://paulbourke.net/dataformats/obj/ + + +#include +#include + +#include "stretchy_buffer.h" + +#include "joey.h" +#include "j3d.h" + + +int main(int argc, char *argv[]) { + + char *nameIn; + char *nameOut; + jint16 r; + juint16 x; + juint16 y; + char token[1024]; + char *c; + FILE *f; + j3CoordinatesT v; + j3ObjectT o; + j3TriangleT t; + j3WorldT world; + + if (argc < 3) { + printf("Usage: %s [infile] [outfile]\n", argv[0]); + return 1; + } + + nameIn = argv[1]; + nameOut = argv[2]; + + f = fopen(nameIn, "rt"); + + // Did we find the file? + if (f == NULL) { + // Nope. + printf("Unable to open %s\n", nameIn); + return 1; + } + + world.objectCount = 0; + world.objects = NULL; + o.vertexCount = 0; + o.triangleCount = 0; + o.verticies = NULL; + o.triangles = NULL; + + while (true) { + + // Read next token + r = (jint16)fscanf(f, "%s", token); + + // End of file? + if (r == EOF) { + break; + } + + // Vertex? + if (strcmp(token, "v" ) == 0) { + r = (jint16)fscanf(f, "%f %f %f\n", &v.local.x, &v.local.y, &v.local.z); + sb_push(o.verticies, v); + o.vertexCount++; + } + + // Face? + if (strcmp(token, "f" ) == 0) { + for (x=0; x<3; x++) { + // Fetch 'x'th vertex index + r = (jint16)fscanf(f, "%s", token); + c = strstr(token, "/"); + if (c) c[0] = 0; + r = (jint16)atoi(token); + t.index[x] = (juint16)r - 1; // obj indicies start at 1 + } + fscanf(f, "\n"); + sb_push(o.triangles, t); + o.triangleCount++; + } + } + + //***TODO*** support multiple objects - not sure how I want to do this yet + sb_push(world.objects, o); + world.objectCount++; + + // Finished reading + fclose(f); + + printf("Objects: %d\n", world.objectCount); + for (x=0; x /* size_t */ -#include /* memset, etc */ -#include /* exit */ - -#ifdef __GNUC__ -#define UTARRAY_UNUSED __attribute__((__unused__)) -#else -#define UTARRAY_UNUSED -#endif - -#ifdef oom -#error "The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code." -#define utarray_oom() oom() -#endif - -#ifndef utarray_oom -#define utarray_oom() exit(-1) -#endif - -typedef void (ctor_f)(void *dst, const void *src); -typedef void (dtor_f)(void *elt); -typedef void (init_f)(void *elt); -typedef struct { - size_t sz; - init_f *init; - ctor_f *copy; - dtor_f *dtor; -} UT_icd; - -typedef struct { - unsigned i,n;/* i: index of next available slot, n: num slots */ - UT_icd icd; /* initializer, copy and destructor functions */ - char *d; /* n slots of size icd->sz*/ -} UT_array; - -#define utarray_init(a,_icd) do { \ - memset(a,0,sizeof(UT_array)); \ - (a)->icd = *(_icd); \ -} while(0) - -#define utarray_done(a) do { \ - if ((a)->n) { \ - if ((a)->icd.dtor) { \ - unsigned _ut_i; \ - for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ - (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ - } \ - } \ - free((a)->d); \ - } \ - (a)->n=0; \ -} while(0) - -#define utarray_new(a,_icd) do { \ - (a) = (UT_array*)malloc(sizeof(UT_array)); \ - if ((a) == NULL) { \ - utarray_oom(); \ - } \ - utarray_init(a,_icd); \ -} while(0) - -#define utarray_free(a) do { \ - utarray_done(a); \ - free(a); \ -} while(0) - -#define utarray_reserve(a,by) do { \ - if (((a)->i+(by)) > (a)->n) { \ - char *utarray_tmp; \ - while (((a)->i+(by)) > (a)->n) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ - utarray_tmp=(char*)realloc((a)->d, (a)->n*(a)->icd.sz); \ - if (utarray_tmp == NULL) { \ - utarray_oom(); \ - } \ - (a)->d=utarray_tmp; \ - } \ -} while(0) - -#define utarray_push_back(a,p) do { \ - utarray_reserve(a,1); \ - if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \ - else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \ -} while(0) - -#define utarray_pop_back(a) do { \ - if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \ - else { (a)->i--; } \ -} while(0) - -#define utarray_extend_back(a) do { \ - utarray_reserve(a,1); \ - if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \ - else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \ - (a)->i++; \ -} while(0) - -#define utarray_len(a) ((a)->i) - -#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) -#define _utarray_eltptr(a,j) ((a)->d + ((a)->icd.sz * (j))) - -#define utarray_insert(a,p,j) do { \ - if ((j) > (a)->i) utarray_resize(a,j); \ - utarray_reserve(a,1); \ - if ((j) < (a)->i) { \ - memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ - ((a)->i - (j))*((a)->icd.sz)); \ - } \ - if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \ - else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \ - (a)->i++; \ -} while(0) - -#define utarray_inserta(a,w,j) do { \ - if (utarray_len(w) == 0) break; \ - if ((j) > (a)->i) utarray_resize(a,j); \ - utarray_reserve(a,utarray_len(w)); \ - if ((j) < (a)->i) { \ - memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ - _utarray_eltptr(a,j), \ - ((a)->i - (j))*((a)->icd.sz)); \ - } \ - if ((a)->icd.copy) { \ - unsigned _ut_i; \ - for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ - (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \ - } \ - } else { \ - memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ - utarray_len(w)*((a)->icd.sz)); \ - } \ - (a)->i += utarray_len(w); \ -} while(0) - -#define utarray_resize(dst,num) do { \ - unsigned _ut_i; \ - if ((dst)->i > (unsigned)(num)) { \ - if ((dst)->icd.dtor) { \ - for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \ - (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \ - } \ - } \ - } else if ((dst)->i < (unsigned)(num)) { \ - utarray_reserve(dst, (num) - (dst)->i); \ - if ((dst)->icd.init) { \ - for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \ - (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \ - } \ - } else { \ - memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz*((num) - (dst)->i)); \ - } \ - } \ - (dst)->i = (num); \ -} while(0) - -#define utarray_concat(dst,src) do { \ - utarray_inserta(dst, src, utarray_len(dst)); \ -} while(0) - -#define utarray_erase(a,pos,len) do { \ - if ((a)->icd.dtor) { \ - unsigned _ut_i; \ - for (_ut_i = 0; _ut_i < (len); _ut_i++) { \ - (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \ - } \ - } \ - if ((a)->i > ((pos) + (len))) { \ - memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \ - ((a)->i - ((pos) + (len))) * (a)->icd.sz); \ - } \ - (a)->i -= (len); \ -} while(0) - -#define utarray_renew(a,u) do { \ - if (a) utarray_clear(a); \ - else utarray_new(a, u); \ -} while(0) - -#define utarray_clear(a) do { \ - if ((a)->i > 0) { \ - if ((a)->icd.dtor) { \ - unsigned _ut_i; \ - for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ - (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \ - } \ - } \ - (a)->i = 0; \ - } \ -} while(0) - -#define utarray_sort(a,cmp) do { \ - qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \ -} while(0) - -#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp) - -#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) -#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : (((a)->i != utarray_eltidx(a,e)+1) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) -#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) != 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) -#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) -#define utarray_eltidx(a,e) (((char*)(e) - (a)->d) / (a)->icd.sz) - -/* last we pre-define a few icd for common utarrays of ints and strings */ -static void utarray_str_cpy(void *dst, const void *src) { - char **_src = (char**)src, **_dst = (char**)dst; - *_dst = (*_src == NULL) ? NULL : strdup(*_src); -} -static void utarray_str_dtor(void *elt) { - char **eltc = (char**)elt; - if (*eltc != NULL) free(*eltc); -} -static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; -static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int),NULL,NULL,NULL}; -static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void*),NULL,NULL,NULL}; - - -#endif /* UTARRAY_H */