Integrated Import Folder command from branch.

This commit is contained in:
nobody 2012-01-24 02:38:04 +00:00
parent 9469e2bdef
commit 45797c9d45
13 changed files with 543 additions and 215 deletions

View file

@ -736,8 +736,61 @@ void PiecesLibrary::RemoveCategory(int Index)
// =============================================================================
// Pieces handling stuff
bool PiecesLibrary::DeleteAllPieces()
{
FileDisk newbin, newidx, oldbin, oldidx;
char file1[LC_MAXPATH], file2[LC_MAXPATH], tmp[256];
strcpy(file1, m_LibraryPath);
strcat(file1, "pieces-b.old");
remove(file1);
strcpy(file2, m_LibraryPath);
strcat(file2, "pieces.bin");
rename(file2, file1);
if ((!oldbin.Open(file1, "rb")) ||
(!newbin.Open(file2, "wb")))
return false;
strcpy(file1, m_LibraryPath);
strcat(file1, "pieces-i.old");
remove(file1);
strcpy(file2, m_LibraryPath);
strcat(file2, "pieces.idx");
rename(file2, file1);
if ((!oldidx.Open(file1, "rb")) ||
(!newidx.Open(file2, "wb")))
return false;
oldidx.Seek(0, SEEK_SET);
oldidx.Read(tmp, 34);
newidx.Write(tmp, 34);
oldbin.Read(tmp, 32);
newbin.Write(tmp, 32);
// list of moved pieces
lcuint16 moved = 0;
newidx.WriteShort(&moved, 1);
// info at the end
lcuint32 binoff = newbin.GetPosition();
newidx.WriteLong(&binoff, 1);
lcuint16 count = 0;
newidx.WriteShort(&count, 1);
oldidx.Close();
oldbin.Close();
newidx.Close();
newbin.Close();
m_Modified = true;
return true;
}
// Remove pieces from the library
bool PiecesLibrary::DeletePieces (PtrArray<PieceInfo>& Pieces)
bool PiecesLibrary::DeletePieces(PtrArray<const char>& Pieces)
{
FileDisk newbin, newidx, oldbin, oldidx;
char file1[LC_MAXPATH], file2[LC_MAXPATH], tmp[200];
@ -793,7 +846,7 @@ bool PiecesLibrary::DeletePieces (PtrArray<PieceInfo>& Pieces)
oldidx.Read(&name, LC_PIECE_NAME_LEN);
for (i = 0; i < Pieces.GetSize(); i++)
if (strcmp(name, Pieces[i]->m_strName) == 0)
if (strcmp(name, Pieces[i]) == 0)
break;
if (i != Pieces.GetSize())
@ -1400,7 +1453,7 @@ bool PiecesLibrary::ImportTexture (const char* Name)
// =============================================================================
// LDraw support
bool PiecesLibrary::ImportLDrawPiece (const char* Filename)
bool PiecesLibrary::ImportLDrawPiece(const char* Filename, File* NewIdxFile, File* NewBinFile, File* OldIdxFile, File* OldBinFile)
{
LC_LDRAW_PIECE piece;
@ -1408,16 +1461,112 @@ bool PiecesLibrary::ImportLDrawPiece (const char* Filename)
if (ReadLDrawPiece (Filename, &piece))
{
// if (FindPieceInfo (piece.name) != NULL)
// Sys_MessageBox ("Piece already exists in the library !");
char* Moved = strstr(piece.description, "~Moved to ");
if (Moved)
{
lcuint16 Count;
OldIdxFile->Seek(-(2+4+2), SEEK_END);
OldIdxFile->ReadShort(&Count, 1);
lcuint32 cs = Count * 2 * LC_PIECE_NAME_LEN;
OldIdxFile->Seek(-(long)(cs+2), SEEK_CUR);
if (SaveLDrawPiece (&piece))
Sys_MessageBox ("Piece successfully imported.");
else
lcuint32 Length = OldIdxFile->GetPosition();
void* Buffer = malloc(Length);
OldIdxFile->Seek(0, SEEK_SET);
OldIdxFile->Read(Buffer, Length);
NewIdxFile->Seek(0, SEEK_SET);
NewIdxFile->Write(Buffer, Length);
free(Buffer);
Buffer = malloc(cs);
OldIdxFile->Read(Buffer, cs);
char* Reference = (char*)Buffer;
// Add piece to moved list.
if (!strchr(Moved, '\\') && !strchr(Moved, '/'))
{
Moved += strlen("~Moved to ");
_strupr(Moved);
char* Dst = NULL;
for (int i = 0; i < Count; i++)
{
if (!strncmp(&Reference[i*2*LC_PIECE_NAME_LEN], piece.name, LC_PIECE_NAME_LEN))
{
Dst = &Reference[i*LC_PIECE_NAME_LEN+LC_PIECE_NAME_LEN];
memset(Dst, 0, LC_PIECE_NAME_LEN);
memcpy(Dst, Moved, strlen(Moved));
}
}
if (!Dst)
{
Buffer = realloc(Buffer, 2*LC_PIECE_NAME_LEN*(Count+1));
Reference = (char*)Buffer;
memset(&Reference[Count*2*LC_PIECE_NAME_LEN], 0, 2*LC_PIECE_NAME_LEN);
memcpy(&Reference[Count*2*LC_PIECE_NAME_LEN], piece.name, strlen(piece.name));
memcpy(&Reference[Count*2*LC_PIECE_NAME_LEN+LC_PIECE_NAME_LEN], Moved, strlen(Moved));
Count++;
}
}
NewIdxFile->Write(Reference, Count*2*LC_PIECE_NAME_LEN);
NewIdxFile->WriteShort(&Count, 1);
free(Buffer);
Buffer = malloc(4+2);
OldIdxFile->Seek(-(4+2), SEEK_END);
OldIdxFile->Read(Buffer, 4+2);
NewIdxFile->Write(Buffer, 4+2);
free(Buffer);
OldBinFile->Seek(0, SEEK_END);
Length = OldBinFile->GetPosition();
Buffer = malloc(Length);
OldBinFile->Seek(0, SEEK_SET);
OldBinFile->Read(Buffer, Length);
NewBinFile->Seek(0, SEEK_SET);
NewBinFile->Write(Buffer, Length);
free(Buffer);
// Delete existing piece.
// lcPtrArray<const char> Pieces;
// Pieces.Add(piece.name);
// DeletePieces(Pieces);
}
else if (!SaveLDrawPiece(&piece, NewIdxFile, NewBinFile, OldIdxFile, OldBinFile))
{
fprintf(stderr, "Error saving library after importing %s.\n", Filename);
Sys_MessageBox ("Error saving library.");
return false;
}
}
else
{
void* Buffer;
lcuint32 Length;
OldBinFile->Seek(0, SEEK_END);
Length = OldBinFile->GetPosition();
Buffer = malloc(Length);
OldBinFile->Seek(0, SEEK_SET);
OldBinFile->Read(Buffer, Length);
NewBinFile->Seek(0, SEEK_SET);
NewBinFile->Write(Buffer, Length);
free(Buffer);
OldIdxFile->Seek(0, SEEK_END);
Length = OldIdxFile->GetPosition();
Buffer = malloc(Length);
OldIdxFile->Seek(0, SEEK_SET);
OldIdxFile->Read(Buffer, Length);
NewIdxFile->Seek(0, SEEK_SET);
NewIdxFile->Write(Buffer, Length);
free(Buffer);
fprintf(stderr, "Error reading file %s\n", Filename);
Sys_MessageBox ("Error reading file.");
}
FreeLDrawPiece(&piece);
@ -2355,64 +2504,47 @@ bool ReadLDrawPiece(const char* filename, LC_LDRAW_PIECE* piece)
return true;
}
bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
bool SaveLDrawPiece(LC_LDRAW_PIECE* piece, File* NewIdxFile, File* NewBinFile, File* OldIdxFile, File* OldBinFile)
{
FileDisk newbin, newidx, oldbin, oldidx;
char file1[LC_MAXPATH], file2[LC_MAXPATH];
unsigned short count, moved;
unsigned long i, j, cs, binoff = 0, delta;
lcuint16 count, moved;
lcuint32 i, j, cs, binoff = 0, delta;
void* membuf;
short scale, sb[6];
lcuint16 scale, sb[6];
PiecesLibrary *pLib = lcGetPiecesLibrary();
strcpy(file1, pLib->GetLibraryPath());
strcat(file1, "pieces-b.old");
remove(file1);
strcpy(file2, pLib->GetLibraryPath());
strcat(file2, "pieces.bin");
rename(file2, file1);
File& NewIdx = *NewIdxFile;
File& NewBin = *NewBinFile;
File& OldIdx = *OldIdxFile;
File& OldBin = *OldBinFile;
if ((!oldbin.Open(file1, "rb")) ||
(!newbin.Open(file2, "wb")))
return false;
OldIdx.Seek(0, SEEK_SET);
OldBin.Seek(0, SEEK_SET);
strcpy(file1, pLib->GetLibraryPath());
strcat(file1, "pieces-i.old");
remove(file1);
strcpy(file2, pLib->GetLibraryPath());
strcat(file2, "pieces.idx");
rename(file2, file1);
if ((!oldidx.Open(file1, "rb")) ||
(!newidx.Open(file2, "wb")))
return false;
oldidx.Seek(-2, SEEK_END);
oldidx.ReadShort(&count, 1);
oldidx.Seek(34, SEEK_SET);
OldIdx.Seek(-2, SEEK_END);
OldIdx.ReadShort(&count, 1);
OldIdx.Seek(34, SEEK_SET);
for (j = 0; j < count; j++)
{
char name[LC_PIECE_NAME_LEN];
oldidx.Read(name, LC_PIECE_NAME_LEN);
OldIdx.Read(name, LC_PIECE_NAME_LEN);
if (strcmp(name, piece->name) == 0)
{
oldidx.Seek(64+12+1+4, SEEK_CUR);
oldidx.ReadLong(&binoff, 1);
oldidx.ReadLong(&delta, 1);
oldidx.Seek(-(LC_PIECE_NAME_LEN+64+12+1+4+4+4), SEEK_CUR);
OldIdx.Seek(64+12+1+4, SEEK_CUR);
OldIdx.ReadLong(&binoff, 1);
OldIdx.ReadLong(&delta, 1);
OldIdx.Seek(-(LC_PIECE_NAME_LEN+64+12+1+4+4+4), SEEK_CUR);
delta += binoff;
break;
}
oldidx.Seek(64+12+1+4+4+4, SEEK_CUR);
OldIdx.Seek(64+12+1+4+4+4, SEEK_CUR);
}
if (binoff == 0)
binoff = oldbin.GetLength();
binoff = OldBin.GetLength();
cs = oldidx.GetPosition();
cs = OldIdx.GetPosition();
membuf = malloc(cs);
if (membuf == NULL)
{
@ -2420,9 +2552,9 @@ bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
return false;
}
oldidx.Seek(0, SEEK_SET);
oldidx.Read(membuf, cs);
newidx.Write(membuf, cs);
OldIdx.Seek(0, SEEK_SET);
OldIdx.Read(membuf, cs);
NewIdx.Write(membuf, cs);
free(membuf);
membuf = malloc (binoff);
@ -2432,9 +2564,9 @@ bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
return false;
}
oldbin.Seek(0, SEEK_SET);
oldbin.Read(membuf, binoff);
newbin.Write(membuf, binoff);
OldBin.Seek(0, SEEK_SET);
OldBin.Read(membuf, binoff);
NewBin.Write(membuf, binoff);
free(membuf);
// Save piece
@ -2553,68 +2685,68 @@ bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
scale = 100;
// Write the vertex data
newbin.WriteLong(&piece->verts_count, 1);
NewBin.WriteLong(&piece->verts_count, 1);
for (i = 0; i < piece->verts_count; i++)
{
float tmp[3] = { scale*piece->verts[(i*3)], scale*piece->verts[(i*3)+1], scale*piece->verts[(i*3)+2] };
short sh[3] = { (short)tmp[0], (short)tmp[1], (short)tmp[2] };
newbin.WriteShort(&sh, 3);
NewBin.WriteShort(&sh, 3);
}
// Write the connections information
for (s = 0, con = piece->connections; con; con = con->next)
s++;
newbin.WriteShort(&s, 1);
NewBin.WriteShort(&s, 1);
for (con = piece->connections; con; con = con->next)
{
float tmp[3] = { scale*con->pos[0], scale*con->pos[1], scale*con->pos[2] };
short sh[3] = { (short)tmp[0], (short)tmp[1], (short)tmp[2] };
newbin.WriteByte(&con->type, 1);
newbin.WriteShort(sh, 3);
NewBin.WriteByte(&con->type, 1);
NewBin.WriteShort(sh, 3);
sh[0] = (short)(con->up[0]*(1<<14));
sh[1] = (short)(con->up[1]*(1<<14));
sh[2] = (short)(con->up[2]*(1<<14));
newbin.WriteShort(sh, 3);
NewBin.WriteShort(sh, 3);
}
// Textures
for (bt = 0, tex = piece->textures; tex; tex = tex->next)
bt++;
newbin.WriteByte(&bt, 1);
NewBin.WriteByte(&bt, 1);
for (tex = piece->textures; tex; tex = tex->next)
{
newbin.WriteByte(&tex->color, 1);
newbin.Write(tex->name, 8);
NewBin.WriteByte(&tex->color, 1);
NewBin.Write(tex->name, 8);
for (i = 0; i < 12; i++)
{
float tmp[1] = { tex->points[i]*scale };
short sh[1] = { (short)tmp[0] };
newbin.WriteShort(sh, 1);
NewBin.WriteShort(sh, 1);
}
for (i = 12; i < 20; i++)
{
float tmp = tex->points[i];
short sh[1] = { (short)tmp };
newbin.WriteShort(sh, 1);
NewBin.WriteShort(sh, 1);
}
}
for (s = 0, group = piece->groups; group; group = group->next)
s++;
newbin.WriteShort(&s, 1);
NewBin.WriteShort(&s, 1);
for (group = piece->groups; group; group = group->next)
{
for (bt = 0; bt < 5; bt++)
if (!group->connections[bt])
break;
newbin.WriteByte(&bt, 1);
NewBin.WriteByte(&bt, 1);
for (bt = 0; bt < 5; bt++)
{
@ -2624,15 +2756,15 @@ bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
for (s = 0, con = piece->connections; con; con = con->next, s++)
if (con == group->connections[bt])
break;
newbin.WriteShort(&s, 1);
NewBin.WriteShort(&s, 1);
}
// TODO: make this endian-safe
newbin.Write(group->drawinfo, group->infosize);
NewBin.Write(group->drawinfo, group->infosize);
}
// Now write the index
newidx.Write(piece->name, LC_PIECE_NAME_LEN);
newidx.Write(piece->description, 64);
NewIdx.Write(piece->name, LC_PIECE_NAME_LEN);
NewIdx.Write(piece->description, 64);
for (i = 0; i < 6; i++)
{
@ -2642,7 +2774,7 @@ bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
// sb[i] = scale*box[i];
sb[i] = (short)ff;
}
newidx.WriteShort(sb, 6);
NewIdx.WriteShort(sb, 6);
// Calculate flags.
bt = LC_PIECE_COUNT;
@ -2653,63 +2785,58 @@ bool SaveLDrawPiece(LC_LDRAW_PIECE* piece)
bt |= LC_PIECE_MEDIUM;
if (piece->long_info)
bt |= LC_PIECE_LONGDATA;
bt |= LC_PIECE_LONGDATA_FILE;
newidx.WriteByte(&bt, 1);
NewIdx.WriteByte(&bt, 1);
i = 0;//PiecesLibrary::GetDefaultPieceGroup(piece->description);
newidx.WriteLong(&i, 1);
newidx.WriteLong(&binoff, 1);
NewIdx.WriteLong(&i, 1);
NewIdx.WriteLong(&binoff, 1);
i = newbin.GetLength() - binoff;
newidx.WriteLong(&i, 1);
i = NewBin.GetLength() - binoff;
NewIdx.WriteLong(&i, 1);
// replacing a piece
if (j != count)
{
unsigned long d = newbin.GetPosition() - delta;
oldidx.Seek (LC_PIECE_NAME_LEN+64+12+1+4+4+4, SEEK_CUR);
unsigned long d = NewBin.GetPosition() - delta;
OldIdx.Seek (LC_PIECE_NAME_LEN+64+12+1+4+4+4, SEEK_CUR);
for (j++; j < count; j++)
{
unsigned long dw;
lcuint32 dw;
char buf[LC_PIECE_NAME_LEN+64+12+1+4];
oldidx.Read(buf, LC_PIECE_NAME_LEN+64+12+1+4);
oldidx.ReadLong(&dw, 1);
OldIdx.Read(buf, LC_PIECE_NAME_LEN+64+12+1+4);
OldIdx.ReadLong(&dw, 1);
dw += d;
newidx.Write(buf, LC_PIECE_NAME_LEN+64+12+1+4);
newidx.WriteLong(&dw, 1);
oldidx.ReadLong(&dw, 1);
newidx.WriteLong(&dw, 1);
NewIdx.Write(buf, LC_PIECE_NAME_LEN+64+12+1+4);
NewIdx.WriteLong(&dw, 1);
OldIdx.ReadLong(&dw, 1);
NewIdx.WriteLong(&dw, 1);
}
d = oldbin.GetLength()-delta;
d = OldBin.GetLength()-delta;
membuf = malloc (d);
oldbin.Seek (delta, SEEK_SET);
oldbin.Read (membuf, d);
newbin.Write(membuf, d);
OldBin.Seek(delta, SEEK_SET);
OldBin.Read(membuf, d);
NewBin.Write(membuf, d);
free(membuf);
}
else
count++;
// Fix the end of the index
oldidx.Seek(-(2+4+2), SEEK_END);
oldidx.ReadShort(&moved, 1);
cs = 2+(moved*16);
oldidx.Seek(-(long)cs, SEEK_CUR);
OldIdx.Seek(-(2+4+2), SEEK_END);
OldIdx.ReadShort(&moved, 1);
cs = 2+(moved*LC_PIECE_NAME_LEN*2);
OldIdx.Seek(-(long)cs, SEEK_CUR);
membuf = malloc(cs);
oldidx.Read(membuf, cs);
newidx.Write(membuf, cs);
OldIdx.Read(membuf, cs);
NewIdx.Write(membuf, cs);
free(membuf);
binoff = newbin.GetPosition();
newidx.WriteLong(&binoff, 1);
newidx.WriteShort(&count, 1);
oldidx.Close();
oldbin.Close();
newidx.Close();
newbin.Close();
binoff = NewBin.GetPosition();
NewIdx.WriteLong(&binoff, 1);
NewIdx.WriteShort(&count, 1);
return true;
}

