New J3D binary file format. New crash bug.

This commit is contained in:
Scott Duensing 2019-08-27 21:19:57 -05:00
parent 06cc056bc5
commit 5b749ebf19
21 changed files with 834 additions and 468 deletions

4
.gitignore vendored
View file

@ -1,7 +1,9 @@
*.~ *~
*.user *.user
*.sta *.sta
*.dis *.dis
*.lnk *.lnk
*.map *.map
*.sym *.sym
*.j3d
build-*

73
BuildTables/.gitignore vendored Normal file
View file

@ -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

View file

@ -0,0 +1,7 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.c

94
BuildTables/main.c Normal file
View file

@ -0,0 +1,94 @@
/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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 <stdio.h>
#include <math.h>
#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 <scott@kangaroopunch.com>\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;
}

20
j3d/LICENSE Normal file
View file

@ -0,0 +1,20 @@
/*
* JoeyLib3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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.
*/

4
j3d/README.md Normal file
View file

@ -0,0 +1,4 @@
Basic 3D Library for JoeyLib
https://skunkworks.kangaroopunch.com/skunkworks/joeylib3d
https://skunkworks.kangaroopunch.com/skunkworks/joeylib

View file

@ -2,10 +2,12 @@
PROJECT=j3d PROJECT=j3d
GAME=${JOEY}/j3d/j3d GAME=${JOEY}/j3d/j3d
DATA=(${GAME}/cube.obj ${GAME}/font.sta) DATA=(${GAME}/cube.j3d ${GAME}/font.sta)
#SOURCE=(*.c *.h) #SOURCE=(*.c *.h)
SOURCE=() SOURCE=()
# ***TODO*** Automatically convert OBJ to J3D
pushd "${GAME}" pushd "${GAME}"
find . -type f -name "*.xcf" -exec ${JOEY}/utils/xcf2sta.sh {} \; find . -type f -name "*.xcf" -exec ${JOEY}/utils/xcf2sta.sh {} \;
popd popd

View file

