New J3D binary file format. New crash bug.
This commit is contained in:
parent
06cc056bc5
commit
5b749ebf19
21 changed files with 834 additions and 468 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,7 +1,9 @@
|
|||
*.~
|
||||
*~
|
||||
*.user
|
||||
*.sta
|
||||
*.dis
|
||||
*.lnk
|
||||
*.map
|
||||
*.sym
|
||||
*.j3d
|
||||
build-*
|
||||
|
|
73
BuildTables/.gitignore
vendored
Normal file
73
BuildTables/.gitignore
vendored
Normal 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
|
||||
|
7
BuildTables/BuildTables.pro
Normal file
7
BuildTables/BuildTables.pro
Normal file
|
@ -0,0 +1,7 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
CONFIG -= qt
|
||||
|
||||
SOURCES += \
|
||||
main.c
|
94
BuildTables/main.c
Normal file
94
BuildTables/main.c
Normal 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
20
j3d/LICENSE
Normal 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
4
j3d/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
Basic 3D Library for JoeyLib
|
||||
|
||||
https://skunkworks.kangaroopunch.com/skunkworks/joeylib3d
|
||||
https://skunkworks.kangaroopunch.com/skunkworks/joeylib
|
|
@ -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
|
|
@ -30,9 +30,8 @@
|
|||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
#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; t<o->triangleCount; 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,9 +329,9 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
}
|
||||
|
||||
|
||||
bool _j3UtilClipLine(int *x1, int *y1, int *x2, int *y2) {
|
||||
int xi;
|
||||
int yi;
|
||||
bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
||||
jint16 xi;
|
||||
jint16 yi;
|
||||
float dx;
|
||||
float dy;
|
||||
bool point1 = false; // End points visible?
|
||||
|
@ -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; x<sb_count((*world)->objects); 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);
|
||||
}
|
||||
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;
|
||||
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
|
||||
r = fscanf(in, "%s", token);
|
||||
// Allocate memory for objects
|
||||
(*world)->objects = (j3ObjectT *)jlMalloc(sizeof(j3ObjectT));
|
||||
if ((*world)->objects) {
|
||||
|
||||
// End of file?
|
||||
if (r == EOF) {
|
||||
// Iterate across objects in file
|
||||
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;
|
||||
}
|
||||
|
||||
// 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++;
|
||||
if (fread(&(*world)->objects[x].verticies[y].local.y, sizeof(float), 1, in) != 1) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (fread(&(*world)->objects[x].verticies[y].local.z, sizeof(float), 1, in) != 1) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
fscanf(in, "\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);
|
||||
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
|
|
@ -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);
|
||||
|
|
@ -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 \
|
156
j3d/j3dtbls.h
Normal file
156
j3d/j3dtbls.h
Normal 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
141
j3d/main.c
Normal 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
11
j3d/notes.txt
Normal 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)))
|
||||
|
|
@ -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/.
|
103
main.c
103
main.c
|
@ -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
166
obj2j3d/main.c
Normal 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
17
obj2j3d/obj2j3d.pro
Normal 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
247
utarray.h
|
@ -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 */
|
Loading…
Add table
Reference in a new issue