View file

@ -13,11 +13,11 @@ class PieceInfo;
#define LC_CATEGORY_FILE_ID LC_FOURCC('C', 'A', 'T', 0)
#define LC_CATEGORY_FILE_VERSION 0x0100
typedef struct
struct PiecesLibraryCategory
{
String Name;
String Keywords;
} PiecesLibraryCategory;
};
class PiecesLibrary
{
@ -74,11 +74,12 @@ public:
Texture* GetTexture(int index) const;
// File operations.
bool DeletePieces(PtrArray<PieceInfo>& Pieces);
bool DeleteAllPieces();
bool DeletePieces(PtrArray<const char>& Pieces);
bool LoadUpdate(const char* update);
bool DeleteTextures(char** Names, int NumTextures);
bool ImportTexture(const char* Name);
bool ImportLDrawPiece(const char* Filename);
bool ImportLDrawPiece(const char* Filename, File* NewIdxFile, File* NewBinFile, File* OldIdxFile, File* OldBinFile);
// Set when pieces are added/removed from the library.
bool m_Modified;
@ -117,37 +118,37 @@ protected:
// ============================================================================
// This should be cleaned and moved to the PiecesLibrary class
typedef struct connection_s
struct connection_t
{
unsigned char type;
float pos[3];
float up[3];
connection_s* next;
} connection_t;
connection_t* next;
};
typedef struct group_s
struct group_t
{
connection_t* connections[5];
void* drawinfo;
unsigned long infosize;
group_s* next;
} group_t;
group_t* next;
};
typedef struct lineinfo_s
struct lineinfo_t
{
unsigned char type;
unsigned char color;
float points[12];
lineinfo_s* next;
} lineinfo_t;
lineinfo_t* next;
};
typedef struct texture_s
struct texture_t
{
float points[20];
unsigned char color;
char name[9];
texture_s* next;
} texture_t;
texture_t* next;
};
struct LC_LDRAW_PIECE
{
@ -162,7 +163,7 @@ struct LC_LDRAW_PIECE
};
bool ReadLDrawPiece(const char* filename, LC_LDRAW_PIECE* piece);
bool SaveLDrawPiece(LC_LDRAW_PIECE* piece);
bool SaveLDrawPiece(LC_LDRAW_PIECE* piece, File* NewIdxFile, File* NewBinFile, File* OldIdxFile, File* OldBinFile);
void FreeLDrawPiece(LC_LDRAW_PIECE* piece);
#endif // _LIBRARY_H_

