Files
bullet3/Extras/Serialize/makesdna/makesdna.cpp
erwin.coumans 00f58e5a91 added basic serialization for several constraints including btPoint2PointConstraint, btHingeConstraint, btSliderConstraint, btConeTwistConstraint, btGeneric6DofConstraint
(no motor support or advanced settings yet)
added btStaticPlaneShape serialization
Added toggle in cmake for BenchmarksDemo to enable/disable graphics rendering
2010-01-27 02:13:56 +00:00

1236 lines
31 KiB
C++

/// Current makesdna.cpp is a from Blender, but we will completely rewrite it in C++ under a ZLib license
/// The Original version is at https://svn.blender.org/svnroot/bf-blender/trunk/blender/source/blender/makesdna/intern/makesdna.c
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*
* Struct muncher for making SDNA
*
* Originally by Ton, some mods by Frank, and some cleaning and
* extension by Nzc.
*
* Makesdna creates a .c file with a long string of numbers that
* encode the Blender file format. It is fast, because it is basically
* a binary dump. There are some details to mind when reconstructing
* the file (endianness and byte-alignment).
*
* This little program scans all structs that need to be serialized,
* and determined the names and types of all members. It calculates
* how much memory (on disk or in ram) is needed to store that struct,
* and the offsets for reaching a particular one.
*
* There is a facility to get verbose output from sdna. Search for
* debugSDNA. This int can be set to 0 (no output) to some int. Higher
* numbers give more output.
* */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32) && !defined(FREE_WINDOWS)
/* The __intXX are built-in types of the visual complier! So we don't
* need to include anything else here. */
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#ifndef _INTPTR_T_DEFINED
#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef long intptr_t;
#endif
#define _INTPTR_T_DEFINED
#endif
#ifndef _UINTPTR_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef unsigned long uintptr_t;
#endif
#define _UINTPTR_T_DEFINED
#endif
#elif defined(__linux__) || defined(__NetBSD__)
/* Linux-i386, Linux-Alpha, Linux-ppc */
#include <stdint.h>
#elif defined (__APPLE__)
#include <inttypes.h>
#elif defined(FREE_WINDOWS)
#include <stdint.h>
#else
/* FreeBSD, Irix, Solaris */
#include <sys/types.h>
#endif /* ifdef platform for types */
#ifdef __cplusplus
}
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//#include "DNA_sdna_types.h"
// include files for automatic dependancies
#include "DNA_rigidbody.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
#include "LinearMath/btTransform.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
#include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/CollisionShapes/btCylinderShape.h"
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define SDNA_MAX_FILENAME_LENGTH 255
/* Included the path relative from /source/blender/ here, so we can move */
/* headers around with more freedom. */
char *includefiles[] = {
// if you add files here, please add them at the end
// of makesdna.c (this file) as well
"../makesdna/DNA_rigidbody.h",
"../../../src/LinearMath/btVector3.h",
"../../../src/LinearMath/btMatrix3x3.h",
"../../../src/LinearMath/btTransform.h",
"../../../src/BulletCollision/CollisionShapes/btCollisionShape.h",
"../../../src/BulletCollision/CollisionShapes/btStaticPlaneShape.h",
"../../../src/BulletCollision/CollisionShapes/btConvexInternalShape.h",
"../../../src/BulletCollision/CollisionShapes/btMultiSphereShape.h",
"../../../src/BulletCollision/CollisionShapes/btStridingMeshInterface.h",
"../../../src/BulletCollision/CollisionShapes/btTriangleMeshShape.h",
"../../../src/BulletCollision/CollisionShapes/btCompoundShape.h",
"../../../src/BulletCollision/CollisionShapes/btCylinderShape.h",
"../../../src/BulletCollision/CollisionShapes/btCapsuleShape.h",
"../../../src/BulletCollision/CollisionShapes/btConvexHullShape.h",
"../../../src/BulletCollision/CollisionDispatch/btCollisionObject.h",
"../../../src/BulletDynamics/Dynamics/btRigidBody.h",
"../../../src/BulletDynamics/ConstraintSolver/btTypedConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btHingeConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btSliderConstraint.h",
// empty string to indicate end of includefiles
""
};
void* malloc_and_setzero(int numbytes)
{
char* buf = (char*)malloc(numbytes);
memset(buf,0,numbytes);
return buf;
}
int maxdata= 500000, maxnr= 50000;
int nr_names=0;
int nr_types=0;
int nr_structs=0;
char **names, *namedata; /* at adress names[a] is string a */
char **types, *typedata; /* at adress types[a] is string a */
short *typelens; /* at typelens[a] is de length of type a */
short *alphalens; /* contains sizes as they are calculated on the DEC Alpha (64 bits) */
short **structs, *structdata; /* at sp= structs[a] is the first adress of a struct definition
sp[0] is type number
sp[1] is amount of elements
sp[2] sp[3] is typenr, namenr (etc) */
/*
* debugSDNA:
* - 0 = no output, except errors
* - 1 = detail actions
* - 2 = full trace, tell which names and types were found
* - 4 = full trace, plus all gritty details
*/
int debugSDNA = 0;
int additional_slen_offset;
/* ************************************************************************** */
/* Functions */
/* ************************************************************************** */
/**
* Add type <str> to struct indexed by <len>, if it was not yet found.
*/
int add_type(char *str, int len);
/**
* Add variable <str> to
*/
int add_name(char *str);
/**
* Search whether this structure type was already found, and if not,
* add it.
*/
short *add_struct(int namecode);
/**
* Remove comments from this buffer. Assumes that the buffer refers to
* ascii-code text.
*/
int preprocess_include(char *maindata, int len);
/**
* Scan this file for serializable types.
*/
int convert_include(char *filename);
/**
* Determine how many bytes are needed for an array.
*/
int arraysize(char *astr, int len);
/**
* Determine how many bytes are needed for each struct.
*/
static int calculate_structlens(int);
/**
* Construct the DNA.c file
*/
void dna_write(FILE *file, void *pntr, int size);
/**
* Report all structures found so far, and print their lenghts.
*/
void printStructLenghts(void);
/* ************************************************************************** */
/* Implementation */
/* ************************************************************************** */
/* ************************* MAKEN DNA ********************** */
int add_type(char *str, int len)
{
int nr;
char *cp;
if(str[0]==0) return -1;
/* search through type array */
for(nr=0; nr<nr_types; nr++) {
if(strcmp(str, types[nr])==0) {
if (len) {
typelens[nr]= len;
alphalens[nr] = len;
}
return nr;
}
}
/* append new type */
if(nr_types==0) cp= typedata;
else {
cp= types[nr_types-1]+strlen(types[nr_types-1])+1;
}
strcpy(cp, str);
types[nr_types]= cp;
typelens[nr_types]= len;
alphalens[nr_types]= len;
if(nr_types>=maxnr) {
printf("too many types\n");
return nr_types-1;;
}
nr_types++;
return nr_types-1;
}
/**
*
* Because of the weird way of tokenizing, we have to 'cast' function
* pointers to ... (*f)(), whatever the original signature. In fact,
* we add name and type at the same time... There are two special
* cases, unfortunately. These are explicitly checked.
*
* */
int add_name(char *str)
{
int nr, i, j, k;
char *cp;
char buf[255]; /* stupid limit, change it :) */
char *name;
additional_slen_offset = 0;
if((str[0]==0) /* || (str[1]==0) */) return -1;
if (str[0] == '(' && str[1] == '*') {
if (debugSDNA > 3) printf("\t\t\t\t*** Function pointer found\n");
/* functionpointer: transform the type (sometimes) */
i = 0;
j = 0;
while (str[i] != ')') {
buf[i] = str[i];
i++;
}
/* Another number we need is the extra slen offset. This extra
* offset is the overshoot after a space. If there is no
* space, no overshoot should be calculated. */
j = i; /* j at first closing brace */
if (debugSDNA > 3) printf("first brace after offset %d\n", i);
j++; /* j beyond closing brace ? */
while ((str[j] != 0) && (str[j] != ')' )) {
if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]);
j++;
}
if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]);
if (debugSDNA > 3) printf("special after offset %d\n", j);
if (str[j] == 0 ) {
if (debugSDNA > 3) printf("offsetting for space\n");
/* get additional offset */
k = 0;
while (str[j] != ')') {
j++;
k++;
}
if (debugSDNA > 3) printf("extra offset %d\n", k);
additional_slen_offset = k;
} else if (str[j] == ')' ) {
if (debugSDNA > 3) printf("offsetting for brace\n");
; /* don't get extra offset */
} else {
printf("Error during tokening function pointer argument list\n");
}
/*
* Put )(void) at the end? Maybe )(). Should check this with
* old sdna. Actually, sometimes )(), sometimes )(void...)
* Alas.. such is the nature of braindamage :(
*
* Sorted it out: always do )(), except for headdraw and
* windraw, part of ScrArea. This is important, because some
* linkers will treat different fp's differently when called
* !!! This has to do with interference in byte-alignment and
* the way args are pushed on the stack.
*
* */
buf[i] = 0;
if (debugSDNA > 3) printf("Name before chomping: %s\n", buf);
if ( (strncmp(buf,"(*headdraw", 10) == 0)
|| (strncmp(buf,"(*windraw", 9) == 0) ) {
buf[i] = ')';
buf[i+1] = '(';
buf[i+2] = 'v';
buf[i+3] = 'o';
buf[i+4] = 'i';
buf[i+5] = 'd';
buf[i+6] = ')';
buf[i+7] = 0;
} else {
buf[i] = ')';
buf[i+1] = '(';
buf[i+2] = ')';
buf[i+3] = 0;
}
/* now precede with buf*/
if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf);
name = buf;
} else {
/* normal field: old code */
name = str;
}
/* search name array */
for(nr=0; nr<nr_names; nr++) {
if(strcmp(name, names[nr])==0) {
return nr;
}
}
/* append new type */
if(nr_names==0) cp= namedata;
else {
cp= names[nr_names-1]+strlen(names[nr_names-1])+1;
}
strcpy(cp, name);
names[nr_names]= cp;
if(nr_names>=maxnr) {
printf("too many names\n");
return nr_names-1;
}
nr_names++;
return nr_names-1;
}
short *add_struct(int namecode)
{
int len;
short *sp;
if(nr_structs==0) {
structs[0]= structdata;
}
else {
sp= structs[nr_structs-1];
len= sp[1];
structs[nr_structs]= sp+ 2*len+2;
}
sp= structs[nr_structs];
sp[0]= namecode;
if(nr_structs>=maxnr) {
printf("too many structs\n");
return sp;
}
nr_structs++;
return sp;
}
int preprocess_include(char *maindata, int len)
{
int a, newlen, comment = 0;
char *cp, *temp, *md;
temp= (char*) malloc_and_setzero(len);
memcpy(temp, maindata, len);
// remove all c++ comments
/* replace all enters/tabs/etc with spaces */
cp= temp;
a= len;
comment = 0;
while(a--) {
if(cp[0]=='/' && cp[1]=='/') {
comment = 1;
} else if (*cp<32) {
comment = 0;
}
if (comment || *cp<32 || *cp>128 ) *cp= 32;
cp++;
}
/* data from temp copy to maindata, remove comments and double spaces */
cp= temp;
md= maindata;
newlen= 0;
comment= 0;
a= len;
while(a--) {
if(cp[0]=='/' && cp[1]=='*') {
comment= 1;
cp[0]=cp[1]= 32;
}
if(cp[0]=='*' && cp[1]=='/') {
comment= 0;
cp[0]=cp[1]= 32;
}
/* do not copy when: */
if(comment);
else if( cp[0]==' ' && cp[1]==' ' );
else if( cp[-1]=='*' && cp[0]==' ' ); /* pointers with a space */
else {
md[0]= cp[0];
md++;
newlen++;
}
cp++;
}
free(temp);
return newlen;
}
static void *read_file_data(char *filename, int *len_r)
{
#ifdef WIN32
FILE *fp= fopen(filename, "rb");
#else
FILE *fp= fopen(filename, "r");
#endif
void *data;
if (!fp) {
*len_r= -1;
return NULL;
}
fseek(fp, 0L, SEEK_END);
*len_r= ftell(fp);
fseek(fp, 0L, SEEK_SET);
data= malloc_and_setzero(*len_r);
if (!data) {
*len_r= -1;
fclose(fp);
return NULL;
}
if (fread(data, *len_r, 1, fp)!=1) {
*len_r= -1;
free(data);
fclose(fp);
return NULL;
}
fclose(fp);
return data;
}
const char* skipStructTypes[]=
{
"btRigidBodyConstructionInfo",
"Euler",
"btConstraintInfo2",
"btConstraintSetting",
""
};
int skipStruct(const char* structType)
{
int i=0;
while (strlen(skipStructTypes[i]))
{
if (strcmp(structType,skipStructTypes[i])==0)
{
return 1;
}
i++;
}
return 0;
}
int convert_include(char *filename)
{
/* read include file, skip structs with a '#' before it.
store all data in temporal arrays.
*/
int filelen, count, overslaan, slen, type, name, strct;
short *structpoin, *sp;
char *maindata, *mainend, *md, *md1;
md= maindata= (char*)read_file_data(filename, &filelen);
if (filelen==-1) {
printf("Can't read file %s\n", filename);
return 1;
}
filelen= preprocess_include(maindata, filelen);
mainend= maindata+filelen-1;
/* we look for '{' and then back to 'struct' */
count= 0;
overslaan= 0;
while(count<filelen) {
/* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
if(md[0]=='#' && md[1]==' ' && md[2]=='#') {
overslaan= 1;
}
if(md[0]=='{') {
md[0]= 0;
if(overslaan) {
overslaan= 0;
}
else {
if(md[-1]==' ') md[-1]= 0;
md1= md-2;
while( *md1!=32) md1--; /* to beginning of word */
md1++;
/* we've got a struct name when... */
if( strncmp(md1-7, "struct", 6)==0 ) {
if (!skipStruct(md1))
{
strct= add_type(md1, 0);
structpoin= add_struct(strct);
sp= structpoin+2;
if (debugSDNA > 1) printf("\t|\t|-- detected struct %s\n", types[strct]);
/* first lets make it all nice strings */
md1= md+1;
while(*md1 != '}') {
if(md1>mainend) break;
if(*md1==',' || *md1==' ') *md1= 0;
md1++;
}
/* read types and names until first character that is not '}' */
md1= md+1;
while( *md1 != '}' ) {
if(md1>mainend) break;
/* skip when it says 'struct' or 'unsigned' or 'const' */
if(*md1) {
if( strncmp(md1, "struct", 6)==0 ) md1+= 7;
if( strncmp(md1, "unsigned", 8)==0 ) md1+= 9;
if( strncmp(md1, "const", 5)==0 ) md1+= 6;
/* we've got a type! */
type= add_type(md1, 0);
if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1);
md1+= strlen(md1);
/* read until ';' */
while( *md1 != ';' ) {
if(md1>mainend) break;
if(*md1) {
/* We've got a name. slen needs
* correction for function
* pointers! */
slen= (int) strlen(md1);
if( md1[slen-1]==';' ) {
md1[slen-1]= 0;
name= add_name(md1);
slen += additional_slen_offset;
sp[0]= type;
sp[1]= name;
if ((debugSDNA>1) && (names[name] != 0 )) printf("%s |", names[name]);
structpoin[1]++;
sp+= 2;
md1+= slen;
break;
}
name= add_name(md1);
slen += additional_slen_offset;
sp[0]= type;
sp[1]= name;
if ((debugSDNA > 1) && (names[name] != 0 )) printf("%s ||", names[name]);
structpoin[1]++;
sp+= 2;
md1+= slen;
}
md1++;
}
if (debugSDNA > 1) printf(")\n");
}
md1++;
}
}
}
}
}
count++;
md++;
}
free(maindata);
return 0;
}
int arraysize(char *astr, int len)
{
int a, mul=1;
char str[100], *cp=0;
memcpy(str, astr, len+1);
for(a=0; a<len; a++) {
if( str[a]== '[' ) {
cp= &(str[a+1]);
}
else if( str[a]==']' && cp) {
str[a]= 0;
mul*= atoi(cp);
}
}
return mul;
}
static int calculate_structlens(int firststruct)
{
int a, b, len, alphalen, unknown= nr_structs, lastunknown, structtype, type, mul, namelen;
short *sp, *structpoin;
char *cp;
int has_pointer, dna_error = 0;
while(unknown) {
lastunknown= unknown;
unknown= 0;
/* check all structs... */
for(a=0; a<nr_structs; a++) {
structpoin= structs[a];
structtype= structpoin[0];
/* when length is not known... */
if(typelens[structtype]==0) {
sp= structpoin+2;
len= 0;
alphalen = 0;
has_pointer = 0;
/* check all elements in struct */
for(b=0; b<structpoin[1]; b++, sp+=2) {
type= sp[0];
cp= names[sp[1]];
namelen= (int) strlen(cp);
/* is it a pointer or function pointer? */
if(cp[0]=='*' || cp[1]=='*') {
has_pointer = 1;
/* has the name an extra length? (array) */
mul= 1;
if( cp[namelen-1]==']') mul= arraysize(cp, namelen);
/* 4-8 aligned/ */
if(sizeof(void *) == 4) {
if (len % 4) {
printf("Align pointer error in struct (len4): %s %s\n", types[structtype], cp);
dna_error = 1;
}
} else {
if (len % 8) {
printf("Align pointer error in struct (len8): %s %s\n", types[structtype], cp);
dna_error = 1;
}
}
if (alphalen % 8) {
printf("Align pointer error in struct (alphalen8): %s %s\n", types[structtype],cp);
dna_error = 1;
}
len += sizeof(void *) * mul;
alphalen += 8 * mul;
} else if( typelens[type] ) {
/* has the name an extra length? (array) */
mul= 1;
if( cp[namelen-1]==']') mul= arraysize(cp, namelen);
/* struct alignment */
if(type >= firststruct) {
if(sizeof(void *)==8 && (len % 8) ) {
printf("Align struct error: %s %s\n", types[structtype],cp);
dna_error = 1;
}
}
/* 2-4 aligned/ */
if(typelens[type]>3 && (len % 4) ) {
printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%4);
dna_error = 1;
}
else if(typelens[type]==2 && (len % 2) ) {
printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%2);
dna_error = 1;
}
len += mul*typelens[type];
alphalen += mul * alphalens[type];
} else {
len= 0;
alphalen = 0;
break;
}
}
if (len==0) {
unknown++;
} else {
typelens[structtype]= len;
alphalens[structtype]= alphalen;
// two ways to detect if a struct contains a pointer:
// has_pointer is set or alphalen != len
if (has_pointer || alphalen != len) {
if (alphalen % 8) {
printf("alphalen = %d len = %d\n",alphalen,len);
printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8);
dna_error = 1;
}
}
if(len % 4) {
printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4);
dna_error = 1;
}
}
}
}
if(unknown==lastunknown) break;
}
if(unknown) {
printf("ERROR: still %d structs unknown\n", unknown);
if (debugSDNA) {
printf("*** Known structs : \n");
for(a=0; a<nr_structs; a++) {
structpoin= structs[a];
structtype= structpoin[0];
/* length unknown */
if(typelens[structtype]!=0) {
printf(" %s\n", types[structtype]);
}
}
}
printf("*** Unknown structs : \n");
for(a=0; a<nr_structs; a++) {
structpoin= structs[a];
structtype= structpoin[0];
/* length unkown yet */
if(typelens[structtype]==0) {
printf(" %s\n", types[structtype]);
}
}
}
return(dna_error);
}
#define MAX_DNA_LINE_LENGTH 20
void dna_write(FILE *file, void *pntr, int size)
{
static int linelength = 0;
int i;
char *data;
data = (char *) pntr;
for (i = 0 ; i < size ; i++)
{
fprintf(file, "%d,", data[i]);
linelength++;
if (linelength >= MAX_DNA_LINE_LENGTH) {
fprintf(file, "\n");
linelength = 0;
}
}
}
void printStructLenghts(void)
{
int a, unknown= nr_structs, lastunknown, structtype;
short *structpoin;
printf("\n\n*** All detected structs:\n");
while(unknown) {
lastunknown= unknown;
unknown= 0;
/* check all structs... */
for(a=0; a<nr_structs; a++) {
structpoin= structs[a];
structtype= structpoin[0];
printf("\t%s\t:%d\n", types[structtype], typelens[structtype]);
}
}
printf("*** End of list\n");
}
int make_structDNA(char *baseDirectory, FILE *file)
{
int len, i;
short *sp;
/* str contains filenames. Since we now include paths, I stretched */
/* it a bit. Hope this is enough :) -nzc- */
char str[SDNA_MAX_FILENAME_LENGTH], *cp;
int firststruct;
if (debugSDNA > -1) {
fflush(stdout);
printf("Running makesdna at debug level %d\n", debugSDNA);
}
/* the longest known struct is 50k, so we assume 100k is sufficent! */
namedata= (char*)malloc_and_setzero(maxdata);
typedata= (char*)malloc_and_setzero(maxdata);
structdata= (short*)malloc_and_setzero(maxdata);
/* a maximum of 5000 variables, must be sufficient? */
names= (char**)malloc_and_setzero(sizeof(char *)*maxnr);
types= (char**)malloc_and_setzero(sizeof(char *)*maxnr);
typelens= (short*) malloc_and_setzero(sizeof(short)*maxnr);
alphalens= (short*)malloc_and_setzero(sizeof(short)*maxnr);
structs= (short**)malloc_and_setzero(sizeof(short)*maxnr);
/* insertion of all known types */
/* watch it: uint is not allowed! use in structs an unsigned int */
add_type("char", 1); /* 0 */
add_type("uchar", 1); /* 1 */
add_type("short", 2); /* 2 */
add_type("ushort", 2); /* 3 */
add_type("int", 4); /* 4 */
add_type("long", 4); /* 5 */ /* should it be 8 on 64 bits? */
add_type("ulong", 4); /* 6 */
add_type("float", 4); /* 7 */
add_type("double", 8); /* 8 */
add_type("void", 0); /* 9 */
// the defines above shouldn't be output in the padding file...
firststruct = nr_types;
/* add all include files defined in the global array */
/* Since the internal file+path name buffer has limited length, I do a */
/* little test first... */
/* Mind the breaking condition here! */
if (debugSDNA) printf("\tStart of header scan:\n");
for (i = 0; strlen(includefiles[i]); i++) {
sprintf(str, "%s%s", baseDirectory, includefiles[i]);
if (debugSDNA) printf("\t|-- Converting %s\n", str);
if (convert_include(str)) {
return (1);
}
}
if (debugSDNA) printf("\tFinished scanning %d headers.\n", i);
if (calculate_structlens(firststruct)) {
// error
return(1);
}
/* FOR DEBUG */
if (debugSDNA > 1)
{
int a,b;
/* short *elem; */
short num_types;
printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
for(a=0; a<nr_names; a++) {
printf(" %s \n", names[a]);
}
printf("\n");
sp= typelens;
for(a=0; a<nr_types; a++, sp++) {
printf(" %s %d\n", types[a], *sp);
}
printf("\n");
for(a=0; a<nr_structs; a++) {
sp= structs[a];
printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1],typelens[sp[0]]);
num_types = sp[1];
sp+= 2;
/* ? num_types was elem? */
for(b=0; b< num_types; b++, sp+= 2) {
printf(" %s %s\n", types[sp[0]], names[sp[1]]);
}
}
}
/* file writing */
if (debugSDNA > -1) printf("Writing file ... ");
if(nr_names==0 || nr_structs==0);
else {
strcpy(str, "SDNA");
dna_write(file, str, 4);
/* write names */
strcpy(str, "NAME");
dna_write(file, str, 4);
len= nr_names;
dna_write(file, &len, 4);
/* calculate size of datablock with strings */
cp= names[nr_names-1];
cp+= strlen(names[nr_names-1]) + 1; /* +1: null-terminator */
len= (intptr_t) (cp - (char*) names[0]);
len= (len+3) & ~3;
dna_write(file, names[0], len);
/* write TYPES */
strcpy(str, "TYPE");
dna_write(file, str, 4);
len= nr_types;
dna_write(file, &len, 4);
/* calculate datablock size */
cp= types[nr_types-1];
cp+= strlen(types[nr_types-1]) + 1; /* +1: null-terminator */
len= (intptr_t) (cp - (char*) types[0]);
len= (len+3) & ~3;
dna_write(file, types[0], len);
/* WRITE TYPELENGTHS */
strcpy(str, "TLEN");
dna_write(file, str, 4);
len= 2*nr_types;
if(nr_types & 1) len+= 2;
dna_write(file, typelens, len);
/* WRITE STRUCTS */
strcpy(str, "STRC");
dna_write(file, str, 4);
len= nr_structs;
dna_write(file, &len, 4);
/* calc datablock size */
sp= structs[nr_structs-1];
sp+= 2+ 2*( sp[1] );
len= (intptr_t) ((char*) sp - (char*) structs[0]);
len= (len+3) & ~3;
dna_write(file, structs[0], len);
/* a simple dna padding test */
if (0) {
FILE *fp;
int a;
fp= fopen("padding.c", "w");
if(fp==NULL);
else {
// add all include files defined in the global array
for (i = 0; strlen(includefiles[i]); i++) {
fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
}
fprintf(fp, "main(){\n");
sp = typelens;
sp += firststruct;
for(a=firststruct; a<nr_types; a++, sp++) {
if(*sp) {
fprintf(fp, "\tif(sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp);
fprintf(fp, "%%d %s %d ", types[a], *sp);
fprintf(fp, "\\n\", sizeof(struct %s) - %d);\n", types[a], *sp);
}
}
fprintf(fp, "}\n");
fclose(fp);
}
}
/* end end padding test */
}
free(namedata);
free(typedata);
free(structdata);
free(names);
free(types);
free(typelens);
free(structs);
if (debugSDNA > -1) printf("done.\n");
return(0);
}
/* ************************* END MAKE DNA ********************** */
static void make_bad_file(char *file)
{
FILE *fp= fopen(file, "w");
fprintf(fp, "ERROR! Cannot make correct DNA.c file, STUPID!\n");
fclose(fp);
}
#ifndef BASE_HEADER
#define BASE_HEADER "../"
#endif
int main(int argc, char ** argv)
{
// printf("btCollisionObject=%d\n",sizeof(btCollisionObject));
// printf("btCollisionObjectData=%d\n",sizeof(btCollisionObjectData));
// printf("btTransform=%d\n",sizeof(btTransform));
// printf("btTransformData=%d\n",sizeof(btTransformData));
//
// btCollisionObject* bla = new btCollisionObject();
// btCollisionObjectData* bla2 = new btCollisionObjectData();
//int offsetof(bla,m_hasAnisotropicFriction);
/*
btTransformData m_worldTransform;
btTransform m_interpolationWorldTransform;
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
btVector3 m_anisotropicFriction;
bool m_hasAnisotropicFriction;
btScalar m_contactProcessingThreshold;
btBroadphaseProxy *m_broadphaseHandle;
btCollisionShape *m_collisionShape;
btCollisionShape *m_rootCollisionShape;
int m_collisionFlags;
int m_islandTag1;
int m_companionId;
int m_activationState1;
btScalar m_deactivationTime;
btScalar m_friction;
btScalar m_restitution;
void* m_userObjectPointer;
int m_internalType;
btScalar m_hitFraction;
btScalar m_ccdSweptSphereRadius;
btScalar m_ccdMotionThreshold;
bool m_checkCollideWith;
char m_pad[7];
*/
FILE *file;
int return_status = 0;
if (argc!=2 && argc!=3) {
printf("Usage: %s outfile.c [base directory]\n", argv[0]);
return_status = 1;
} else {
file = fopen(argv[1], "w");
if (!file) {
printf ("Unable to open file: %s\n", argv[1]);
return_status = 1;
} else {
char baseDirectory[256];
if (argc==3) {
strcpy(baseDirectory, argv[2]);
} else {
strcpy(baseDirectory, BASE_HEADER);
}
if (sizeof(void*)==8)
{
fprintf (file, "unsigned char sBulletDNAstr64[]= {\n");
} else
{
fprintf (file, "unsigned char sBulletDNAstr[]= {\n");
}
if (make_structDNA(baseDirectory, file)) {
// error
fclose(file);
make_bad_file(argv[1]);
return_status = 1;
} else {
fprintf(file, "};\n");
if (sizeof(void*)==8)
{
fprintf(file, "int sBulletDNAlen64= sizeof(sBulletDNAstr64);\n");
} else
{
fprintf(file, "int sBulletDNAlen= sizeof(sBulletDNAstr);\n");
}
fclose(file);
}
}
}
return(return_status);
}
/* end of list */