summaryrefslogtreecommitdiff
path: root/tools/convert
diff options
context:
space:
mode:
authorleocad1999-11-19 15:38:42 +0000
committerleocad1999-11-19 15:38:42 +0000
commit981d03141a8e035613562b45a5e9c0a2326059a0 (patch)
tree4e0b2f8b3f6401b9deaed5acc5235b6e66d0a3c0 /tools/convert
parent3585ac3b274f9693ba3b77ad8539774cbcd34f6c (diff)
Added the library conversion utilities
git-svn-id: http://svn.leocad.org/trunk@12 c7d43263-9d01-0410-8a33-9dba5d9f93d6
Diffstat (limited to 'tools/convert')
-rw-r--r--tools/convert/convert.c1720
-rw-r--r--tools/convert/convert.h221
-rw-r--r--tools/convert/moved.txt215
-rw-r--r--tools/convert/texture.cpp120
-rw-r--r--tools/convert/texture.h678
5 files changed, 2954 insertions, 0 deletions
diff --git a/tools/convert/convert.c b/tools/convert/convert.c
new file mode 100644
index 0000000..dfba77f
--- /dev/null
+++ b/tools/convert/convert.c
@@ -0,0 +1,1720 @@
+#include <stdio.h>
+#include <io.h>
+#include <malloc.h>
+#include <memory.h>
+#include <string.h>
+#include <math.h>
+#include <sys/stat.h>
+#include "convert.h"
+
+typedef struct CONNECTION
+{
+ unsigned char type;
+ float pos[3];
+ float up[3];
+ struct CONNECTION* next;
+} CONNECTION;
+
+typedef struct GROUP
+{
+ CONNECTION* connections[5];
+ void* drawinfo;
+ unsigned long infosize;
+ struct GROUP* next;
+} GROUP;
+
+typedef struct lineinfo_s
+{
+ unsigned char type;
+ unsigned char color;
+ float points[12];
+ struct lineinfo_s* next;
+} lineinfo_t;
+
+typedef struct TEXTURE
+{
+ float points[20];
+ unsigned char color;
+ char name[9];
+ struct TEXTURE* next;
+} TEXTURE;
+
+float* _fVerts;
+unsigned int _nVertsCount;
+CONNECTION* _pConnections;
+GROUP* _pGroups;
+TEXTURE* _pTextures;
+char _strName[9];
+char _strDescription[65];
+
+// stud, technic stud, stud under 1x? plate, stud under ?x? plate
+char* valid[12] = { "STUD.DAT", "STUD2.DAT", "STUD3.DAT", "STUD4.DAT" };
+unsigned char numvalid = 4;
+
+#define LC_MESH 1
+#define LC_STUD 2
+#define LC_STUD2 3
+#define LC_STUD3 4
+#define LC_STUD4 5
+
+/////////////////////////////////////////////////////
+// functions
+
+static unsigned long GetDefaultPieceGroup(char* name)
+{
+ char tmp[9];
+ strncpy (tmp, name, 9);
+// tmp[8] = 0;
+
+ if (strstr(tmp,"Baseplate") || strstr(tmp,"Plate") ||
+ strstr(tmp,"Platform"))
+ return 0x001;
+
+ if (strstr(tmp,"Brick") || strstr(tmp,"Cylin") ||
+ strstr(tmp,"Cone"))
+ return 0x002;
+
+ if (strstr(tmp,"Tile"))
+ return 0x004;
+
+ if (strstr(tmp,"Slope"))
+ return 0x008;
+
+ if (strstr(tmp,"Technic") || strstr(tmp,"Crane") ||
+ strstr(tmp,"Wheel") || strstr(tmp,"Tyre") ||
+ strstr(tmp,"Electric"))
+ return 0x010;
+
+ // space & plane
+ if (strstr(tmp,"Space") || strstr(tmp,"Plane") ||
+ strstr(tmp,"Windscr") || strstr(tmp,"~2421") ||
+ strstr(tmp,"Wing") || strstr(tmp,"Wedge") ||
+ strstr(tmp,"Propellor") || strstr(tmp,"Rotor") ||
+ strstr(tmp,"Rack") || strstr(tmp,"Tail"))
+ return 0x020;
+
+ if (strstr(tmp,"Train"))
+ return 0x040;
+
+ // other parts
+ if (strstr(tmp,"Arch") || strstr(tmp,"Panel") ||
+ strstr(tmp,"Car") || strstr(tmp,"Window") ||
+ strstr(tmp,"Freestyle") || strstr(tmp,"Support")||
+ strstr(tmp,"Fence") || strstr(tmp,"Gate") ||
+ strstr(tmp,"Garage") || strstr(tmp,"Stairs") ||
+ strstr(tmp,"Bracket") || strstr(tmp,"Hinge") ||
+ strstr(tmp,"Homemaker") || strstr(tmp,"Rock") ||
+ strstr(tmp,"Cupboard") || strstr(tmp,"Storage")||
+ strstr(tmp,"Scala") || strstr(tmp,"Boat") ||
+ strstr(tmp,"Trailer") || strstr(tmp,"Box") ||
+ strstr(tmp,"Turntab") || strstr(tmp,"Winch") ||
+ strstr(tmp,"Door") || strstr(tmp,"Magnet"))
+ return 0x080;
+
+ // accessories
+ if (strstr(tmp,"Minifig") || strstr(tmp,"Antenna")||
+ strstr(tmp,"Ladder") || strstr(tmp,"Jack") ||
+ strstr(tmp,"Exhaust") || strstr(tmp,"Lever") ||
+ strstr(tmp,"Roadsign") || strstr(tmp,"Town") ||
+ strstr(tmp,"Leaves") || strstr(tmp,"Horse") ||
+ strstr(tmp,"Tree") || strstr(tmp,"Flower") ||
+ strstr(tmp,"Plant") ||
+ strstr(tmp,"Conveyor") || strstr(tmp,"Tractor")||
+ strstr(tmp,"Grab") || strstr(tmp,"Roller") ||
+ strstr(tmp,"Stretch") || strstr(tmp,"Tap ") ||
+ strstr(tmp,"Forklift") || strstr(tmp,"Flag") ||
+ strstr(tmp,"Belville") || strstr(tmp,"Light &")||
+ strstr(tmp,"Hose") || strstr(tmp,"Arm P") ||
+ strstr(tmp,"Brush") || strstr(tmp,"Castle") ||
+ strstr(tmp,"Tipper") || strstr(tmp,"Bar"))
+ return 0x100;
+
+ return 1;
+}
+
+static __inline GROUP* NewGroup()
+{
+ GROUP* pGroup;
+
+ if (_pGroups)
+ {
+ pGroup = _pGroups;
+ while (pGroup->next)
+ pGroup = pGroup->next;
+ pGroup->next = (GROUP*)malloc(sizeof(GROUP));
+ pGroup = pGroup->next;
+ }
+ else
+ {
+ _pGroups = (GROUP*)malloc(sizeof(GROUP));
+ pGroup = _pGroups;
+ }
+
+ memset(pGroup, 0, sizeof(GROUP));
+
+ return pGroup;
+}
+
+static __inline CONNECTION* AddConnection(CONNECTION* pNew)
+{
+ CONNECTION* pCon;
+
+ pCon = _pConnections;
+ while (pCon)
+ {
+ if ((pCon->type == pNew->type) &&
+ FloatPointsClose(pCon->pos, pNew->pos) &&
+ FloatPointsClose(pCon->up, pNew->up))
+ {
+ free(pNew);
+ return pCon;
+ }
+
+ pCon = pCon->next;
+ }
+
+ if (_pConnections)
+ {
+ pCon = _pConnections;
+ while (pCon->next)
+ pCon = pCon->next;
+ pCon->next = pNew;
+ }
+ else
+ {
+ _pConnections = pNew;
+ pNew->next = NULL;
+ }
+
+ return pNew;
+}
+
+void CleanUp()
+{
+ GROUP *tmp, *pg = _pGroups;
+ CONNECTION *ctmp, *pc = _pConnections;
+ TEXTURE *ttmp, *pt = _pTextures;
+ _nVertsCount = 0;
+ _pGroups = NULL;
+ _pConnections = NULL;
+ _pTextures = NULL;
+
+ if (_fVerts != NULL)
+ {
+ free(_fVerts);
+ _fVerts = NULL;
+ }
+
+ while (pt)
+ {
+ ttmp = pt->next;
+ free(pt);
+ pt = ttmp;
+ };
+
+ while (pg != NULL)
+ {
+ free (pg->drawinfo);
+ tmp = pg;
+ pg = pg->next;
+ free (tmp);
+ }
+
+ while (pc != NULL)
+ {
+ ctmp = pc;
+ pc = pc->next;
+ free (ctmp);
+ }
+}
+
+void CreateMesh(GROUP* pGroup, lineinfo_t* info)
+{
+ lineinfo_t *a, *b;
+ int i, j, k, v;
+ unsigned int count[256][3], vert = 0;
+ unsigned char* bytes;
+ memset (count, 0, sizeof(count));
+
+ for (a = info->next; a; a = a->next)
+ {
+ count[a->color][a->type-2]++;
+ vert += a->type;
+ }
+
+ k = 0;
+ for (i = 0; i < 256; i++)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ k++;
+ }
+
+ if (_nVertsCount > 65535)
+ {
+ unsigned long* drawinfo;
+ pGroup->infosize = sizeof(unsigned long)*(vert + (k*4)+1) + 2;
+ pGroup->drawinfo = malloc(pGroup->infosize);
+ bytes = (unsigned char*)pGroup->drawinfo;
+ drawinfo = (unsigned long*)(bytes + 1);
+ *bytes = LC_MESH;
+ *drawinfo = k; // number colors
+ drawinfo++;
+
+ for (i = 16; i < 256; i++)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ {
+ *drawinfo = i;
+ drawinfo++;
+
+ printf("%d ", i);
+
+ for (j = 4; j > 1; j--)
+ {
+ *drawinfo = count[i][j-2]*j;
+ drawinfo++;
+ printf("%d ", count[i][j-2]*j);
+
+ if (count[i][j-2] != 0)
+ {
+ a = info->next;
+ b = info;
+ while(a)
+ if ((a->type == j) && (a->color == i))
+ {
+ for (k = 0; k < a->type; k++)
+ for (v = 0; v < (int)_nVertsCount; v++)
+ if (FloatPointsClose(&_fVerts[v*3], &a->points[k*3]))
+ {
+ *drawinfo = v;
+ drawinfo++;
+ break;
+ }
+
+ b->next = a->next;
+ free(a);
+ a = b->next;
+ }
+ else
+ {
+ b = a;
+ a = a->next;
+ }
+ }
+ }
+ }
+
+ if (i == 16) i = -1;
+ if (i == 15) i = 23;
+ }
+
+ printf("\n");
+ }
+ else
+ {
+ unsigned short* drawinfo;
+ pGroup->infosize = sizeof(unsigned short)*(vert + (k*4)+1) + 2;
+ pGroup->drawinfo = malloc(pGroup->infosize);
+ bytes = (unsigned char*)pGroup->drawinfo;
+ drawinfo = (unsigned short*)(bytes + 1);
+ *bytes = LC_MESH;
+ *drawinfo = k; // number colors
+ drawinfo++;
+
+ for (i = 16; i < 256; i++)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ {
+ *drawinfo = i;
+ drawinfo++;
+ }
+
+ for (j = 4; j > 1; j--)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ {
+ *drawinfo = count[i][j-2]*j;
+ drawinfo++;
+ }
+
+ if (count[i][j-2] != 0)
+ {
+ a = info->next;
+ b = info;
+ while(a)
+ if ((a->type == j) && (a->color == i))
+ {
+ for (k = 0; k < a->type; k++)
+ for (v = 0; v < (int)_nVertsCount; v++)
+ if (FloatPointsClose(&_fVerts[v*3], &a->points[k*3]))
+ {
+ *drawinfo = v;
+ drawinfo++;
+ break;
+ }
+
+ b->next = a->next;
+ free(a);
+ a = b->next;
+ }
+ else
+ {
+ b = a;
+ a = a->next;
+ }
+ }
+ }
+
+ if (i == 16) i = -1;
+ if (i == 15) i = 23;
+ }
+ }
+
+ bytes[pGroup->infosize-1] = 0; // End
+}
+
+void decodefile (FILE *F, matrix *mat, unsigned char defcolor, lineinfo_t* info, char* dir)
+{
+ char buf[1024];
+ int type, color;
+ char fn[260], filename[32];
+ float fm[12];
+ unsigned char val;
+ FILE *tf;
+
+ while (fgets(buf, 1024, F))
+ {
+ while (buf[strlen(buf)-1] == 10 || buf[strlen(buf)-1] == 13 || buf[strlen(buf)-1] == 32)
+ buf[strlen(buf)-1] = 0;
+
+ type = -1;
+ sscanf(buf, "%d", &type);
+
+ if (type == 6)
+ {
+ float* f;
+
+ TEXTURE* tex;
+ if (_pTextures)
+ {
+ tex = _pTextures;
+ while (tex->next)
+ tex = tex->next;
+ tex->next = (TEXTURE*)malloc(sizeof(TEXTURE));
+ tex = tex->next;
+ }
+ else
+ {
+ _pTextures = (TEXTURE*)malloc(sizeof(TEXTURE));
+ tex = _pTextures;
+ }
+ memset(tex, 0, sizeof(TEXTURE));
+ f = tex->points;
+
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %s",
+ &type, &color, &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19], tex->name);
+ tex->color = color;
+ ConvertPoints (f, 4);
+
+ continue;
+ }
+
+ if (type > 1 && type < 5)
+ {
+ lineinfo_t* newinfo = (lineinfo_t*)malloc(sizeof(lineinfo_t));
+ info->next = newinfo;
+ newinfo->next = 0;
+ newinfo->type = type;
+ info = newinfo;
+ }
+
+ switch (type)
+ {
+ case 1:
+ {
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f %f %f %f %s",
+ &type, &color, &fm[0], &fm[1], &fm[2], &fm[3], &fm[4], &fm[5], &fm[6], &fm[7], &fm[8], &fm[9], &fm[10], &fm[11], filename);
+
+ strcpy (fn, dir);
+ strcat (fn, "P\\");
+ strcat (fn, filename);
+
+ strupr(filename);
+ for (val = 0; val < numvalid; val++)
+ if (strcmp(filename, valid[val]) == 0)
+ break;
+ if (val != numvalid)
+ break;
+
+ if (color == 16) color = defcolor;
+
+ tf = fopen (fn, "rt");
+
+ if (!tf)
+ {
+ strcpy (fn, dir);
+ strcat (fn, "PARTS\\");
+ strcat (fn, filename);
+ tf = fopen (fn, "rt");
+ }
+
+ if (!tf)
+ {
+ strcpy (fn, dir);
+ strcat (fn, "PARTS\\S\\");
+ strcat (fn, filename);
+ tf = fopen (fn, "rt");
+ }
+
+ if (tf)
+ {
+ matrix m1, m2;
+ LoadIdentity(&m1);
+ LoadIdentity(&m2);
+ ConvertFromLDraw (&m1, fm);
+ Multiply(&m2, mat, &m1);
+
+ decodefile (tf, &m2, (unsigned char)color, info, dir);
+ while (info->next)
+ info = info->next;
+ fclose(tf);
+ }
+ } break;
+
+ case 2:
+ {
+ sscanf (buf, "%d %d %f %f %f %f %f %f", &type, &color,
+ &info->points[0], &info->points[1], &info->points[2],
+ &info->points[3], &info->points[4], &info->points[5]);
+ if (color == 16) color = defcolor;
+ if (color > 256) color -= 256;
+ info->color = color;
+ ConvertPoints (info->points, 2);
+ TransformPoints (mat, info->points, 2);
+ } break;
+
+ case 3:
+ {
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f", &type, &color,
+ &info->points[0], &info->points[1], &info->points[2],
+ &info->points[3], &info->points[4], &info->points[5],
+ &info->points[6], &info->points[7], &info->points[8]);
+ if (color == 16) color = defcolor;
+ if (color > 256) color -= 256;
+ info->color = color;
+ ConvertPoints (info->points, 3);
+ TransformPoints (mat, info->points, 3);
+ } break;
+
+ case 4:
+ {
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f %f %f %f", &type, &color,
+ &info->points[0], &info->points[1], &info->points[2],
+ &info->points[3], &info->points[4], &info->points[5],
+ &info->points[6], &info->points[7], &info->points[8],
+ &info->points[9], &info->points[10], &info->points[11]);
+ if (color == 16) color = defcolor;
+ if (color > 256) color -= 256;
+ info->color = color;
+ ConvertPoints (info->points, 4);
+ TransformPoints (mat, info->points, 4);
+ FixQuads(info->points);
+
+#ifdef TRIANGULATE
+ LINEINFO* newinfo = (LINEINFO*)malloc(sizeof(LINEINFO));
+ info->next = newinfo;
+ info->type = 3;
+ newinfo->next = NULL;
+ newinfo->type = 3;
+ newinfo->color = color;
+ newinfo->points[0] = info->points[6];
+ newinfo->points[1] = info->points[7];
+ newinfo->points[2] = info->points[8];
+ newinfo->points[3] = info->points[9];
+ newinfo->points[4] = info->points[10];
+ newinfo->points[5] = info->points[11];
+ newinfo->points[6] = info->points[0];
+ newinfo->points[7] = info->points[1];
+ newinfo->points[8] = info->points[2];
+ info = newinfo;
+#endif
+ } break;
+
+ }
+ memset (buf, 0, sizeof(buf));
+ }
+}
+
+void decodeconnections (FILE *F, matrix *mat, unsigned char defcolor, char* dir)
+{
+ char buf[1024];
+ int type, color;
+ char fn[260], filename[32];
+ float fm[12];
+ matrix m1, m2;
+ unsigned char val;
+ FILE *tf;
+ GROUP* pGroup;
+ CONNECTION* pCon;
+ unsigned char* bytes;
+ float* floats;
+
+ while (fgets(buf, 1024, F))
+ {
+ while (buf[strlen(buf)-1] == 10 || buf[strlen(buf)-1] == 13 || buf[strlen(buf)-1] == 32)
+ buf[strlen(buf)-1] = 0;
+
+ type = -1;
+ sscanf(buf, "%d", &type);
+
+ if (type != 1)
+ {
+ memset (buf, 0, sizeof(buf));
+ continue;
+ }
+
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f %f %f %f %s",
+ &type, &color, &fm[0], &fm[1], &fm[2], &fm[3], &fm[4], &fm[5], &fm[6], &fm[7], &fm[8], &fm[9], &fm[10], &fm[11], filename);
+
+ strcpy (fn, dir);
+ strcat (fn, "P\\");
+ strcat (fn, filename);
+
+ if (color == 16) color = defcolor;
+
+ strupr(filename);
+ for (val = 0; val < numvalid; val++)
+ if (strcmp(filename, valid[val]) == 0)
+ {
+ LoadIdentity(&m1);
+ LoadIdentity(&m2);
+ ConvertFromLDraw (&m1, fm);
+ Multiply (&m2, mat, &m1);
+
+ if (val == 0) // STUD.DAT
+ {
+ pGroup = NewGroup();
+ pCon = (CONNECTION*)malloc(sizeof(CONNECTION));
+ memset(pCon, 0, sizeof(CONNECTION));
+
+ pGroup->infosize = 3*sizeof(unsigned char) + 12*sizeof(float);
+ pGroup->drawinfo = malloc(pGroup->infosize);
+ bytes = pGroup->drawinfo;
+ floats = (float*)(bytes+2);
+
+ bytes[0] = LC_STUD;
+ bytes[1] = color; // color
+ floats[0] = m2.m[0];
+ floats[1] = m2.m[1];
+ floats[2] = m2.m[2];
+ floats[3] = m2.m[4];
+ floats[4] = m2.m[5];
+ floats[5] = m2.m[6];
+ floats[6] = m2.m[8];
+ floats[7] = m2.m[9];
+ floats[8] = m2.m[10];
+ floats[9] = m2.m[12];
+ floats[10] = m2.m[13];
+ floats[11] = m2.m[14];
+ bytes[pGroup->infosize-1] = 0; // end
+
+ pCon->type = 0; // stud
+ pCon->pos[0] = m2.m[12];
+ pCon->pos[1] = m2.m[13];
+ pCon->pos[2] = m2.m[14];
+ pCon->up[2] = 1;
+ TransformPoints(&m2, pCon->up, 1);
+ pCon->up[0] -= m2.m[12];
+ pCon->up[1] -= m2.m[13];
+ pCon->up[2] -= m2.m[14];
+
+ pCon = AddConnection(pCon);
+ pGroup->connections[0] = pCon;
+ }
+
+ if (val == 1) // STUD2.DAT
+ {
+ pGroup = NewGroup();
+ pCon = (CONNECTION*)malloc(sizeof(CONNECTION));
+ memset(pCon, 0, sizeof(CONNECTION));
+
+ pGroup->infosize = 3*sizeof(unsigned char) + 12*sizeof(float);
+ pGroup->drawinfo = malloc(pGroup->infosize);
+ bytes = pGroup->drawinfo;
+ floats = (float*)(bytes+2);
+
+ bytes[0] = LC_STUD2;
+ bytes[1] = color; // color
+ floats[0] = m2.m[0];
+ floats[1] = m2.m[1];
+ floats[2] = m2.m[2];
+ floats[3] = m2.m[4];
+ floats[4] = m2.m[5];
+ floats[5] = m2.m[6];
+ floats[6] = m2.m[8];
+ floats[7] = m2.m[9];
+ floats[8] = m2.m[10];
+ floats[9] = m2.m[12];
+ floats[10] = m2.m[13];
+ floats[11] = m2.m[14];
+ bytes[pGroup->infosize-1] = 0; // end
+
+ pCon->type = 0; // stud
+ pCon->pos[0] = m2.m[12];
+ pCon->pos[1] = m2.m[13];
+ pCon->pos[2] = m2.m[14];
+ pCon->up[2] = 1;
+ TransformPoints(&m2, pCon->up, 1);
+ pCon->up[0] -= m2.m[12];
+ pCon->up[1] -= m2.m[13];
+ pCon->up[2] -= m2.m[14];
+
+ pCon = AddConnection(pCon);
+ pGroup->connections[0] = pCon;
+ }
+
+ if (val == 2) // STUD3.DAT
+ {
+ pGroup = NewGroup();
+ pGroup->infosize = 3*sizeof(unsigned char) + 12*sizeof(float);
+ pGroup->drawinfo = malloc(pGroup->infosize);
+ bytes = pGroup->drawinfo;
+ floats = (float*)(bytes+2);
+
+ bytes[0] = LC_STUD3;
+ bytes[1] = color; // color
+ floats[0] = m2.m[0];
+ floats[1] = m2.m[1];
+ floats[2] = m2.m[2];
+ floats[3] = m2.m[4];
+ floats[4] = m2.m[5];
+ floats[5] = m2.m[6];
+ floats[6] = m2.m[8];
+ floats[7] = m2.m[9];
+ floats[8] = m2.m[10];
+ floats[9] = m2.m[12];
+ floats[10] = m2.m[13];
+ floats[11] = m2.m[14];
+ bytes[pGroup->infosize-1] = 0; // end
+ }
+
+ if (val == 3) // STUD4.DAT
+ {
+ float t[4][3] = { {0.4f,0.4f,0}, {-0.4f,0.4f,0}, {0.4f,-0.4f,0}, {-0.4f,-0.4f,0} };
+ int c;
+
+ pGroup = NewGroup();
+ pGroup->infosize = 3*sizeof(unsigned char) + 12*sizeof(float);
+ pGroup->drawinfo = malloc(pGroup->infosize);
+ bytes = pGroup->drawinfo;
+ floats = (float*)(bytes+2);
+
+ bytes[0] = LC_STUD4;
+ bytes[1] = color; // color
+ floats[0] = m2.m[0];
+ floats[1] = m2.m[1];
+ floats[2] = m2.m[2];
+ floats[3] = m2.m[4];
+ floats[4] = m2.m[5];
+ floats[5] = m2.m[6];
+ floats[6] = m2.m[8];
+ floats[7] = m2.m[9];
+ floats[8] = m2.m[10];
+ floats[9] = m2.m[12];
+ floats[10] = m2.m[13];
+ floats[11] = m2.m[14];
+ bytes[pGroup->infosize-1] = 0; // end
+
+ for (c = 0; c < 4; c++)
+ {
+ pCon = (CONNECTION*)malloc(sizeof(CONNECTION));
+ memset(pCon, 0, sizeof(CONNECTION));
+ pCon->type = 1; // inv stud
+ TranslatePoint(&m2, pCon->pos, t[c]);
+ pCon->pos[2] -= 0.16f;
+
+ pCon->up[2] = 1;
+ TransformPoints(&m2, pCon->up, 1);
+ pCon->up[0] -= m2.m[12];
+ pCon->up[1] -= m2.m[13];
+ pCon->up[2] -= m2.m[14];
+
+ pGroup->connections[c] = AddConnection(pCon);
+ }
+
+ pCon = (CONNECTION*)malloc(sizeof(CONNECTION));
+ memset(pCon, 0, sizeof(CONNECTION));
+ pCon->type = 1; // inv stud
+ pCon->pos[2] -= 0.16f;
+
+ pCon->up[2] = 1;
+ TransformPoints(&m2, pCon->up, 1);
+ pCon->up[0] -= m2.m[12];
+ pCon->up[1] -= m2.m[13];
+ pCon->up[2] -= m2.m[14];
+
+ AddConnection(pCon);
+ }
+
+ memset (buf, 0, sizeof(buf));
+ continue;
+ }
+
+ tf = fopen (fn, "rt");
+
+ if (!tf)
+ {
+ strcpy (fn, dir);
+ strcat (fn, "PARTS\\");
+ strcat (fn, filename);
+ tf = fopen (fn, "rt");
+ }
+
+ if (!tf)
+ {
+ strcpy (fn, dir);
+ strcat (fn, "PARTS\\S\\");
+ strcat (fn, filename);
+ tf = fopen (fn, "rt");
+ }
+
+ if (tf)
+ {
+ matrix m1, m2;
+ LoadIdentity(&m1);
+ LoadIdentity(&m2);
+ ConvertFromLDraw (&m1, fm);
+ Multiply(&m2, mat, &m1);
+
+ decodeconnections (tf, &m2, (unsigned char)color, dir);
+// while (info->next)
+// info = info->next;
+ fclose(tf);
+ }
+
+ memset (buf, 0, sizeof(buf));
+ }
+}
+
+void ReadFile(char* strFile)
+{
+ char fn[260], tmp[260], *ptr;
+ matrix mat;
+ float* verts;
+ unsigned long i, j, unique;
+ lineinfo_t info, *a;
+ FILE *f;
+// drawgroup_t* ldg;
+
+ CleanUp();
+ memset(_strName, 0, sizeof(_strName));
+ memset(_strDescription, 0, sizeof(_strDescription));
+
+ strcpy(tmp, strFile);
+ if (ptr = strrchr(tmp, '.')) *ptr = 0;
+ ptr = strrchr(tmp, '\\');
+ if (ptr == NULL)
+ ptr = tmp;
+ else
+ ptr++;
+ strcpy (_strName, ptr);
+ strupr (_strName);
+
+//(&_fVerts, &_nVertsCount);
+//(float** ppVerts, unsigned int* nCount)
+ LoadIdentity(&mat);
+ info.next = 0;
+ info.type = 0;
+
+ f = fopen (strFile, "rt");
+ if (fgets (tmp, 100, f))
+ {
+ while (tmp[strlen(tmp)-1]==10||tmp[strlen(tmp)-1]==13||tmp[strlen(tmp)-1]==32)
+ tmp[strlen(tmp)-1]=0;
+ tmp[66] = 0;
+ strcpy (_strDescription, tmp+2);
+ }
+
+ printf("File %s : %s\n", _strName, _strDescription);
+
+ strcpy (fn, strFile);
+ if (ptr = strrchr(fn, '.')) *ptr = 0;
+ memset (tmp, 0, sizeof(char[100]));
+ ptr = strrchr(fn, '\\');
+ if (ptr == 0)
+ ptr = fn;
+ else
+ ptr++;
+ strcpy (tmp, ptr);
+ strupr (tmp);
+
+ strcpy (fn, strFile);
+ ptr = strrchr(fn, '\\');
+ *ptr = 0;
+ ptr = strrchr(fn, '\\');
+ *(ptr+1) = 0;
+
+ decodefile (f, &mat, 16, &info, fn);
+ fclose (f);
+
+ unique = 0;
+ verts = (float*)malloc(sizeof(float)*1500);
+
+ // Create array of unique vertices
+ for (a = info.next; a; a = a->next)
+ {
+ for (j = 0; j < a->type; j++)
+ {
+ for (i = unique-1; i != -1; i--)
+ if (FloatPointsClose(&verts[i*3], &a->points[j*3]))
+ break;
+
+ if (i == -1)
+ {
+ if ((unique % 500) == 0)
+ verts = (float*)realloc(verts, sizeof(float)*3*(unique+500));
+ memcpy(&verts[unique*3], &a->points[j*3], sizeof(float)*3);
+ unique++;
+ }
+ }
+ }
+
+ _fVerts = verts;
+ _nVertsCount = unique;
+ printf ("%d vertexes\n", unique);
+
+ // Main group
+ _pGroups = (GROUP*)malloc(sizeof(GROUP));
+ memset(_pGroups, 0, sizeof(GROUP));
+ CreateMesh(_pGroups, &info);
+
+ a = info.next;
+ while (a)
+ {
+ lineinfo_t* b = a->next;
+ free(a);
+ a = b;
+ }
+ info.next = 0;
+
+/*
+ char filename[32], name[260];
+ FILE *tf;
+ matrix m1,m2;
+ int type, color;
+ char buf[1024];
+ float fm[12];
+*/
+ // Included files
+ f = fopen (strFile, "rt");
+ LoadIdentity(&mat);
+ decodeconnections(f, &mat, 16, fn);
+ fclose(f);
+/*
+ while (fgets(buf, 1024, f))
+ {
+ while (buf[strlen(buf)-1] == 10 || buf[strlen(buf)-1] == 13 || buf[strlen(buf)-1] == 32)
+ buf[strlen(buf)-1] = 0;
+
+ type = -1;
+ sscanf(buf, "%d", &type);
+
+ if (type == 1)
+ {
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f %f %f %f %s",
+ &type, &color, &fm[0], &fm[1], &fm[2], &fm[3], &fm[4], &fm[5], &fm[6], &fm[7], &fm[8], &fm[9], &fm[10], &fm[11], filename);
+
+ strupr(filename);
+ LoadIdentity(&mat);
+ info.next = 0;
+
+ ldg->next = (drawgroup_t*)malloc(sizeof(drawgroup_t));
+ ldg = ldg->next;
+ memset(ldg, 0, sizeof(drawgroup_t));
+
+ strcpy (name, fn);
+ strcat (name, "P\\");
+ strcat (name, filename);
+
+ tf = fopen (name, "rt");
+
+ if (!tf)
+ {
+ strcpy (name, fn);
+ strcat (name, "PARTS\\");
+ strcat (name, filename);
+ tf = fopen (name, "rt");
+ }
+
+ if (!tf)
+ {
+ strcpy (name, fn);
+ strcat (name, "PARTS\\S\\");
+ strcat (name, filename);
+ tf = fopen (name, "rt");
+ }
+
+ if (ptr = strrchr(filename, '.')) *ptr = 0;
+ strcpy(ldg->name, filename);
+
+ LoadIdentity(&m1);
+ LoadIdentity(&m2);
+ ConvertFromLDraw (&m1, fm);
+ Multiply (&m2, &mat, &m1);
+/*
+ if (strcmp(ldg->name, "STUD") == 0)
+ {
+ ldg->pos[0] = m2.m[12];
+ ldg->pos[1] = m2.m[13];
+ ldg->pos[2] = m2.m[14];
+ ldg->up[2] = 1;
+ m2.TransformPoints(ldg->up, 1);
+ ldg->up[0] -= m2.m[12];
+ ldg->up[1] -= m2.m[13];
+ ldg->up[2] -= m2.m[14];
+ ldg->type = 1;
+ }
+
+ if (strcmp(ldg->name, "STUD4") == 0)
+ {
+ ldg->pos[0] = m2.m[12];
+ ldg->pos[1] = m2.m[13];
+ ldg->pos[2] = m2.m[14];
+ ldg->up[2] = 1;
+ m2.TransformPoints(ldg->up, 1);
+ ldg->up[0] -= m2.m[12];
+ ldg->up[1] -= m2.m[13];
+ ldg->up[2] -= m2.m[14];
+ ldg->type = 0;
+ }
+
+ decodefile (tf, &m2, (unsigned char)color, &info, fn);
+ AddDrawInfo (ldg, &info, verts, unique);
+ fclose(tf);
+ }
+ }
+*/
+}
+
+void SaveFile(FILE *bin, FILE *idx, unsigned long *binoff)
+{
+ unsigned long i;
+ float box[6] = { -100, -100, -100, 100, 100, 100 };
+ float maxdim;
+ GROUP* pGroup;
+ CONNECTION* pCon;
+ matrix mat;
+ TEXTURE* tex;
+ short scale;
+ unsigned short s;
+ unsigned char bt;
+ short sb[6];
+
+ pGroup = _pGroups;
+ while (pGroup)
+ {
+ unsigned char* bytes = (unsigned char*)pGroup->drawinfo;
+ float* floats;
+
+ while (*bytes)
+ {
+ if (*bytes == LC_MESH)
+ {
+ if (_nVertsCount > 65535)
+ {
+ unsigned long colors, *p;
+ p = (unsigned long*)(bytes + 1);
+ colors = *p;
+ p++;
+
+ while (colors--)
+ {
+ p++; // color code
+ p += *p + 1;
+ p += *p + 1;
+ p += *p + 1;
+ }
+
+ bytes = (unsigned char*)p;
+ }
+ else
+ {
+ unsigned short colors, *p;
+ p = (unsigned short*)(bytes + 1);
+ colors = *p;
+ p++;
+
+ while (colors--)
+ {
+ p++; // color code
+ p += *p + 1;
+ p += *p + 1;
+ p += *p + 1;
+ }
+
+ bytes = (unsigned char*)p;
+ }
+ }
+
+ if ((*bytes == LC_STUD) || (*bytes == LC_STUD2))
+ {
+ float stud[6] = { 0.16f, 0.16f, 0.16f, -0.16f, -0.16f, 0 };
+ floats = (float*)(bytes+2);
+
+ LoadIdentity(&mat);
+ mat.m[0] = floats[0];
+ mat.m[1] = floats[1];
+ mat.m[2] = floats[2];
+ mat.m[4] = floats[3];
+ mat.m[5] = floats[4];
+ mat.m[6] = floats[5];
+ mat.m[8] = floats[6];
+ mat.m[9] = floats[7];
+ mat.m[10] = floats[8];
+ mat.m[12] = floats[9];
+ mat.m[13] = floats[10];
+ mat.m[14] = floats[11];
+ TransformPoints (&mat, stud, 2);
+
+ for (i = 0; i < 2; i++)
+ {
+ if (stud[(3*i)] > box[0]) box[0] = stud[(3*i)];
+ if (stud[(3*i)+1] > box[1]) box[1] = stud[(3*i)+1];
+ if (stud[(3*i)+2] > box[2]) box[2] = stud[(3*i)+2];
+ if (stud[(3*i)] < box[3]) box[3] = stud[(3*i)];
+ if (stud[(3*i)+1] < box[4]) box[4] = stud[(3*i)+1];
+ if (stud[(3*i)+2] < box[5]) box[5] = stud[(3*i)+2];
+ }
+
+ bytes += 2*sizeof(unsigned char) + 12*sizeof(float);
+ }
+
+ if ((*bytes == LC_STUD4) || (*bytes == LC_STUD3))
+ bytes += 2*sizeof(unsigned char) + 12*sizeof(float);
+ }
+
+ pGroup = pGroup->next;
+ }
+
+ for (i = 0; i < _nVertsCount; i++)
+ {
+ if (_fVerts[(3*i)] > box[0]) box[0] = _fVerts[(3*i)];
+ if (_fVerts[(3*i)+1] > box[1]) box[1] = _fVerts[(3*i)+1];
+ if (_fVerts[(3*i)+2] > box[2]) box[2] = _fVerts[(3*i)+2];
+ if (_fVerts[(3*i)] < box[3]) box[3] = _fVerts[(3*i)];
+ if (_fVerts[(3*i)+1] < box[4]) box[4] = _fVerts[(3*i)+1];
+ if (_fVerts[(3*i)+2] < box[5]) box[5] = _fVerts[(3*i)+2];
+ }
+
+ maxdim = 0;
+ for (i = 0; i < 6; i++)
+ if (fabs(box[i]) > maxdim) maxdim = (float)fabs(box[i]);
+ scale = 10000;
+ if (maxdim > 3.2f)
+ scale = 1000;
+ if (maxdim > 32.0f)
+ scale = 100;
+
+ // write the vertex data
+ fwrite(&_nVertsCount, sizeof(_nVertsCount), 1, bin);
+ for (i = 0; i < _nVertsCount; i++)
+ {
+ float tmp[3] = { scale*_fVerts[(i*3)], scale*_fVerts[(i*3)+1], scale*_fVerts[(i*3)+2] };
+ short sh[3] = { (short)tmp[0], (short)tmp[1], (short)tmp[2] };
+ fwrite(&sh, sizeof(sh), 1, bin);
+ }
+
+ s = 0;
+ pCon = _pConnections;
+ while (pCon)
+ {
+ s++;
+ pCon = pCon->next;
+ }
+ fwrite(&s, sizeof(s), 1, bin);
+
+ pCon = _pConnections;
+ while (pCon)
+ {
+ float tmp[3] = { scale*pCon->pos[0], scale*pCon->pos[1], scale*pCon->pos[2] };
+ short sh[3] = { (short)tmp[0], (short)tmp[1], (short)tmp[2] };
+
+ fwrite(&pCon->type, sizeof(pCon->type), 1, bin);
+ fwrite(&sh, sizeof(sh), 1, bin);
+
+ sh[0] = (short)(pCon->up[0]*(1<<14));
+ sh[1] = (short)(pCon->up[1]*(1<<14));
+ sh[2] = (short)(pCon->up[2]*(1<<14));
+ fwrite(&sh, sizeof(sh), 1, bin);
+
+ pCon = pCon->next;
+ }
+
+ // Textures
+ bt = 0;
+ for (tex = _pTextures; tex; tex = tex->next)
+ bt++;
+ fwrite(&bt, 1, 1, bin);
+
+ for (tex = _pTextures; tex; tex = tex->next)
+ {
+ fwrite(&tex->color, 1, 1, bin);
+ fwrite(tex->name, 8, 1, bin);
+
+ for (i = 0; i < 12; i++)
+ {
+ float tmp[1] = { tex->points[i]*scale };
+ short sh[1] = { (short)tmp[0] };
+ fwrite(&sh, sizeof(sh), 1, bin);
+ }
+ for (i = 12; i < 20; i++)
+ {
+ float tmp[1] = { tex->points[i] };
+ short sh[1] = { (short)tmp[0] };
+ fwrite(&sh, sizeof(sh), 1, bin);
+ }
+ }
+
+ s = 0;
+ pGroup = _pGroups;
+ while (pGroup)
+ {
+ s++;
+ pGroup = pGroup->next;
+ }
+ fwrite(&s, sizeof(s), 1, bin);
+
+ pGroup = _pGroups;
+ while (pGroup)
+ {
+ for (bt = 0; bt < 5; bt++)
+ if (!pGroup->connections[bt])
+ break;
+ fwrite(&bt, sizeof(bt), 1, bin);
+
+ for (bt = 0; bt < 5; bt++)
+ {
+ if (!pGroup->connections[bt])
+ break;
+
+ s = 0;
+ pCon = _pConnections;
+ while (pCon)
+ {
+ if (pCon == pGroup->connections[bt])
+ break;
+ pCon = pCon->next;
+ s++;
+ }
+ fwrite(&s, sizeof(s), 1, bin);
+ }
+
+ fwrite(pGroup->drawinfo, pGroup->infosize, 1, bin);
+
+ pGroup = pGroup->next;
+ }
+
+ fwrite(_strName, 8, 1, idx);
+ fwrite(_strDescription, 64, 1, idx);
+ for (i = 0; i < 6; i++)
+ {
+ float ff, f = 1.0f * box[i];
+ f *= scale;
+ ff = f;
+// sb[i] = scale*box[i];
+ sb[i] = (short)ff;
+ }
+ fwrite(&sb, sizeof(sb), 1, idx);
+ bt = 0x01; // LC_PIECE_COUNT
+ if (scale == 10000) bt |= 0x10; // LC_PIECE_SMALL
+ if (scale == 1000) bt |= 0x20; // LC_PIECE_MEDIUM
+ fwrite(&bt, sizeof(bt), 1, idx);
+ i = GetDefaultPieceGroup(_strDescription);
+ fwrite(&i, sizeof(i), 1, idx);
+ fwrite(binoff, sizeof(*binoff), 1, idx);
+ i = ftell(bin) - *binoff;
+ fwrite(&i, sizeof(i), 1, idx);
+ *binoff = ftell(bin);
+}
+
+int main(int argc, char *argv[])
+{
+ struct _finddata_t c_file;
+ long hFile;
+ char tmp[260];
+ FILE *bin, *idx;
+ unsigned long binoff;
+ unsigned short count, moved;
+
+ if (argc != 2)
+ {
+ argv[1] = "f:\\ldraw\\parts\\";
+
+// printf("Usage: convert <ldraw/parts/>\n");
+// return 1;
+ }
+
+ _fVerts = 0;
+ _nVertsCount = 0;
+ _pGroups = 0;
+ _pConnections = 0;
+ _pTextures = 0;
+
+ strcpy(tmp, argv[1]);
+ strcat(tmp, "*.dat");
+
+ if((hFile = _findfirst(tmp, &c_file )) == -1L)
+ printf( "No *.dat files in current directory!\n");
+ else
+ {
+ char strbin[32] = "LeoCAD piece library data file\0\0";
+ char stridx[32] = "LeoCAD piece library index file\0";
+ unsigned char bt;
+
+ bin = fopen("PIECES.BIN", "wb");
+ idx = fopen("PIECES.IDX", "wb");
+ fwrite(strbin, 32, 1, bin);
+ binoff = 32;
+ fwrite(stridx, 32, 1, idx);
+ bt = 3; // version
+ fwrite(&bt, 1, 1, idx);
+ bt = 3; // last update
+ fwrite(&bt, 1, 1, idx);
+
+ strcpy(tmp, argv[1]);
+ strcat(tmp, c_file.name);
+ count = 1;
+
+ ReadFile(tmp);
+ printf("Saving...\n");
+ SaveFile(bin, idx, &binoff);
+
+ while(_findnext(hFile, &c_file) == 0)
+ {
+ strcpy(tmp, argv[1]);
+ strcat(tmp, c_file.name);
+ count++;
+
+ ReadFile(tmp);
+ printf("Saving...\n");
+ SaveFile(bin, idx, &binoff);
+ }
+ _findclose(hFile);
+
+ fclose(bin);
+
+ {
+ char buf[100], f1[9], f2[9], *ptr, *ptr2;
+ FILE* f;
+
+ moved = 0;
+ f = fopen("MOVED.TXT", "rt");
+
+ while (fgets(buf, 100, f) != NULL)
+ {
+ if (ptr = strchr(buf, ' '))
+ {
+ *ptr = 0;
+ memset(f1, 0, 9);
+ strcpy(f1, buf);
+ ptr++;
+ if (ptr2 = strchr(ptr, ' '))
+ {
+ *ptr2 = 0;
+ memset(f2, 0, 9);
+ strcpy(f2, ptr);
+ moved++;
+ strupr(f1);
+ strupr(f2);
+ fwrite(f1, 8, 1, idx);
+ fwrite(f2, 8, 1, idx);
+ }
+ }
+ }
+ fclose(f);
+ }
+
+ fwrite(&moved, sizeof(moved), 1, idx);
+ fwrite(&binoff, sizeof(binoff), 1, idx);
+ fwrite(&count, sizeof(count), 1, idx);
+ fclose(idx);
+ }
+
+ CleanUp();
+ return 0;
+}
+
+/*
+void Inline(drawgroup_t* pdg)
+{
+ unsigned int count[256][3], vert, j, k, v, loc;
+ int i;
+ unsigned int colcount;
+ int curcol;
+ unsigned int* drawinfo;
+ drawgroup_t *ldg, *dg;
+
+ if (pdg->info == NULL)
+ {
+ ldg = &_DrawGroup;
+ dg = _DrawGroup.next;
+
+ while (dg)
+ {
+ if (dg == pdg)
+ {
+ ldg->next = dg->next;
+ free(pdg);
+ return;
+ }
+ ldg = dg;
+ dg = dg->next;
+ }
+ }
+
+
+ vert = 0;
+ memset (count, 0, sizeof(count));
+
+ loc = 1;
+ colcount = _DrawGroup.info[0];
+ while (colcount)
+ {
+ curcol = _DrawGroup.info[loc];
+ loc++;
+ for (j = 0; j < 3; j++)
+ {
+ count[curcol][j] += _DrawGroup.info[loc];
+ loc += _DrawGroup.info[loc]+1;
+ }
+ colcount--;
+ }
+
+ loc = 1;
+ colcount = pdg->info[0];
+ while (colcount)
+ {
+ int curcol = pdg->info[loc];
+ loc++;
+ for (j = 0; j < 3; j++)
+ {
+ count[curcol][j] += pdg->info[loc];
+ loc += pdg->info[loc]+1;
+ }
+ colcount--;
+ }
+
+ k = 0;
+ for (i = 0; i < 256; i++)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ {
+ k++;
+ vert += count[i][0] + count[i][1] + count[i][2];
+ }
+ }
+ vert += (k*4)+1;
+
+ drawinfo = (unsigned int*)malloc(vert*sizeof(unsigned int));
+ drawinfo[0] = k;
+ vert = 1;
+
+ for (i = 16; i < 256; i++)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ {
+ drawinfo[vert] = i;
+ vert++;
+ }
+
+ for (j = 0; j < 3; j++)
+ {
+ if (count[i][0] || count[i][1] || count[i][2])
+ {
+ drawinfo[vert] = count[i][j];
+ vert++;
+ }
+
+ if (count[i][j] != 0)
+ {
+ {
+ unsigned int* info = _DrawGroup.info;
+ loc = 1;
+ colcount = info[0];
+ while (colcount)
+ {
+ int curcol = info[loc];
+ loc++;
+
+ for (v = 0; v < 3; v++)
+ {
+ if ((v == j) && (curcol == i))
+ {
+ memcpy(&drawinfo[vert], &info[loc+1], info[loc]*sizeof(unsigned int));
+ vert += info[loc];
+ }
+ loc += info[loc]+1;
+ }
+ colcount--;
+ }
+ }
+
+ {
+ unsigned int* info = pdg->info;
+ loc = 1;
+ colcount = info[0];
+ while (colcount)
+ {
+ int curcol = info[loc];
+ loc++;
+
+ for (v = 0; v < 3; v++)
+ {
+ if ((v == j) && (curcol == i))
+ {
+ memcpy(&drawinfo[vert], &info[loc+1], info[loc]*sizeof(unsigned int));
+ vert += info[loc];
+ }
+ loc += info[loc]+1;
+ }
+ colcount--;
+ }
+ }
+ }
+ }
+ if (i == 16) i = -1;
+ if (i == 15) i = 23;
+ }
+ free(_DrawGroup.info);
+ _DrawGroup.info = drawinfo;
+ _DrawGroup.infosize = vert;
+
+ ldg = &_DrawGroup;
+ dg = _DrawGroup.next;
+
+ while (dg)
+ {
+ if (dg == pdg)
+ {
+ ldg->next = dg->next;
+ free(pdg->info);
+ free(pdg);
+ break;
+ }
+ ldg = dg;
+ dg = dg->next;
+ }
+}
+
+void decode (char* strFile, float** ppVerts, unsigned int* nCount, char* strDescription)
+{
+ char tmp[100];
+ matrix mat;
+ lineinfo_t info;
+ FILE *f;
+ char *ptr;
+ char fn[260];
+ lineinfo_t *a;
+ unsigned int i, j, unique;
+ float* verts;
+ drawgroup_t* ldg;
+ char buf[1024];
+ int type, color;
+ char filename[32], name[260];
+ float fm[12];
+ FILE *tf;
+ matrix m1,m2;
+
+ LoadIdentity(&mat);
+ info.next = 0;
+ info.type = 0;
+
+ f = fopen (strFile, "rt");
+ if (fgets (tmp, 100, f))
+ {
+ while (tmp[strlen(tmp)-1]==10||tmp[strlen(tmp)-1]==13||tmp[strlen(tmp)-1]==32)
+ tmp[strlen(tmp)-1]=0;
+ tmp[66] = 0;
+ strcpy (strDescription, tmp+2);
+ }
+
+ printf("Decoding %s : %s\n", _strName, _strDescription);
+
+ strcpy (fn, strFile);
+ if (ptr = strrchr(fn, '.')) *ptr = 0;
+ memset (tmp, 0, sizeof(char[100]));
+ ptr = strrchr(fn, '\\');
+ if (ptr == 0)
+ ptr = fn;
+ else
+ ptr++;
+ strcpy (tmp, ptr);
+ strupr (tmp);
+
+ strcpy (fn, strFile);
+ ptr = strrchr(fn, '\\');
+ *ptr = 0;
+ ptr = strrchr(fn, '\\');
+ *(ptr+1) = 0;
+
+ decodefile (f, &mat, 16, &info, fn);
+ fclose (f);
+
+ unique = 0;
+ verts = (float*)malloc(sizeof(float)*1500);
+
+ // Create array of unique vertices
+ for (a = info.next; a; a = a->next)
+ {
+ for (j = 0; j < a->type; j++)
+ {
+ for (i = unique-1; i != -1; i--)
+ if (FloatPointsClose(&verts[i*3], &a->points[j*3]))
+ break;
+
+ if (i == -1)
+ {
+ if ((unique % 500) == 0)
+ verts = (float*)realloc(verts, sizeof(float)*3*(unique+500));
+ memcpy(&verts[unique*3], &a->points[j*3], sizeof(float)*3);
+ unique++;
+ }
+ }
+ }
+
+ a = info.next;
+ while (a)
+ {
+ lineinfo_t* b = a->next;
+ free(a);
+ a = b;
+ }
+ info.next = 0;
+
+ *ppVerts = verts;
+ *nCount = unique;
+
+ printf ("%d vertexes\n", unique);
+
+ // Main group
+ f = fopen (strFile, "rt");
+ LoadIdentity(&mat);
+ decodefile (f, &mat, 16, &info, fn);
+ fclose(f);
+ AddDrawInfo (&_DrawGroup, &info, verts, unique);
+ Inline(&_DrawGroup);
+ ldg = &_DrawGroup;
+
+ // Included files
+ f = fopen (strFile, "rt");
+ while (fgets(buf, 1024, f))
+ {
+ while (buf[strlen(buf)-1] == 10 || buf[strlen(buf)-1] == 13 || buf[strlen(buf)-1] == 32)
+ buf[strlen(buf)-1] = 0;
+
+ type = -1;
+ sscanf(buf, "%d", &type);
+
+ if (type == 1)
+ {
+ sscanf (buf, "%d %d %f %f %f %f %f %f %f %f %f %f %f %f %s",
+ &type, &color, &fm[0], &fm[1], &fm[2], &fm[3], &fm[4], &fm[5], &fm[6], &fm[7], &fm[8], &fm[9], &fm[10], &fm[11], filename);
+
+ strupr(filename);
+ LoadIdentity(&mat);
+ info.next = 0;
+
+ ldg->next = (drawgroup_t*)malloc(sizeof(drawgroup_t));
+ ldg = ldg->next;
+ memset(ldg, 0, sizeof(drawgroup_t));
+
+ strcpy (name, fn);
+ strcat (name, "P\\");
+ strcat (name, filename);
+
+ tf = fopen (name, "rt");
+
+ if (!tf)
+ {
+ strcpy (name, fn);
+ strcat (name, "PARTS\\");
+ strcat (name, filename);
+ tf = fopen (name, "rt");
+ }
+
+ if (!tf)
+ {
+ strcpy (name, fn);
+ strcat (name, "PARTS\\S\\");
+ strcat (name, filename);
+ tf = fopen (name, "rt");
+ }
+
+ if (ptr = strrchr(filename, '.')) *ptr = 0;
+ strcpy(ldg->name, filename);
+
+ LoadIdentity(&m1);
+ LoadIdentity(&m2);
+ ConvertFromLDraw (&m1, fm);
+ Multiply (&m2, &mat, &m1);
+#if 0
+ if (strcmp(ldg->name, "STUD") == 0)
+ {
+ ldg->pos[0] = m2.m[12];
+ ldg->pos[1] = m2.m[13];
+ ldg->pos[2] = m2.m[14];
+ ldg->up[2] = 1;
+ m2.TransformPoints(ldg->up, 1);
+ ldg->up[0] -= m2.m[12];
+ ldg->up[1] -= m2.m[13];
+ ldg->up[2] -= m2.m[14];
+ ldg->type = 1;
+ }
+
+ if (strcmp(ldg->name, "STUD4") == 0)
+ {
+ ldg->pos[0] = m2.m[12];
+ ldg->pos[1] = m2.m[13];
+ ldg->pos[2] = m2.m[14];
+ ldg->up[2] = 1;
+ m2.TransformPoints(ldg->up, 1);
+ ldg->up[0] -= m2.m[12];
+ ldg->up[1] -= m2.m[13];
+ ldg->up[2] -= m2.m[14];
+ ldg->type = 0;
+ }
+#endif
+ decodefile (tf, &m2, (unsigned char)color, &info, fn);
+ AddDrawInfo (ldg, &info, verts, unique);
+ fclose(tf);
+ }
+ }
+ fclose(f);
+}
+
+void OpenFile(char* strFile)
+{
+ char tmp[260], *ptr;
+ CleanUp();
+
+// if (stricmp() strFile.Right(4).CompareNoCase(_T(".DAT")) == 0)
+ {
+ memset(_strName, 0, sizeof(_strName));
+ memset(_strDescription, 0, sizeof(_strDescription));
+
+ strcpy(tmp, strFile);
+ if (ptr = strrchr(tmp, '.')) *ptr = 0;
+ ptr = strrchr(tmp, '\\');
+ if (ptr == NULL)
+ ptr = tmp;
+ else
+ ptr++;
+ strcpy (_strName, ptr);
+ strupr (_strName);
+
+ decode (strFile, &_fVerts, &_nVertsCount, _strDescription);
+ }
+}
+*/
+
diff --git a/tools/convert/convert.h b/tools/convert/convert.h
new file mode 100644
index 0000000..370df21
--- /dev/null
+++ b/tools/convert/convert.h
@@ -0,0 +1,221 @@
+// Hide math stuff here.
+//
+
+static float Identity[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
+
+// Perform a 4x4 matrix multiplication (product = a x b).
+// WARNING: (product != b) assumed
+static __inline void matmul(float *product, const float *a, const float *b)
+{
+ int i;
+
+// #define M(row,col) m[col*4+row]
+#define A(row,col) a[(col<<2)+row]
+#define B(row,col) b[(col<<2)+row]
+#define P(row,col) product[(col<<2)+row]
+
+ for (i = 0; i < 4; i++)
+ {
+ float ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
+ P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
+ P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
+ P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
+ P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
+ }
+
+#undef A
+#undef B
+#undef P
+}
+
+typedef struct
+{
+ float m[16];
+} matrix;
+
+static __inline void ConvertFromLDraw(matrix* m, float f[12])
+{
+ float trans[16] = { 1,0,0,0, 0,0,-1,0, 0,1,0,0, 0,0,0,1 };
+ float t[16] = { 1,0,0,0, 0,0,1,0, 0,-1,0,0, 0,0,0,1 };
+ m->m[0] = f[3]; m->m[1] = f[6]; m->m[2] = f[9];
+ m->m[4] = f[4]; m->m[5] = f[7]; m->m[6] = f[10];
+ m->m[8] = f[5]; m->m[9] = f[8]; m->m[10]= f[11];
+ m->m[12]= f[0]/25; m->m[13]= f[1]/25; m->m[14]= f[2]/25;
+ matmul (m->m, m->m, t);
+ matmul (trans, trans, m->m);
+ memcpy (&m[0], &trans[0], sizeof(m->m));
+}
+
+static __inline void LoadIdentity(matrix* m)
+{
+ memcpy (&m->m[0], &Identity, sizeof(float[16]));
+}
+
+static __inline void Multiply(matrix* m, matrix* m1, matrix* m2)
+{
+ matmul (m->m, m1->m, m2->m);
+}
+
+static __inline void TransformPoint(matrix* m, float out[], const float in[3])
+{
+ out[0] = m->m[0]*in[0] + m->m[4]*in[1] + m->m[8]*in[2] + m->m[12];
+ out[1] = m->m[1]*in[0] + m->m[5]*in[1] + m->m[9]*in[2] + m->m[13];
+ out[2] = m->m[2]*in[0] + m->m[6]*in[1] + m->m[10]*in[2] + m->m[14];
+}
+
+static __inline void TranslatePoint(matrix* m, float* in, float* t)
+{
+ in[0] = m->m[0]*t[0] + m->m[4]*t[1] + m->m[8]*t[2] + m->m[12];
+ in[1] = m->m[1]*t[0] + m->m[5]*t[1] + m->m[9]*t[2] + m->m[13];
+ in[2] = m->m[2]*t[0] + m->m[6]*t[1] + m->m[10]*t[2] + m->m[14];
+}
+
+static __inline void TransformPoints (matrix* m, float p[], int n)
+{
+ int i;
+ float tmp[3];
+
+ for (i = 0; i < n*3; i += 3)
+ {
+ tmp[0] = p[i];
+ tmp[1] = p[i+1];
+ tmp[2] = p[i+2];
+ TransformPoint (m, &p[i], tmp);
+ }
+}
+
+static __inline void ConvertPoints (float pts[], int count)
+{
+ float tmp;
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ pts[3*i] /= 25;
+ tmp = pts[3*i+1];
+ pts[3*i+1] = pts[3*i+2]/25;
+ pts[3*i+2] = -tmp/25;
+ }
+}
+
+static __inline void Resequence(float v[4][3], int a, int b, int c, int d)
+{
+ float o[4][3];
+ memcpy(o, v, sizeof(o));
+ memcpy(v[0], o[a], sizeof(o[0]));
+ memcpy(v[1], o[b], sizeof(o[0]));
+ memcpy(v[2], o[c], sizeof(o[0]));
+ memcpy(v[3], o[d], sizeof(o[0]));
+}
+
+static __inline void Sub3(float v[], float q1[], float q2[])
+{
+ v[0] = q1[0]-q2[0];
+ v[1] = q1[1]-q2[1];
+ v[2] = q1[2]-q2[2];
+}
+
+static __inline float Dot3(float q1[], float q2[])
+{
+ return q1[0]*q2[0]+q1[1]*q2[1]+q1[2]*q2[2];
+}
+
+static __inline void Cross3(float v[], float q1[], float q2[])
+{
+ v[0] = (q1[1]*q2[2]) - (q1[2]*q2[1]);
+ v[1] = (q1[2]*q2[0]) - (q1[0]*q2[2]);
+ v[2] = (q1[0]*q2[1]) - (q1[1]*q2[0]);
+}
+
+static __inline void TestQuads(float quad[4][3])
+{
+ float v01[3], v02[3], v03[3];
+ float v12[3], v13[3], v23[3];
+ float cp1[3], cp2[3];
+ float dotA, dotB, dotC;
+ int A, B, C;
+
+ // Calculate A
+ Sub3(v01, quad[1], quad[0]);
+ Sub3(v02, quad[2], quad[0]);
+ Sub3(v03, quad[3], quad[0]);
+ Cross3(cp1, v01, v02);
+ Cross3(cp2, v02, v03);
+ dotA = Dot3(cp1, cp2);
+ A = (dotA > 0.0f);
+
+ if (A)
+ {
+ // 3 is in I, typical case, OK: 0123 D02 (convex/concave)
+ // CONVEXINFO: quad is convex if (!B && !C): OK: 0123 D02/13 (convex)
+ }
+ else
+ {
+ // Calculate B and C (may be postponed/discarded)
+ // NOTE: postponed !
+ Sub3(v12, quad[2], quad[1]);
+ Sub3(v13, quad[3], quad[1]);
+ Sub3(v23, quad[3], quad[2]);
+ Cross3(cp1, v12, v01);
+ Cross3(cp2, v01, v13);
+ dotB = Dot3(cp1, cp2);
+ B = (dotB > 0.0f);
+ Cross3(cp1, v02, v12);
+ Cross3(cp2, v12, v23);
+ dotC = -Dot3(cp1, cp2);
+ C = (dotC > 0.0f);
+
+ // 3 is in II, III, IV or V. Calculation of B and C could be postponed
+ // to here if CONVEXINFO (above) is not needed
+ if (B)
+ {
+ // 3 is in II or III
+ if (C)
+ {
+ // 3 is in II, OK: 0123 D13 (concave)
+ Resequence(quad, 1, 2, 3, 0); // just to shift diagonal
+ }
+ else
+ {
+ // 3 is in III, bow-tie error: using 0312 D01/D23 (convex)
+ Resequence(quad, 0, 3, 1, 2);
+ }
+ }
+ else
+ {
+ // 3 is in IV or V
+ if (C)
+ {
+ // 3 is in IV, bow-tie error: using 0132 D12/D03 (convex)
+ Resequence(quad, 0, 1, 3, 2);
+ }
+ else
+ {
+ // 3 is in V, OK: 0123 D13 (concave)
+ Resequence(quad, 1, 2, 3, 0); // just to shift diagonal
+ }
+ }
+ }
+ // The four vertices quad[0], quad[1], quad[2] and quad[3] now have
+ // the correct sequence, the polygon can be divided by the diagonal 02
+ // into two triangles, 012 and 230.
+}
+
+static __inline void FixQuads(float quad[])
+{
+ float t[4][3];
+ memcpy(t, quad, sizeof(t));
+ TestQuads(t);
+ memcpy(quad, t, sizeof(t));
+}
+
+static __inline int FloatPointsClose (float pt1[], float pt2[])
+{
+ if (fabs(pt1[0] - pt2[0]) > 0.01)
+ return 0;
+ if (fabs(pt1[1] - pt2[1]) > 0.01)
+ return 0;
+ if (fabs(pt1[2] - pt2[2]) > 0.01)
+ return 0;
+ return 1;
+}
diff --git a/tools/convert/moved.txt b/tools/convert/moved.txt
new file mode 100644
index 0000000..4107e4c
--- /dev/null
+++ b/tools/convert/moved.txt
@@ -0,0 +1,215 @@
+4 3193
+5 3192
+6 3464
+9 3460
+11 3579
+12 7930
+13 7026
+16 3596
+18 3626A
+19 3624
+22 3581
+25 3582
+26 3497
+28 3062B
+34 7049
+40 3046
+47 3659
+48 3049
+56 3660
+57 3045
+62 3145
+64 3359
+65 3358
+89 9244
+93 3479
+94 3865
+95 2748
+96 3831
+97 3830
+98 3685
+99 3684
+100 3665
+101 3623
+102 3644
+103 73037
+114 3848
+116 3847
+117 3846
+117P47 3846P47
+118 3849
+121 3787
+122 122C01
+123 3641
+132 3483
+134 3794
+138 3855
+140 3821
+141 3822
+142 3741
+143 3742
+144 3854
+145 3856
+146 2529
+148 3957
+149 3962
+150 3899
+157 4070
+158 3189
+159 3188
+161 4085
+163 3315
+174 4081
+175 4178
+176 4023
+177 73092
+178 4175
+179 4073
+180 4161
+195 4170
+196 4171
+197 73090
+198 4176
+199 3675
+205 32073
+206 73071
+211 6100
+212 4229
+216 3612
+217 4228
+231 4349
+234 4286
+236 73312
+238 3048
+239 4528
+240 4287
+241 4529
+246 73435
+247 73436
+247B 73435
+248 3676
+252 4599
+256 3058
+257 4476
+258 4169
+259 4168
+262 3811
+262P01 3811P01
+274 4590
+275 4460
+278 4490
+249 4495
+291 4868
+292 4869
+293 3867
+294 4447
+295 4448
+296 4740
+297 4593
+299 4589
+302 4872
+305 2335
+306 2343
+307 4735
+321 2412
+324 2458
+338 2433
+339 4474
+340 2583
+352 4095
+368 2569
+369 3187
+370 3186
+371 2920
+372 2337
+373 6019
+376 4733
+380 6016
+381 6048
+386 6020
+387 6060
+388 6070
+391 6558
+395 3587
+396 4595
+401 2516
+404 6541
+407 71076
+408 71075
+415 6217
+418 6037
+426 6043
+427 6046
+428 75535
+432 6126
+461 3688
+497 7039
+513 3144
+583 30031
+588 71137
+602 32000
+605 6152
+708 3062A
+720 3218
+808 2348A
+810 6238
+829 3433
+860 6120
+960 2620
+961 4284
+965 4089
+2348 2348B
+2358P01 80547
+2418 2418B
+2455 3755
+2561 2566
+2562 2536
+2748 3857
+2837A 2838C01
+2872 2921
+3062 3062B
+3137A 3137
+3137B 20
+3149A 313
+3149B 314
+3149C 3149
+3324A 3324
+3465 3480
+3463 3481
+3626 3626B
+3626-4T 3626B-4T
+3626P01 3626BP01
+3626P02 3626BP02
+3709 3709B
+3944 3961
+3945 3839
+3946 3963
+3949 3838
+3950 3959
+3951 3939
+3951P68 3939P68
+4203 4201
+4601 4624
+6237 601
+73590 73590B
+9326 973
+9326-4T 973S01
+9326P01 973P01
+9326P02 973P02
+9326P11 973P11
+9326P14 973P14
+9326P15 973P15
+9326P16 973P16
+9326P17 973P17
+9326P18 973P18
+9326P47 973P47
+9326P51 973P51
+9326P52 973P52
+9326P60 973P60
+9326P61 973P61
+9326P63 973P63
+9326P68 973P68
+9326T01 973P01
+9326T02 973P02
+4265 4265B
+571 6629
diff --git a/tools/convert/texture.cpp b/tools/convert/texture.cpp
new file mode 100644
index 0000000..bc91ddd
--- /dev/null
+++ b/tools/convert/texture.cpp
@@ -0,0 +1,120 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <io.h>
+#include "texture.h"
+
+void ConvertFile(char* szFilename, FILE* idx, FILE* bin, unsigned long* binoff)
+{
+ long i, j;
+ unsigned short width, height;
+ unsigned char* buf = ReadBMP(szFilename, &width, &height);
+ unsigned char bt;
+ unsigned short sh;
+ char* p;
+ p = strrchr(szFilename, '.');
+ *p = 0;
+ p = strrchr(szFilename, '\\');
+ strupr(p);
+ p++;
+
+ char name[9];
+ memset(name, 0, 9);
+ strcpy(name, p);
+
+ fwrite(name, 8, 1, idx);
+ sh = (unsigned short)width;
+ fwrite(&sh, sizeof(sh), 1, idx);
+ sh = (unsigned short)height;
+ fwrite(&sh, sizeof(sh), 1, idx);
+
+ if (strcmp("SYSFONT", name) == 0)
+ {
+ bt = 0; // luminance
+ fwrite(&bt, 1, 1, idx);
+
+ // Store top->bottom only this one
+ for (i = 0; i < height; i++)
+ {
+ unsigned char* b = buf+(height-i-1)*width*3;
+
+ for (j = 0; j < width; j++)
+ {
+ if (b[j*3] > 0 || b[j*3+1] > 0 || b[j*3+2] > 0)
+ bt = 0;
+ else
+ bt = 255;
+ fwrite(&bt, 1, 1, bin);
+ }
+ }
+
+ fwrite(binoff, sizeof(*binoff), 1, idx);
+ *binoff += width*height;
+ }
+
+ if (strcmp("SPACE", name) == 0)
+ {
+ bt = 2; // RGBA
+ fwrite(&bt, 1, 1, idx);
+ for (i = 0; i < width*height; i++)
+ {
+ if (buf[i*3] == 255 && buf[i*3+1] == 0 && buf[i*3+2] == 255)
+ {
+ buf[i*3] = buf[i*3+1] = buf[i*3+2] = 255;
+ bt = 0;
+ }
+ else
+ bt = 255;
+
+ fwrite(&buf[i*3], 3, 1, bin);
+ fwrite(&bt, 1, 1, bin);
+ }
+
+ fwrite(binoff, sizeof(*binoff), 1, idx);
+ *binoff += width*height*4;
+ }
+
+ free (buf);
+}
+
+static char* filepath = "f:\\ldraw\\textures\\";
+static char* filenames[] = { "SYSFONT", "SPACE" };
+static int filecount = 2;
+
+int main(int argc, char *argv[])
+{
+ char tmp[260];
+ FILE *bin, *idx;
+ unsigned long binoff;
+ unsigned short count = 0;
+
+ char strbin[32] = "LeoCAD texture data file\0\0\0\0\0\0\0";
+ char stridx[32] = "LeoCAD texture index file\0\0\0\0\0\0";
+ unsigned char bt;
+
+ bin = fopen("TEXTURES.BIN", "wb");
+ idx = fopen("TEXTURES.IDX", "wb");
+ fwrite(strbin, 32, 1, bin);
+ binoff = 32;
+ fwrite(stridx, 32, 1, idx);
+ bt = 1; // version
+ fwrite(&bt, 1, 1, idx);
+ bt = 3; // last update
+ fwrite(&bt, 1, 1, idx);
+
+ for (int i = 0; i < filecount; i++)
+ {
+ strcpy(tmp, filepath);
+ strcat(tmp, filenames[i]);
+ strcat(tmp, ".bmp");
+ count++;
+ ConvertFile(tmp, idx, bin, &binoff);
+ }
+
+ fclose(bin);
+ fwrite(&binoff, sizeof(binoff), 1, idx);
+ fwrite(&count, sizeof(count), 1, idx);
+ fclose(idx);
+
+ return 0;
+} \ No newline at end of file
diff --git a/tools/convert/texture.h b/tools/convert/texture.h
new file mode 100644
index 0000000..a02af44
--- /dev/null
+++ b/tools/convert/texture.h
@@ -0,0 +1,678 @@
+
+static unsigned char* ReadBMP (char* filename, unsigned short *width, unsigned short *height)
+{
+ int bmWidth;
+ int bmHeight;
+ unsigned char bmPlanes;
+ unsigned char bmBitsPixel;
+ typedef struct {
+ unsigned char rgbBlue;
+ unsigned char rgbGreen;
+ unsigned char rgbRed;
+ unsigned char rgbReserved;
+ } RGBQUAD;
+ unsigned char m1,m2;
+ unsigned long sizeimage;
+ short res1,res2;
+ long filesize, pixoff;
+ long bmisize, compression;
+ long xscale, yscale;
+ long colors, impcol;
+ unsigned long m_bytesRead = 0;
+ unsigned char* outbuf;
+ FILE *fp;
+
+ fp = fopen(filename,"rb");
+ if (fp == NULL)
+ return NULL;
+ else
+ {
+ long rc;
+ rc = fread(&m1, 1, 1, fp);
+ m_bytesRead++;
+ if (rc == -1)
+ {
+ fclose(fp);
+ return NULL;
+ }
+
+ rc = fread(&m2, 1, 1, fp);
+ m_bytesRead++;
+ if ((m1!='B') || (m2!='M'))
+ {
+ fclose(fp);
+ return NULL;
+ }
+
+ rc = fread((long*)&(filesize),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((int*)&(res1),2,1,fp); m_bytesRead+=2;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((int*)&(res2),2,1,fp); m_bytesRead+=2;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(pixoff),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(bmisize),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long *)&(bmWidth),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(bmHeight),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((int*)&(bmPlanes),2,1,fp); m_bytesRead+=2;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((int*)&(bmBitsPixel),2,1,fp); m_bytesRead+=2;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(compression),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(sizeimage),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) {fclose(fp); return NULL; }
+
+ rc = fread((long*)&(xscale),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(yscale),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(colors),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ rc = fread((long*)&(impcol),4,1,fp); m_bytesRead+=4;
+ if (rc != 1) { fclose(fp); return NULL; }
+
+ // I don't do RLE files
+ if (compression != 0) // BI_RGB
+ {
+ fclose(fp);
+ return NULL;
+ }
+
+ if (colors == 0)
+ colors = 1 << bmBitsPixel;
+
+ RGBQUAD *colormap = NULL;
+
+ switch (bmBitsPixel)
+ {
+ case 24:
+ break;
+ // read pallete
+ case 1:
+ case 4:
+ case 8:
+ colormap = new RGBQUAD[colors];
+ if (colormap == NULL)
+ {
+ fclose(fp);
+ return NULL;
+ }
+
+ int i;
+ for (i = 0; i < colors; i++)
+ {
+ unsigned char r ,g, b, dummy;
+
+ rc = fread(&b, 1, 1, fp);
+ m_bytesRead++;
+ if (rc!=1)
+ {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ rc = fread(&g, 1, 1, fp);
+ m_bytesRead++;
+ if (rc!=1)
+ {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ rc = fread(&r, 1, 1, fp);
+ m_bytesRead++;
+ if (rc != 1)
+ {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+
+ rc = fread(&dummy, 1, 1, fp);
+ m_bytesRead++;
+ if (rc != 1)
+ {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ colormap[i].rgbRed=r;
+ colormap[i].rgbGreen=g;
+ colormap[i].rgbBlue=b;
+ }
+ break;
+ }
+
+ if ((long)m_bytesRead > pixoff)
+ {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ while ((long)m_bytesRead < pixoff)
+ {
+ char dummy;
+ fread(&dummy,1,1,fp);
+ m_bytesRead++;
+ }
+
+ int w = bmWidth;
+ int h = bmHeight;
+
+ // set the output params
+ outbuf = (unsigned char*)malloc(w*h*3);
+ long row_size = w * 3;
+ long bufsize = (long)w * 3 * (long)h;
+
+ if (outbuf != NULL)
+ {
+ *width = w;
+ *height = h;
+ long row = 0;
+ long rowOffset = 0;
+
+ // read rows in reverse order
+ for (row = 0; row < bmHeight; row++)
+ {
+ // which row are we working on?
+ rowOffset = (long unsigned)row*row_size;
+
+ if (bmBitsPixel == 24)
+ {
+ for (int col=0;col<w;col++)
+ {
+ long offset = col * 3;
+ char pixel[3];
+
+ if (fread((void*)(pixel),1,3,fp)==3)
+ {
+ // we swap red and blue here
+ *(outbuf + rowOffset + offset + 0)=pixel[2]; // r
+ *(outbuf + rowOffset + offset + 1)=pixel[1]; // g
+ *(outbuf + rowOffset + offset + 2)=pixel[0]; // b
+ }
+ }
+ m_bytesRead += row_size;
+
+ // read DWORD padding
+ while ((m_bytesRead-pixoff)&3)
+ {
+ char dummy;
+ if (fread(&dummy,1,1,fp) != 1)
+ {
+ free(outbuf);
+ fclose(fp);
+ return NULL;
+ }
+ m_bytesRead++;
+ }
+ }
+ else
+ {
+ // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
+ int bit_count = 0;
+ unsigned long mask = (1 << bmBitsPixel) - 1;
+
+ unsigned char inbyte = 0;
+
+ for (int col=0;col<w;col++)
+ {
+ int pix = 0;
+
+ // if we need another byte
+ if (bit_count <= 0)
+ {
+ bit_count = 8;
+ if (fread(&inbyte,1,1,fp) != 1)
+ {
+ free(outbuf);
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+ m_bytesRead++;
+ }
+
+ // keep track of where we are in the bytes
+ bit_count -= bmBitsPixel;
+ pix = ( inbyte >> bit_count) & mask;
+
+ // lookup the color from the colormap - stuff it in our buffer
+ // swap red and blue
+ *(outbuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
+ *(outbuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
+ *(outbuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
+ }
+
+ // read DWORD padding
+ while ((m_bytesRead-pixoff)&3)
+ {
+ char dummy;
+ if (fread(&dummy,1,1,fp)!=1)
+ {
+ free(outbuf);
+ if (colormap)
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+ m_bytesRead++;
+ }
+ }
+ }
+ }
+
+ if (colormap)
+ delete [] colormap;
+
+ fclose(fp);
+ }
+
+// VerticalFlip(image);
+ return outbuf;
+}
+
+
+
+
+
+/*
+#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
+
+static BOOL VertFlipBuf(BYTE* inbuf, UINT widthBytes, UINT height)
+{
+ BYTE *tb1, *tb2;
+ ULONG off1 = 0, off2 = 0;
+
+ if (inbuf == NULL)
+ return FALSE;
+
+ tb1 = (BYTE*)malloc(widthBytes);
+ if (tb1 == NULL)
+ return FALSE;
+
+ tb2 = (BYTE*)malloc(widthBytes);
+ if (tb2 == NULL)
+ {
+ free(tb1);
+ return FALSE;
+ }
+
+ for (UINT row_cnt = 0; row_cnt < (height+1)/2; row_cnt++)
+ {
+ off1 = row_cnt*widthBytes;
+ off2 = ((height-1)-row_cnt)*widthBytes;
+
+ memcpy(tb1, inbuf+off1, widthBytes);
+ memcpy(tb2, inbuf+off2, widthBytes);
+ memcpy(inbuf+off1, tb2, widthBytes);
+ memcpy(inbuf+off2, tb1, widthBytes);
+ }
+
+ free (tb1);
+ free (tb2);
+
+ return TRUE;
+}
+
+static BYTE* MakeDwordAlignedBuf(BYTE *dataBuf, UINT widthPix, UINT height, UINT *uiOutWidthBytes)
+{
+ if (dataBuf == NULL)
+ return NULL;
+
+ UINT uiWidthBytes = WIDTHBYTES(widthPix * 24);
+ DWORD dwNewsize = (DWORD)((DWORD)uiWidthBytes * (DWORD)height);
+ BYTE *pNew;
+
+ pNew = (BYTE*)new BYTE[dwNewsize];
+ if (pNew == NULL)
+ return NULL;
+
+ // copy row-by-row
+ UINT uiInWidthBytes = widthPix * 3;
+ UINT uiCount;
+ for (uiCount=0;uiCount < height;uiCount++)
+ {
+ BYTE* bpInAdd;
+ BYTE* bpOutAdd;
+ ULONG lInOff;
+ ULONG lOutOff;
+
+ lInOff = uiInWidthBytes * uiCount;
+ lOutOff = uiWidthBytes * uiCount;
+
+ bpInAdd = dataBuf + lInOff;
+ bpOutAdd = pNew + lOutOff;
+
+ memcpy(bpOutAdd,bpInAdd,uiInWidthBytes);
+ }
+
+ *uiOutWidthBytes = uiWidthBytes;
+ return pNew;
+}
+
+static BOOL BGRFromRGB(BYTE *buf, UINT widthPix, UINT height)
+{
+ if (buf == NULL)
+ return FALSE;
+
+ UINT col, row;
+ for (row=0;row<height;row++) {
+ for (col=0;col<widthPix;col++)
+ {
+ LPBYTE pRed, pGrn, pBlu;
+ pRed = buf + row * widthPix * 3 + col * 3;
+ pGrn = buf + row * widthPix * 3 + col * 3 + 1;
+ pBlu = buf + row * widthPix * 3 + col * 3 + 2;
+
+ // swap red and blue
+ BYTE tmp;
+ tmp = *pRed;
+ *pRed = *pBlu;
+ *pBlu = tmp;
+ }
+ }
+ return TRUE;
+}
+
+static unsigned char* ReadBMP (char* fileName, UINT *width, UINT *height)
+{
+ BITMAP inBM;
+ unsigned char m1,m2;
+ unsigned long sizeimage;
+ short res1,res2;
+ long filesize, pixoff;
+ long bmisize, compression;
+ long xscale, yscale;
+ long colors, impcol;
+ FILE *fp;
+
+ unsigned char *outBuf=NULL;
+ unsigned long m_bytesRead = 0;
+ *width=0;
+ *height=0;
+
+ fp=fopen(fileName,"rb");
+ if (fp==NULL) {
+ return NULL;
+ } else {
+ long rc;
+ rc=fread((unsigned char*)&(m1),1,1,fp); m_bytesRead+=1;
+ if (rc==-1) {fclose(fp); return NULL;}
+
+ rc=fread((unsigned char*)&(m2),1,1,fp); m_bytesRead+=1;
+ if ((m1!='B') || (m2!='M')) {
+ fclose(fp);
+ return NULL;
+ }
+
+ rc=fread((long *)&(filesize),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((int *)&(res1),2,1,fp); m_bytesRead+=2;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((int *)&(res2),2,1,fp); m_bytesRead+=2;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(pixoff),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(bmisize),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(inBM.bmWidth),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(inBM.bmHeight),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((int *)&(inBM.bmPlanes),2,1,fp); m_bytesRead+=2;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((int *)&(inBM.bmBitsPixel),2,1,fp); m_bytesRead+=2;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(compression),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(sizeimage),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(xscale),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(yscale),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(colors),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ rc=fread((long *)&(impcol),4,1,fp); m_bytesRead+=4;
+ if (rc!=1) {fclose(fp); return NULL;}
+
+ ////////////////////////////////////////////////////////////////////////////
+ // i don't do RLE files
+
+ if (compression!=BI_RGB) {
+ fclose(fp);
+ return NULL;
+ }
+
+ if (colors == 0) {
+ colors = 1 << inBM.bmBitsPixel;
+ }
+
+
+ RGBQUAD *colormap = NULL;
+
+ switch (inBM.bmBitsPixel) {
+ case 24:
+ break;
+ // read pallete
+ case 1:
+ case 4:
+ case 8:
+ colormap = new RGBQUAD[colors];
+ if (colormap==NULL) {
+ fclose(fp);
+ return NULL;
+ }
+
+ int i;
+ for (i=0;i<colors;i++) {
+ unsigned char r,g,b, dummy;
+
+ rc=fread((unsigned char*)&(b),1,1,fp);
+ m_bytesRead++;
+ if (rc!=1) {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ rc=fread((unsigned char*)&(g),1,1,fp);
+ m_bytesRead++;
+ if (rc!=1) {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ rc=fread((unsigned char*)&(r),1,1,fp);
+ m_bytesRead++;
+ if (rc!=1) {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+
+ rc=fread((unsigned char*)&(dummy),1,1,fp);
+ m_bytesRead++;
+ if (rc!=1) {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ colormap[i].rgbRed=r;
+ colormap[i].rgbGreen=g;
+ colormap[i].rgbBlue=b;
+ }
+ break;
+ }
+
+
+ if ((long)m_bytesRead>pixoff) {
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+
+ while ((long)m_bytesRead<pixoff) {
+ char dummy;
+ fread(&dummy,1,1,fp);
+ m_bytesRead++;
+ }
+
+ int w=inBM.bmWidth;
+ int h=inBM.bmHeight;
+
+ // set the output params
+ *width=w;
+ *height=h;
+
+ long row_size = w * 3;
+ long bufsize = (long)w * 3 * (long)h;
+
+ outBuf=(unsigned char*) new unsigned char[bufsize];
+ if (outBuf!=NULL)
+ {
+ long row=0;
+ long rowOffset=0;
+
+ // read rows in reverse order
+ for (row=inBM.bmHeight-1;row>=0;row--) {
+
+ // which row are we working on?
+ rowOffset=(long unsigned)row*row_size;
+
+ if (inBM.bmBitsPixel==24) {
+
+ for (int col=0;col<w;col++) {
+ long offset = col * 3;
+ char pixel[3];
+
+ if (fread((void *)(pixel),1,3,fp)==3) {
+ // we swap red and blue here
+ *(outBuf + rowOffset + offset + 0)=pixel[2]; // r
+ *(outBuf + rowOffset + offset + 1)=pixel[1]; // g
+ *(outBuf + rowOffset + offset + 2)=pixel[0]; // b
+ }
+
+ }
+
+ m_bytesRead+=row_size;
+
+ // read DWORD padding
+ while ((m_bytesRead-pixoff)&3) {
+ char dummy;
+ if (fread(&dummy,1,1,fp)!=1) {
+ delete [] outBuf;
+ fclose(fp);
+ return NULL;
+ }
+
+ m_bytesRead++;
+ }
+
+
+ } else { // 1, 4, or 8 bit image
+
+ ////////////////////////////////////////////////////////////////
+ // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
+
+ int bit_count = 0;
+ UINT mask = (1 << inBM.bmBitsPixel) - 1;
+
+ unsigned char inbyte=0;
+
+ for (int col=0;col<w;col++) {
+
+ int pix=0;
+
+ // if we need another byte
+ if (bit_count <= 0) {
+ bit_count = 8;
+ if (fread(&inbyte,1,1,fp)!=1) {
+ delete [] outBuf;
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+ m_bytesRead++;
+ }
+
+ // keep track of where we are in the bytes
+ bit_count -= inBM.bmBitsPixel;
+ pix = ( inbyte >> bit_count) & mask;
+
+ // lookup the color from the colormap - stuff it in our buffer
+ // swap red and blue
+ *(outBuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
+ *(outBuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
+ *(outBuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
+ }
+
+ // read DWORD padding
+ while ((m_bytesRead-pixoff)&3) {
+ char dummy;
+ if (fread(&dummy,1,1,fp)!=1) {
+ delete [] outBuf;
+ if (colormap)
+ delete [] colormap;
+ fclose(fp);
+ return NULL;
+ }
+ m_bytesRead++;
+ }
+ }
+ }
+
+ }
+
+ if (colormap) {
+ delete [] colormap;
+ }
+
+ fclose(fp);
+
+ }
+
+ return outBuf;
+}
+*/ \ No newline at end of file