View file

@ -479,7 +479,7 @@ void Piece::MinIntersectDist(LC_CLICKLINE* pLine)
float* verts = m_pPieceInfo->m_fVertexArray;
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA)
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
lcuint32* info = (lcuint32*)m_pDrawInfo, colors, i;
colors = *info;
@ -698,7 +698,7 @@ bool Piece::IntersectsVolume(const Vector4* Planes, int NumPlanes)
float* verts = m_pPieceInfo->m_fVertexArray;
bool ret = false;
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA)
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
lcuint32* info = (lcuint32*)m_pDrawInfo, colors, i;
colors = *info;
@ -904,7 +904,7 @@ void Piece::BuildDrawInfo()
if (add)
{
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA)
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
lcuint32* p, curcol, colors;
p = (lcuint32*)dg->drawinfo;
@ -956,7 +956,7 @@ void Piece::BuildDrawInfo()
vert += (colcount*4)+1;
// Build the info
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA)
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
m_pDrawInfo = malloc(vert*sizeof(lcuint32));
lcuint32* drawinfo = (lcuint32*)m_pDrawInfo;
@ -1193,7 +1193,7 @@ void Piece::Render(bool bLighting, bool bEdges, unsigned char* nLastColor, bool*
glDisable(GL_TEXTURE_2D);
}
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA)
if (m_pPieceInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
lcuint32 colors, *info = (lcuint32*)m_pDrawInfo;
colors = *info;

View file

@ -427,9 +427,9 @@ void PieceInfo::LoadInformation()
while (*bytes)
{
if (*bytes == LC_MESH)
{
if ((fixverts > 65535) || (m_nFlags & LC_PIECE_LONGDATA))
if (*bytes == LC_MESH)
{
if (m_nFlags & LC_PIECE_LONGDATA_FILE)
{
lcuint32 colors, *p;
p = (lcuint32*)(bytes + 1);
@ -502,15 +502,8 @@ void PieceInfo::LoadInformation()
m_fVertexArray = (float*)malloc(3*sizeof(float)*verts);
m_nVertexCount = verts;
if ((verts > 65535) || (quads > 65535) || (fixquads > 65535))
{
if ((m_nFlags & LC_PIECE_LONGDATA) == 0)
{
m_nFlags |= LC_PIECE_LONGDATA | LC_PIECE_LONGDATA_RUNTIME;
}
}
else
m_nFlags &= ~(LC_PIECE_LONGDATA | LC_PIECE_LONGDATA_RUNTIME);
if (verts > 65535 || quads > 65535)
m_nFlags |= LC_PIECE_LONGDATA_INDICES;
// Copy the 'fixed' vertexes
shorts = (lcint16*)(longs + 1);
@ -540,17 +533,17 @@ void PieceInfo::LoadInformation()
bytes += sizeof(lcuint16);
}
// Currently there's only one type of drawinfo (mesh or stud)
// per group but this will change in the future.
switch (*bytes)
{
case LC_MESH:
if ((fixverts > 65535) || (fixquads > 65535))
{
// Currently there's only one type of drawinfo (mesh or stud)
// per group but this will change in the future.
switch (*bytes)
{
case LC_MESH:
if (m_nFlags & LC_PIECE_LONGDATA_FILE)
{
lcuint32 colors, *p;
bytes++;
p = (lcuint32*)bytes;
*p = LCUINT32(*p);
*p = LCUINT32(*p);
colors = *p;
p++;
@ -608,7 +601,7 @@ void PieceInfo::LoadInformation()
i = (unsigned char*)p - bytes;
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
pGroup->drawinfo = malloc(i*sizeof(lcuint32)/sizeof(lcuint16));
longs = (lcuint32*)pGroup->drawinfo;
@ -656,7 +649,7 @@ void PieceInfo::LoadInformation()
// colors + 2*num_prim + sides*prims
size = 9+SIDES*11;
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
pGroup->drawinfo = malloc(sizeof(lcuint32)*size);
longs = (lcuint32*)pGroup->drawinfo;
@ -815,7 +808,7 @@ void PieceInfo::LoadInformation()
// colors + 2*num_prim + sides*prims
size = 9+SIDES*20;
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
pGroup->drawinfo = malloc(sizeof(lcuint32)*size);
longs = (lcuint32*)pGroup->drawinfo;
@ -1046,7 +1039,7 @@ void PieceInfo::LoadInformation()
// colors + 2*num_prim + sides*prims
size = 9+SIDES*11;
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
pGroup->drawinfo = malloc(sizeof(lcuint32)*size);
longs = (lcuint32*)pGroup->drawinfo;
@ -1205,7 +1198,7 @@ void PieceInfo::LoadInformation()
// colors + 2*num_prim + sides*prims
size = 9+SIDES*20;
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
pGroup->drawinfo = malloc(sizeof(lcuint32)*size);
longs = (lcuint32*)pGroup->drawinfo;
@ -1452,10 +1445,8 @@ void PieceInfo::FreeInformation()
m_pTextures = NULL;
}
if (m_nFlags & LC_PIECE_LONGDATA_RUNTIME)
{
m_nFlags &= ~(LC_PIECE_LONGDATA | LC_PIECE_LONGDATA_RUNTIME);
}
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
m_nFlags &= ~LC_PIECE_LONGDATA_INDICES;
}
// Zoom extents for the preview window and print catalog
@ -1656,7 +1647,7 @@ void PieceInfo::RenderPiece(int nColor)
sh = m_nGroupCount;
for (pGroup = m_pGroups; sh--; pGroup++)
{
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
lcuint32* info, colors;
@ -1750,7 +1741,7 @@ void PieceInfo::WriteWavefront(FILE* file, unsigned char color, unsigned long* s
for (group = 0; group < m_nGroupCount; group++)
{
if (m_nFlags & LC_PIECE_LONGDATA)
if (m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
unsigned long* info = (unsigned long*)m_pGroups[group].drawinfo;
unsigned long count, colors = *info;

View file

@ -1,7 +1,3 @@
//
// pieceinf.h
////////////////////////////////////////////////////
#ifndef _PIECEINF_H_
#define _PIECEINF_H_
@ -11,38 +7,38 @@
#endif
#include "algebra.h"
#define LC_PIECE_COUNT 0x01 // Count this piece in the totals ?
#define LC_PIECE_LONGDATA 0x02 // unsigned long/short index
#define LC_PIECE_CCW 0x04 // Use back-face culling
#define LC_PIECE_SMALL 0x10 // scale = 10000
#define LC_PIECE_MEDIUM 0x20 // scale = 1000 (otherwise = 100)
#define LC_PIECE_LONGDATA_RUNTIME 0x40 // If the original data is 16 bits but we expanded to 32 bits
#define LC_PIECE_COUNT 0x01 // Count this piece in the totals ?
#define LC_PIECE_LONGDATA_FILE 0x02 // unsigned long/short index
#define LC_PIECE_CCW 0x04 // Use back-face culling
#define LC_PIECE_SMALL 0x10 // scale = 10000
#define LC_PIECE_MEDIUM 0x20 // scale = 1000 (otherwise = 100)
#define LC_PIECE_LONGDATA_INDICES 0x40 // unsigned long/short index
#define LC_PIECE_NAME_LEN 256
class File;
class Texture;
typedef struct
struct CONNECTIONINFO
{
unsigned char type;
float center[3];
float normal[3];
} CONNECTIONINFO;
};
typedef struct
struct DRAWGROUP
{
unsigned short connections[6];
void* drawinfo;
} DRAWGROUP;
};
typedef struct TEXTURE
struct TEXTURE
{
Texture* texture;
unsigned char color;
float vertex[4][3];
float coords[4][2];
} TEXTURE;
};
unsigned char ConvertColor(int c);

View file

@ -4190,7 +4190,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
unsigned short g;
for (g = 0; g < pInfo->m_nGroupCount; g++)
if (pInfo->m_nFlags & LC_PIECE_LONGDATA)
if (pInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
{
unsigned long* info = (unsigned long*)pInfo->m_pGroups[g].drawinfo;
unsigned long count, curcolor, colors = *info;

View file

@ -181,32 +181,30 @@ typedef enum
LC_CURSOR_COUNT
} LC_CURSOR_TYPE;
// Piece connections (complicated and wastes memory but fast).
typedef struct CONNECTION
// Piece connections.
struct CONNECTION
{
unsigned char type;
float center[3];
float normal[3];
CONNECTION* link;
Piece* owner;
} CONNECTION;
};
typedef struct
struct CONNECTION_ENTRY
{
Piece* owner;
CONNECTION** cons; // pointers to the structures in each piece
unsigned short numcons;
} CONNECTION_ENTRY;
};
typedef struct
struct CONNECTION_TYPE
{
CONNECTION_ENTRY* entries;
unsigned short numentries;
} CONNECTION_TYPE;
};
// Select by Name dialog data
typedef enum
{
LC_SELDLG_PIECE,
@ -215,15 +213,15 @@ typedef enum
LC_SELDLG_GROUP
} LC_SEL_DATA_TYPE;
typedef struct
struct LC_SEL_DATA
{
const char* name;
unsigned char type;
bool selected;
void* pointer;
} LC_SEL_DATA;
};
typedef struct
struct LC_PIECE_MODIFY
{
Piece* piece;
Vector3 Position;
@ -233,9 +231,9 @@ typedef struct
int to;
bool hidden;
int color;
} LC_PIECE_MODIFY;
};
typedef struct
struct LC_CAMERA_MODIFY
{
Camera* camera;
Vector3 Eye;
@ -246,7 +244,7 @@ typedef struct
float znear;
float zfar;
bool hidden;
} LC_CAMERA_MODIFY;
};
// Image
@ -259,7 +257,7 @@ typedef enum
LC_IMAGE_AVI
} LC_IMAGE_FORMATS;
typedef struct
struct LC_IMAGE_OPTS
{
unsigned char quality;
bool interlaced;
@ -268,9 +266,9 @@ typedef struct
unsigned char background[3];
float pause;
unsigned int format;
} LC_IMAGE_OPTS;
};
typedef struct
struct LC_IMAGEDLG_OPTS
{
char filename[LC_MAXPATH];
unsigned short from;
@ -279,7 +277,7 @@ typedef struct
unsigned short width;
unsigned short height;
LC_IMAGE_OPTS imopts;
} LC_IMAGEDLG_OPTS;
};
typedef enum {
LC_DLG_FILE_OPEN_PROJECT,
@ -287,6 +285,7 @@ typedef enum {
LC_DLG_FILE_MERGE_PROJECT,
LC_DLG_FILE_OPEN,
LC_DLG_FILE_SAVE,
LC_DLG_DIRECTORY_BROWSE,
LC_DLG_PICTURE_SAVE,
LC_DLG_HTML,
LC_DLG_POVRAY,
@ -312,34 +311,40 @@ typedef enum
LC_FILEOPENDLG_LUP
} LC_FILEOPENDLG_TYPES;
typedef struct
struct LC_FILEOPENDLG_OPTS
{
int type;
char path[LC_MAXPATH];
int numfiles;
char** filenames;
} LC_FILEOPENDLG_OPTS;
};
typedef enum
{
LC_FILESAVEDLG_LCF,
} LC_FILESAVEDLG_TYPES;
typedef struct
struct LC_FILESAVEDLG_OPTS
{
int type;
char path[LC_MAXPATH];
} LC_FILESAVEDLG_OPTS;
};
typedef struct
struct LC_DLG_DIRECTORY_BROWSE_OPTS
{
const char* Title;
char Path[LC_MAXPATH];
};
struct LC_POVRAYDLG_OPTS
{
bool render;
char povpath[LC_MAXPATH];
char outpath[LC_MAXPATH];
char libpath[LC_MAXPATH];
} LC_POVRAYDLG_OPTS;
};
typedef struct
struct LC_HTMLDLG_OPTS
{
char path[LC_MAXPATH];
bool singlepage;
@ -350,9 +355,9 @@ typedef struct
bool highlight;
bool htmlext;
LC_IMAGEDLG_OPTS imdlg;
} LC_HTMLDLG_OPTS;
};
typedef struct
struct LC_ARRAYDLG_OPTS
{
unsigned short n1DCount;
unsigned short n2DCount;
@ -362,9 +367,9 @@ typedef struct
float f3D[3];
float fMove[3];
float fRotate[3];
} LC_ARRAYDLG_OPTS;
};
typedef struct
struct LC_PROPERTIESDLG_OPTS
{
char strAuthor[101];
char strDescription[101];
@ -374,9 +379,9 @@ typedef struct
char** names;
unsigned short* count;
int lines;
} LC_PROPERTIESDLG_OPTS;
};
typedef struct
struct LC_GROUPEDITDLG_OPTS
{
int piececount;
Piece** pieces;
@ -384,9 +389,9 @@ typedef struct
int groupcount;
Group** groups;
Group** groupsgroups;
} LC_GROUPEDITDLG_OPTS;
};
typedef struct
struct LC_PREFERENCESDLG_OPTS
{
int nMouse;
int nSaveInterval;
@ -407,12 +412,12 @@ typedef struct
float fGrad2[3];
char strFooter[256];
char strHeader[256];
} LC_PREFERENCESDLG_OPTS;
};
typedef struct
struct LC_CATEGORYDLG_OPTS
{
String Name;
String Keywords;
} LC_CATEGORYDLG_OPTS;
};
#endif