@ -30,9 +30,8 @@
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
#include "stretchy_buffer.h"
#include "j3d.h" #include "j3d.h"
#include "j3dtbls.h"
#ifdef JOEY_IIGS #ifdef JOEY_IIGS
@ -50,13 +49,11 @@ segment "j3d";
// Module global data // Module global data
static float sin_table[361]; static jint16 clipMinX = 0;
static float cos_table[361]; static jint16 clipMinY = 0;
static int clipMinX = 0; static jint16 clipMaxX = 319;
static int clipMinY = 0; static jint16 clipMaxY = 199;
static int clipMaxX = 319; static jint16 viewDistance = 250;
static int clipMaxY = 199;
static int viewDistance = 250;
#define ASPECT_RATIO (float)0.8 #define ASPECT_RATIO (float)0.8
@ -66,17 +63,17 @@ static int viewDistance = 250;
#define HALF_SCREEN_HEIGHT 100 #define HALF_SCREEN_HEIGHT 100
void _j3DrawWireframePair(j3ObjectT *o, int v1, int v2) { void _j3DrawWireframePair(j3ObjectT *o, juint16 v1, juint16 v2) {
float x1; float x1;
float y1; float y1;
float z1; float z1;
float x2; float x2;
float y2; float y2;
float z2; float z2;
int ix1; jint16 ix1;
int iy1; jint16 iy1;
int ix2; jint16 ix2;
int iy2; jint16 iy2;
j3VertexT v; j3VertexT v;
v = o->verticies[v1].camera; v = o->verticies[v1].camera;
@ -95,19 +92,19 @@ void _j3DrawWireframePair(j3ObjectT *o, int v1, int v2) {
x2 = HALF_SCREEN_WIDTH + x2 * viewDistance / z2; x2 = HALF_SCREEN_WIDTH + x2 * viewDistance / z2;
y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * viewDistance / z2; y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * viewDistance / z2;
ix1 = (int)x1; ix1 = (jint16)x1;
iy1 = (int)y1; iy1 = (jint16)y1;
ix2 = (int)x2; ix2 = (jint16)x2;
iy2 = (int)y2; iy2 = (jint16)y2;
if (_j3UtilClipLine(&ix1, &iy1, &ix2, &iy2)) { if (_j3UtilClipLine(&ix1, &iy1, &ix2, &iy2)) {
jlDrawLine((jint16)ix1, (jint16)iy1, (jint16)ix2, (jint16)iy2); jlDrawLine(ix1, iy1, ix2, iy2);
} }
} }
void _j3DrawWireframe(j3ObjectT *o) { void _j3DrawWireframe(j3ObjectT *o) {
int t; // Current triangle jint16 t; // Current triangle
for (t=0; t<o->triangleCount; t++) { for (t=0; t<o->triangleCount; t++) {
_j3DrawWireframePair(o, o->triangles[t].index[0], o->triangles[t].index[1]); _j3DrawWireframePair(o, o->triangles[t].index[0], o->triangles[t].index[1]);
@ -164,11 +161,11 @@ void _j3ObjectReset(j3ObjectT *o) {
void _j3ObjectUpdate(j3ObjectT *o) { void _j3ObjectUpdate(j3ObjectT *o) {
int x; jint16 x;
int y; jint16 y;
int z; jint16 z;
int i; jint16 i;
int axis = 0; byte axis = 0;
j3Matrix4x4T rotateX; j3Matrix4x4T rotateX;
j3Matrix4x4T rotateY; j3Matrix4x4T rotateY;
j3Matrix4x4T rotateZ; j3Matrix4x4T rotateZ;
@ -177,9 +174,9 @@ void _j3ObjectUpdate(j3ObjectT *o) {
// === ROTATION === // === ROTATION ===
x = (int)o->rotation.x; x = (jint16)o->rotation.x;
y = (int)o->rotation.y; y = (jint16)o->rotation.y;
z = (int)o->rotation.z; z = (jint16)o->rotation.z;
j3MathMatrix4x4Identity(final); j3MathMatrix4x4Identity(final);
@ -332,9 +329,9 @@ void _j3ObjectUpdate(j3ObjectT *o) {
} }
bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) { bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
int xi; jint16 xi;
int yi; jint16 yi;
float dx; float dx;
float dy; float dy;
bool point1 = false; // End points visible? bool point1 = false; // End points visible?
@ -380,7 +377,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
rightEdge = true; rightEdge = true;
// Find intersection with right edge // Find intersection with right edge
if (fabsf(dx) > FLT_EPSILON) { // dx != 0 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 { } else {
yi = -1; // Invalidate intersection yi = -1; // Invalidate intersection
} }
@ -389,7 +386,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
leftEdge = true; leftEdge = true;
// Find intersection with left edge // Find intersection with left edge
if (fabsf(dx) > FLT_EPSILON) { // dx != 0 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 { } else {
yi = -1; // Invalidate intersection yi = -1; // Invalidate intersection
} }
@ -400,7 +397,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
bottomEdge = true; bottomEdge = true;
// Find intersection with right edge // Find intersection with right edge
if (fabsf(dy) > FLT_EPSILON) { // dy != 0 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 { } else {
xi = -1; // Invalidate inntersection xi = -1; // Invalidate inntersection
} }
@ -409,7 +406,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
topEdge = true; topEdge = true;
// Find intersection with top edge // Find intersection with top edge
if (fabsf(dy) > FLT_EPSILON) { // dy != 0 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 { } else {
xi = -1; // Invalidate intersection xi = -1; // Invalidate intersection
} }
@ -458,7 +455,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
rightEdge = true; rightEdge = true;
// Find intersection with right edge // Find intersection with right edge
if (fabsf(dx) > FLT_EPSILON) { // dx != 0 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 { } else {
yi = -1; // Invalidate inntersection yi = -1; // Invalidate inntersection
} }
@ -467,7 +464,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
leftEdge = true; leftEdge = true;
// Find intersection with left edge // Find intersection with left edge
if (fabsf(dx) > FLT_EPSILON) { // dx != 0 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 { } else {
yi = -1; // Invalidate intersection yi = -1; // Invalidate intersection
} }
@ -478,7 +475,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
bottomEdge = true; bottomEdge = true;
// Find intersection with right edge // Find intersection with right edge
if (fabsf(dy) > FLT_EPSILON) { // dy != 0 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 { } else {
xi = -1; // invalidate inntersection xi = -1; // invalidate inntersection
} }
@ -487,7 +484,7 @@ bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
topEdge = true; topEdge = true;
// Find intersection with top edge // Find intersection with top edge
if (fabsf(dy) > FLT_EPSILON) { // dy != 0 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 { } else {
xi = -1; // invalidate inntersection xi = -1; // invalidate inntersection
} }
@ -527,41 +524,39 @@ void j3UtilShutdown(void) {
void j3UtilStartup(void) { void j3UtilStartup(void) {
int euler; // Nothing yet
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);
}
} }
void _j3WorldFree(j3WorldT **world) { void _j3WorldFree(j3WorldT **world) {
int x; int x;
for (x=0; x<sb_count((*world)->objects); x++) { if ((*world)) {
sb_free((*world)->objects[x].triangles); for (x=0; x<(*world)->objectCount; x++) {
sb_free((*world)->objects[x].verticies); 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);
} }
sb_free((*world)->objects);
jlFree(*world); jlFree(*world);
}
} }
bool _j3WorldLoad(j3WorldT **world, char *file) { bool _j3WorldLoad(j3WorldT **world, char *file) {
int r; jint16 x;
int x; jint16 y;
char token[1024]; jint16 z;
char *c; byte buffer[4];
FILE *in; FILE *in;
j3CoordinatesT v; bool failed = false;
j3ObjectT o;
j3TriangleT t;
in = fopen(jlUtilMakePathname(file, "obj"), "rt"); in = fopen(jlUtilMakePathname(file, "j3d"), "rb");
// Did we find the file? // Did we find the file?
if (in == NULL) { if (in == NULL) {
@ -577,56 +572,81 @@ bool _j3WorldLoad(j3WorldT **world, char *file) {
// Allocate world object // Allocate world object
*world = (j3WorldT *)jlMalloc(sizeof(j3WorldT)); *world = (j3WorldT *)jlMalloc(sizeof(j3WorldT));
if (*world) {
// Initialize world object & create an initial object to read data into // Initialize world object & create an initial object to read data into
(*world)->objectCount = 0;;
(*world)->objects = NULL; (*world)->objects = NULL;
o.vertexCount = 0;
o.triangleCount = 0;
o.verticies = NULL;
o.triangles = NULL;
_j3ObjectReset(&o); // 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)) {
while (true) { // Get object count
if (fread(&(*world)->objectCount, sizeof(juint16), 1, in) == 1) {
// Read next token // Allocate memory for objects
r = fscanf(in, "%s", token); (*world)->objects = (j3ObjectT *)jlMalloc(sizeof(j3ObjectT));
if ((*world)->objects) {
// End of file? // Iterate across objects in file
if (r == EOF) { for (x=0; x<(*world)->objectCount; x++) {
// 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) {
_j3ObjectReset(&(*world)->objects[x]);
// 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; break;
} }
if (fread(&(*world)->objects[x].verticies[y].local.y, sizeof(float), 1, in) != 1) {
// Vertex? failed = true;
if (strcmp(token, "v" ) == 0) { break;
r = fscanf(in, "%f %f %f\n", &v.local.x, &v.local.y, &v.local.z);
sb_push(o.verticies, v);
o.vertexCount++;
} }
if (fread(&(*world)->objects[x].verticies[y].local.z, sizeof(float), 1, in) != 1) {
// Face? failed = true;
if (strcmp(token, "f" ) == 0) { break;
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++;
} }
} }
//***TODO*** support multiple objects - not sure how I want to do this yet if (!failed) {
sb_push((*world)->objects, o); // 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. // Finished! Clean up.
fclose(in); fclose(in);
return true; return !failed;
} }
#ifndef JOEY_IIGS #ifndef JOEY_IIGS

View file

@ -42,12 +42,12 @@ typedef struct {
} j3CoordinatesT; } j3CoordinatesT;
typedef struct { 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; } j3TriangleT;
typedef struct { typedef struct {
int vertexCount; // How many verticies are in the list juint16 vertexCount; // How many verticies are in the list
int triangleCount; // How many triangles 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) j3CoordinatesT *verticies; // List of verticies as loaded from disk (more v1, v2, v3 than x, y, z)
j3TriangleT *triangles; // Triangles built from vertex list j3TriangleT *triangles; // Triangles built from vertex list
j3VertexT position; // Position of object in world j3VertexT position; // Position of object in world
@ -56,6 +56,7 @@ typedef struct {
} j3ObjectT; } j3ObjectT;
typedef struct { typedef struct {
juint16 objectCount;
j3ObjectT *objects; j3ObjectT *objects;
} j3WorldT; } j3WorldT;
@ -121,11 +122,11 @@ void j3UtilStartup(void);
// Private Prototypes // Private Prototypes
void _j3DrawWireframePair(j3ObjectT *o, int v1, int v2); void _j3DrawWireframePair(j3ObjectT *o, juint16 v1, juint16 v2);
void _j3DrawWireframe(j3ObjectT *o); void _j3DrawWireframe(j3ObjectT *o);
void _j3ObjectReset(j3ObjectT *o); void _j3ObjectReset(j3ObjectT *o);
void _j3ObjectUpdate(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); void _j3WorldFree(j3WorldT **world);
bool _j3WorldLoad(j3WorldT **world, char *file); bool _j3WorldLoad(j3WorldT **world, char *file);

View file

@ -2,8 +2,8 @@ JOEY = /home/scott/joey
include($$JOEY/dist/joey.pri) include($$JOEY/dist/joey.pri)
HEADERS += \ HEADERS += \
stretchy_buffer.h \ j3d.h \
j3d.h j3dtbls.h
SOURCES += \ SOURCES += \
main.c \ main.c \

156
j3d/j3dtbls.h Normal file
View file

@ -0,0 +1,156 @@
/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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_

141
j3d/main.c Normal file
View file

@ -0,0 +1,141 @@
/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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 <stdio.h>
#include <string.h>
#include <stdarg.h>
#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; x<world->objectCount; x++) {
printf("Object %d:\n", x);
printf(" Verticies: %d\n", world->objects[x].vertexCount);
for (y=0; y<world->objects[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; y<world->objects[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; x<world->objectCount; 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; x<world->objectCount; 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();
}

11
j3d/notes.txt Normal file
View file

@ -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)))

View file

@ -3,10 +3,12 @@
GAME=$1 GAME=$1
export JOEY=$2 export JOEY=$2
# ***TODO*** Automatically convert OBJ to J3D
pushd "${GAME}" pushd "${GAME}"
find . -type f -name "*.xcf" -exec ${JOEY}/utils/xcf2sta.sh {} \; find . -type f -name "*.xcf" -exec ${JOEY}/utils/xcf2sta.sh {} \;
popd popd
mkdir -p data mkdir -p data
cp -f "${GAME}"/*.sta data/. cp -f "${GAME}"/*.sta data/.
cp -f "${GAME}"/*.obj data/. cp -f "${GAME}"/*.j3d data/.

103
main.c
View file

@ -1,103 +0,0 @@
/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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 <stdio.h>
#include <string.h>
#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; i<strlen(string); i++) {
c = (byte)string[i];
tx = c % 40;
ty = c / 40;
jlDrawBlit8x8(font, tx, ty, sx++, y);
}
}
int main(void) {
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: Success!");
jlDisplayPresent();
} else {
printAt(font, 1, 1, "Object loading: Failed.");
jlDisplayPresent();
}
//***TODO*** Add methods to inspect world/object information
//printf("Verticies: %d\n", sb_count(world->objects[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();
}

166
obj2j3d/main.c Normal file
View file

@ -0,0 +1,166 @@
/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* 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 <stdio.h>
#include <string.h>
#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<world.objectCount; x++) {
printf("Object %d:\n", x);
printf(" Verticies: %d\n", world.objects[x].vertexCount);
printf(" Triangles: %d\n", world.objects[x].triangleCount);
}
// Create output file
f = fopen(nameOut, "wb");
if (f == NULL) {
// Nope.
printf("Unable to create %s\n", nameOut);
return 1;
}
// Write header
fputc('J', f);
fputc('3', f);
fputc('D', f);
// Version
fputc(0, f);
// Number of objects in file
fwrite(&world.objectCount, sizeof(juint16), 1, f);
// Iterate over objects
for (x=0; x<world.objectCount; x++) {
// Number of verticies
fwrite(&world.objects[x].vertexCount, sizeof(juint16), 1, f);
// Vertex list
for (y=0; y<world.objects[x].vertexCount; y++) {
// Write one at a time in case the struct gets padded
fwrite(&world.objects[x].verticies[y].local.x, sizeof(float), 1, f);
fwrite(&world.objects[x].verticies[y].local.y, sizeof(float), 1, f);
fwrite(&world.objects[x].verticies[y].local.z, sizeof(float), 1, f);
}
// Number of triangles
fwrite(&world.objects[x].triangleCount, sizeof(juint16), 1, f);
// Triangle list
for (y=0; y<world.objects[x].triangleCount; y++) {
// Write one at a time in case the struct gets padded
fwrite(&world.objects[x].triangles[y].index[0], sizeof(juint16), 1, f);
fwrite(&world.objects[x].triangles[y].index[1], sizeof(juint16), 1, f);
fwrite(&world.objects[x].triangles[y].index[2], sizeof(juint16), 1, f);
}
}
// Finished writing
fclose(f);
return 0;
}

17
obj2j3d/obj2j3d.pro Normal file
View file

@ -0,0 +1,17 @@
JOEY = /home/scott/joey
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
INCLUDEPATH += \
$$JOEY/dist \
$$PWD/../j3d
HEADERS += \
$$JOEY/dist/joey.h \
$$PWD/../j3d/j3d.h
SOURCES += \
main.c

247
utarray.h
View file

@ -1,247 +0,0 @@
/*
Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* a dynamic array implementation using macros
*/
#ifndef UTARRAY_H
#define UTARRAY_H
#define UTARRAY_VERSION 2.1.0
#include <stddef.h> /* size_t */
#include <string.h> /* memset, etc */
#include <stdlib.h> /* 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 */