View file

@ -498,6 +498,7 @@ BEGIN
MENUITEM "&Print Catalog...", ID_LIBDLG_FILE_PRINTCATALOG
MENUITEM "Load &Update...", ID_LIBDLG_FILE_MERGEUPDATE
MENUITEM "&Import Piece...", ID_FILE_IMPORTPIECE
MENUITEM "Import &Folder...", ID_FILE_IMPORTFOLDER
MENUITEM "Te&xtures...", ID_LIBDLG_FILE_TEXTURES
MENUITEM SEPARATOR
MENUITEM "Close", IDOK

View file

@ -137,6 +137,103 @@ BOOL CLibraryDlg::OnInitDialog()
return TRUE;
}
bool CLibraryDlg::ImportPieces(const ObjArray<String>& FileList)
{
char file1[LC_MAXPATH], file2[LC_MAXPATH];
PiecesLibrary* Library = lcGetPiecesLibrary();
FileDisk DiskIdx, DiskBin;
strcpy(file1, Library->GetLibraryPath());
strcat(file1, "pieces.idx");
strcpy(file2, Library->GetLibraryPath());
strcat(file2, "pieces.bin");
if ((!DiskIdx.Open(file1, "rb")) || (!DiskBin.Open(file2, "rb")))
return false;
FileMem IdxFile1, IdxFile2, BinFile1, BinFile2;
long Length;
Length = DiskIdx.GetLength();
IdxFile1.SetLength(Length);
DiskIdx.Read(IdxFile1.GetBuffer(), Length);
DiskIdx.Close();
Length = DiskBin.GetLength();
BinFile1.SetLength(Length);
DiskBin.Read(BinFile1.GetBuffer(), Length);
DiskBin.Close();
FileMem* NewIdx = &IdxFile1;
FileMem* NewBin = &BinFile1;
FileMem* OldIdx = &IdxFile2;
FileMem* OldBin = &BinFile2;
CProgressDlg Dlg("Importing pieces");
Dlg.Create(this);
Dlg.SetRange(0, FileList.GetSize());
for (int i = 0; i < FileList.GetSize(); i++)
{
char* Name = FileList[i];
char* Slash = strrchr(Name, '\\');
if (Slash > Name)
Name = Slash+1;
Slash = strrchr(Name, '/');
if (Slash > Name)
Name = Slash+1;
Dlg.SetStatus(Name);
Dlg.StepIt();
FileMem* TmpFile;
TmpFile = NewBin;
NewBin = OldBin;
OldBin = TmpFile;
NewBin->SetLength(0);
TmpFile = NewIdx;
NewIdx = OldIdx;
OldIdx = TmpFile;
NewIdx->SetLength(0);
lcGetPiecesLibrary()->ImportLDrawPiece(FileList[i], NewIdx, NewBin, OldIdx, OldBin);
if (Dlg.CheckCancelButton())
if (AfxMessageBox(IDS_CANCEL_PROMPT, MB_YESNO) == IDYES)
break;
}
if ((!DiskIdx.Open(file1, "wb")) || (!DiskBin.Open(file2, "wb")))
return false;
strcpy(file1, Library->GetLibraryPath());
strcat(file1, "pieces-b.old");
remove(file1);
strcpy(file2, Library->GetLibraryPath());
strcat(file2, "pieces.bin");
rename(file2, file1);
strcpy(file1, Library->GetLibraryPath());
strcat(file1, "pieces-i.old");
remove(file1);
strcpy(file2, Library->GetLibraryPath());
strcat(file2, "pieces.idx");
rename(file2, file1);
DiskBin.Seek(0, SEEK_SET);
DiskBin.Write(NewBin->GetBuffer(), NewBin->GetLength());
DiskIdx.Seek(0, SEEK_SET);
DiskIdx.Write(NewIdx->GetBuffer(), NewIdx->GetLength());
UpdateList();
return true;
}
BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
switch (LOWORD(wParam))
@ -198,13 +295,18 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam)
if (SystemDoDialog (LC_DLG_FILE_OPEN, &opts))
{
ObjArray<String> FileList;
for (int i = 0; i < opts.numfiles; i++)
{
lcGetPiecesLibrary ()->ImportLDrawPiece (opts.filenames[i]);
FileList.Add(opts.filenames[i]);
free (opts.filenames[i]);
}
free (opts.filenames);
ImportPieces(FileList);
Sys_ProfileSaveString ("Default", "LDraw Pieces Path", opts.path);
UpdateList();
@ -213,6 +315,61 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam)
return TRUE;
}
case ID_FILE_IMPORTFOLDER:
{
LC_DLG_DIRECTORY_BROWSE_OPTS Opts;
Opts.Title = "Select Folder";
strcpy(Opts.Path, Sys_ProfileLoadString ("Default", "LDraw Pieces Path", ""));
if (!SystemDoDialog(LC_DLG_DIRECTORY_BROWSE, &Opts))
return TRUE;
ObjArray<String> FileList;
WIN32_FIND_DATA FindData;
HANDLE Find = INVALID_HANDLE_VALUE;
int Len = strlen(Opts.Path);
if (Opts.Path[Len-1] != '\\' && Opts.Path[Len-1] != '/')
strcat(Opts.Path, "\\");
char Dir[MAX_PATH];
strcpy(Dir, Opts.Path);
strcat(Dir, "*.dat");
Find = FindFirstFile(Dir, &FindData);
if (Find == INVALID_HANDLE_VALUE)
{
SystemDoMessageBox("No files found.", LC_MB_OK | LC_MB_ICONERROR);
return TRUE;
}
do
{
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
char File[MAX_PATH];
strcpy(File, Opts.Path);
strcat(File, FindData.cFileName);
FileList.Add(File);
}
while (FindNextFile(Find, &FindData) != 0);
FindClose(Find);
lcGetPiecesLibrary()->DeleteAllPieces();
ImportPieces(FileList);
Sys_ProfileSaveString("Default", "LDraw Pieces Path", Opts.Path);
return TRUE;
}
case ID_LIBDLG_FILE_TEXTURES:
{
CTexturesDlg dlg;
@ -317,12 +474,15 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam)
case ID_LIBDLG_PIECE_DELETE:
{
PtrArray<PieceInfo> Pieces;
PtrArray<const char> Pieces;
for (int i = 0; i < m_List.GetItemCount(); i++)
{
if (m_List.GetItemState(i, LVIS_SELECTED))
Pieces.Add((PieceInfo*)m_List.GetItemData(i));
{
PieceInfo* Info = (PieceInfo*)m_List.GetItemData(i);
Pieces.Add(Info->m_strName);
}
}
if (Pieces.GetSize() == 0)

View file

@ -1,6 +1,9 @@
#ifndef _LIBDLG_H_
#define _LIBDLG_H_
#include "array.h"
#include "str.h"
class PieceInfo;
class CLibraryDlg : public CDialog
@ -33,6 +36,8 @@ public:
void UpdateTree();
void UpdateList();
bool ImportPieces(const ObjArray<String>& FileList);
CToolBar m_wndToolBar;
CImageList m_TreeImages;
int m_SortColumn;

View file

@ -1315,6 +1315,47 @@ bool SystemDoDialog(int nMode, void* param)
}
} break;
case LC_DLG_DIRECTORY_BROWSE:
{
LC_DLG_DIRECTORY_BROWSE_OPTS* Opts = (LC_DLG_DIRECTORY_BROWSE_OPTS*)param;
strcpy(Opts->Path, "");
LPMALLOC ShellMalloc;
if (SHGetMalloc(&ShellMalloc) == NOERROR)
{
BROWSEINFO bi;
LPITEMIDLIST pidl;
if (AfxGetMainWnd())
bi.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();
else
bi.hwndOwner = ::GetDesktopWindow();
bi.pidlRoot = NULL;
bi.pszDisplayName = Opts->Path;
bi.lpszTitle = Opts->Title;
bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = 0;
pidl = SHBrowseForFolder(&bi);
if (pidl != NULL)
{
if (SHGetPathFromIDList(pidl, Opts->Path))
{
if (Opts->Path[strlen(Opts->Path)-1] != '\\')
strcat(Opts->Path, "\\");
return true;
}
ShellMalloc->Free(pidl);
}
ShellMalloc->Release();
}
return false;
} break;
case LC_DLG_HTML:
{
LC_HTMLDLG_OPTS* opts = (LC_HTMLDLG_OPTS*)param;

View file

@ -454,7 +454,7 @@ void Export3DStudio()
memset(facemats, 0, sizeof(facemats));
PieceInfo* pInfo = pPiece->GetPieceInfo();
if (pInfo->m_nFlags & LC_PIECE_LONGDATA)
if (pInfo->m_nFlags & LC_PIECE_LONGDATA_INDICES)
continue; // 3DS can't handle this
// count number of faces used

View file

@ -663,6 +663,7 @@
#define ID_VIEW_TOOLBARS 33175
#define ID_VIEW_SPLIT_HORIZONTALLY 33177
#define ID_TOOLBARS_PROPERTIES 33178
#define ID_FILE_IMPORTFOLDER 33179
#define ID_VIEW_PIECES_BAR 59425
#define ID_VIEW_TOOLS_BAR 59426
#define ID_VIEW_ANIMATION_BAR 59427
@ -676,7 +677,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 242
#define _APS_NEXT_COMMAND_VALUE 33179
#define _APS_NEXT_COMMAND_VALUE 33180
#define _APS_NEXT_CONTROL_VALUE 1247
#define _APS_NEXT_SYMED_VALUE 121
#endif