diff --git a/common/array.cpp b/common/array.cpp index a91a47fb..2928d596 100755 --- a/common/array.cpp +++ b/common/array.cpp @@ -22,10 +22,19 @@ PtrArray::~PtrArray() free(m_pData); } +template +void PtrArray::SetSize(int Size) +{ + if (Size > m_nLength) + Expand(Size - m_nLength); + + m_nLength = Size; +} + template void PtrArray::Expand(int nGrow) { - if((m_nLength + nGrow) > m_nAlloc) + if ((m_nLength + nGrow) > m_nAlloc) { m_pData =(T**)realloc(m_pData,(m_nLength + nGrow) * sizeof(T*)); memset(m_pData + m_nLength, 0, nGrow * sizeof(T*)); @@ -95,6 +104,12 @@ void PtrArray::AddSorted(T* pObj, LC_PTRARRAY_COMPARE_FUNC pFunc, void* pData Add(pObj); } +template +void PtrArray::SetAt(int Index, T* Ptr) +{ + m_pData[Index] = Ptr; +} + template void PtrArray::InsertAt(int nIndex, T* pObj) { diff --git a/common/array.h b/common/array.h index 2cb47643..d11996e8 100755 --- a/common/array.h +++ b/common/array.h @@ -12,12 +12,14 @@ public: int GetSize() const { return m_nLength; } + void SetSize(int Size); T* RemoveIndex(int nIndex); T* RemovePointer(T* pObj); void RemoveAll(); void Add(T* pObj); void AddSorted(T* pObj, LC_PTRARRAY_COMPARE_FUNC pFunc, void* pData); + void SetAt(int Index, T* Ptr); void InsertAt(int nIndex, T* pObj); int FindIndex(T* Obj) const; void Sort(LC_PTRARRAY_COMPARE_FUNC SortFunc, void* SortData); diff --git a/common/library.cpp b/common/library.cpp index 58a457fb..87022fbc 100755 --- a/common/library.cpp +++ b/common/library.cpp @@ -29,8 +29,6 @@ PiecesLibrary::PiecesLibrary() strcpy(m_CategoriesFile, ""); m_pMovedReference = NULL; m_nMovedCount = 0; - m_pPieceIdx = NULL; - m_nPieceCount = 0; m_pTextures = NULL; m_nTextureCount = 0; m_Modified = false; @@ -44,16 +42,15 @@ PiecesLibrary::~PiecesLibrary() void PiecesLibrary::Unload () { + for (int PieceIdx = 0; PieceIdx < m_Pieces.GetSize(); PieceIdx++) + delete m_Pieces[PieceIdx]; + m_Pieces.RemoveAll(); + strcpy(m_LibraryPath, ""); free(m_pMovedReference); m_pMovedReference = NULL; m_nMovedCount = 0; - - delete [] m_pPieceIdx; - m_pPieceIdx = NULL; - m_nPieceCount = 0; - delete [] m_pTextures; m_pTextures = NULL; m_nTextureCount = 0; @@ -68,6 +65,8 @@ bool PiecesLibrary::Load (const char *libpath) Texture* pTexture; int i; + Unload(); + strcpy (m_LibraryPath, libpath); // Make sure that the path ends with a '/' @@ -103,13 +102,14 @@ bool PiecesLibrary::Load (const char *libpath) idx.ReadShort (&count, 1); idx.Seek (34, SEEK_SET); - // Load piece indexes - delete [] m_pPieceIdx; - m_pPieceIdx = new PieceInfo[count]; - m_nPieceCount = count; - - for (PieceInfo *pElements = m_pPieceIdx; count--; pElements++) - pElements->LoadIndex (idx); + // Load piece indices + m_Pieces.SetSize(count); + for (int PieceIdx = 0; PieceIdx < count; PieceIdx++) + { + PieceInfo* Info = new PieceInfo(); + Info->LoadIndex(idx); + m_Pieces.SetAt(PieceIdx, Info); + } // Load moved files reference. if (m_pMovedReference != NULL) @@ -181,6 +181,8 @@ bool PiecesLibrary::Load (const char *libpath) m_CategoriesModified = false; m_Modified = false; + Sys_ProfileSaveString("Settings", "PiecesLibrary", m_LibraryPath); + return true; } @@ -331,30 +333,30 @@ bool PiecesLibrary::ValidateTexturesFile (File& IdxFile, File& BinFile) const return true; } +PieceInfo* PiecesLibrary::CreatePiecePlaceholder(const char* Name) +{ + PieceInfo* Info = new PieceInfo(); + Info->CreatePlaceholder(Name); + m_Pieces.Add(Info); + return Info; +} + // ============================================================================= // Search functions // Remember to make 'name' uppercase. PieceInfo* PiecesLibrary::FindPieceInfo (const char* name) const { - PieceInfo* pInfo; - int i; + for (int PieceIdx = 0; PieceIdx < m_Pieces.GetSize(); PieceIdx++) + if (!strcmp(name, m_Pieces[PieceIdx]->m_strName)) + return m_Pieces[PieceIdx]; - for (i = 0, pInfo = m_pPieceIdx; i < m_nPieceCount; i++, pInfo++) - if (!strcmp (name, pInfo->m_strName)) - return pInfo; - - for (i = 0; i < m_nMovedCount; i++) + for (int i = 0; i < m_nMovedCount; i++) { if (!strcmp (&m_pMovedReference[i*LC_PIECE_NAME_LEN*2], name)) { char* tmp = &m_pMovedReference[i*LC_PIECE_NAME_LEN*2+LC_PIECE_NAME_LEN]; - - for (i = 0, pInfo = m_pPieceIdx; i < m_nPieceCount; i++, pInfo++) - if (!strcmp (tmp, pInfo->m_strName)) - return pInfo; - - break; // something went wrong. + return FindPieceInfo(tmp); } } @@ -363,12 +365,15 @@ PieceInfo* PiecesLibrary::FindPieceInfo (const char* name) const PieceInfo* PiecesLibrary::GetPieceInfo(int index) const { - return &m_pPieceIdx[index]; + if (index < 0 || index >= m_Pieces.GetSize()) + return NULL; + + return m_Pieces[index]; } int PiecesLibrary::GetPieceIndex(PieceInfo *pInfo) const { - return (((char*)pInfo - (char*)m_pPieceIdx) / sizeof (PieceInfo)); + return m_Pieces.FindIndex(pInfo); } Texture* PiecesLibrary::FindTexture(const char* name) const @@ -630,9 +635,9 @@ void PiecesLibrary::GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrA if (m_Categories[CategoryIndex].Name == "Search Results") GroupPieces = false; - for (int i = 0; i < m_nPieceCount; i++) + for (int i = 0; i < m_Pieces.GetSize(); i++) { - PieceInfo* Info = &m_pPieceIdx[i]; + PieceInfo* Info = m_Pieces[i]; if (!PieceInCategory(Info, m_Categories[CategoryIndex].Keywords)) continue; @@ -693,13 +698,30 @@ void PiecesLibrary::GetPatternedPieces(PieceInfo* Parent, PtrArray& P Pieces.RemoveAll(); - for (int i = 0; i < m_nPieceCount; i++) + for (int i = 0; i < m_Pieces.GetSize(); i++) { - PieceInfo* Info = &m_pPieceIdx[i]; + PieceInfo* Info = m_Pieces[i]; if (strncmp(Name, Info->m_strName, strlen(Name)) == 0) Pieces.Add(Info); } + + // Sometimes pieces with A and B versions don't follow the same convention (for example, 3040Pxx instead of 3040BPxx). + if (Pieces.GetSize() == 0) + { + strcpy(Name, Parent->m_strName); + int Len = strlen(Name); + if (Name[Len-1] < '0' || Name[Len-1] > '9') + Name[Len-1] = 'P'; + + for (int i = 0; i < m_Pieces.GetSize(); i++) + { + PieceInfo* Info = m_Pieces[i]; + + if (strncmp(Name, Info->m_strName, strlen(Name)) == 0) + Pieces.Add(Info); + } + } } void PiecesLibrary::SetCategory(int Index, const String& Name, const String& Keywords) diff --git a/common/library.h b/common/library.h index 9658e9a9..a78c02fd 100755 --- a/common/library.h +++ b/common/library.h @@ -26,11 +26,19 @@ public: ~PiecesLibrary(); const char* GetLibraryPath() const - { return m_LibraryPath; } - int GetPieceCount () const - { return m_nPieceCount; } - int GetTextureCount () const - { return m_nTextureCount; } + { + return m_LibraryPath; + } + + int GetPieceCount() const + { + return m_Pieces.GetSize(); + } + + int GetTextureCount() const + { + return m_nTextureCount; + } // Categories. bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const; @@ -73,6 +81,8 @@ public: Texture* FindTexture(const char* name) const; Texture* GetTexture(int index) const; + PieceInfo* CreatePiecePlaceholder(const char* Name); + // File operations. bool DeleteAllPieces(); bool DeletePieces(PtrArray& Pieces); @@ -85,6 +95,8 @@ public: bool m_Modified; protected: + PtrArray m_Pieces; + char m_LibraryPath[LC_MAXPATH]; // path to the library files int m_nMovedCount; // number of moved pieces diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 558d1e3b..f0272e1e 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -243,6 +243,36 @@ void PieceInfo::LoadIndex (File& file) m_fDimensions[5] = (float)sh[5]/scale; } +void PieceInfo::CreatePlaceholder(const char* Name) +{ + m_nRef = 0; + m_nVertexCount = 0; + m_fVertexArray = NULL; + m_nConnectionCount = 0; + m_pConnections = NULL; + m_nGroupCount = 0; + m_pGroups = NULL; + m_nTextureCount = 0; + m_pTextures = NULL; + m_nBoxList = 0; + + strncpy(m_strName, Name, sizeof(m_strName)); + m_strName[sizeof(m_strName)-1] = 0; + strncpy(m_strDescription, Name, sizeof(m_strDescription)); + m_strDescription[sizeof(m_strDescription)-1] = 0; + + m_nFlags = LC_PIECE_PLACEHOLDER; + m_nOffset = 0; + m_nSize = 0; + + m_fDimensions[0] = 0.4f; + m_fDimensions[1] = 0.4f; + m_fDimensions[2] = 0.16f; + m_fDimensions[3] = -0.4f; + m_fDimensions[4] = -0.4f; + m_fDimensions[5] = -0.96f; +} + void PieceInfo::AddRef() { if (m_nRef == 0) @@ -311,6 +341,120 @@ void PieceInfo::CreateBoxDisplayList() void PieceInfo::LoadInformation() { + if (m_nFlags & LC_PIECE_PLACEHOLDER) + { + m_nConnectionCount = 0; + m_pConnections = (CONNECTIONINFO*)malloc (m_nConnectionCount * sizeof(CONNECTIONINFO)); + m_nTextureCount = 0; + + m_nGroupCount = 1; + m_pGroups = (DRAWGROUP*)malloc(sizeof(DRAWGROUP)*m_nGroupCount); + memset(m_pGroups, 0, sizeof(DRAWGROUP)*m_nGroupCount); + + int verts = 8; + m_fVertexArray = (float*)malloc(3*sizeof(float)*verts); + m_nVertexCount = verts; + + Vector3 Min(-0.4f, -0.4f, -0.96f); + Vector3 Max(0.4f, 0.4f, 0.16f); + + m_fVertexArray[0*3+0] = Min[0]; m_fVertexArray[0*3+1] = Min[1]; m_fVertexArray[0*3+2] = Min[2]; + m_fVertexArray[1*3+0] = Min[0]; m_fVertexArray[1*3+1] = Max[1]; m_fVertexArray[1*3+2] = Min[2]; + m_fVertexArray[2*3+0] = Max[0]; m_fVertexArray[2*3+1] = Max[1]; m_fVertexArray[2*3+2] = Min[2]; + m_fVertexArray[3*3+0] = Max[0]; m_fVertexArray[3*3+1] = Min[1]; m_fVertexArray[3*3+2] = Min[2]; + m_fVertexArray[4*3+0] = Min[0]; m_fVertexArray[4*3+1] = Min[1]; m_fVertexArray[4*3+2] = Max[2]; + m_fVertexArray[5*3+0] = Min[0]; m_fVertexArray[5*3+1] = Max[1]; m_fVertexArray[5*3+2] = Max[2]; + m_fVertexArray[6*3+0] = Max[0]; m_fVertexArray[6*3+1] = Max[1]; m_fVertexArray[6*3+2] = Max[2]; + m_fVertexArray[7*3+0] = Max[0]; m_fVertexArray[7*3+1] = Min[1]; m_fVertexArray[7*3+2] = Max[2]; + + m_pGroups->connections[0] = 0xFFFF; + + m_pGroups->drawinfo = malloc((1 + 1 + 3 + 36 + 1 + 3 + 24) * 2); + lcuint16* drawinfo = (lcuint16*)m_pGroups->drawinfo; + + *drawinfo++ = 2; + *drawinfo++ = LC_COL_DEFAULT; + *drawinfo++ = 0; + *drawinfo++ = 36; + + *drawinfo++ = 0; + *drawinfo++ = 1; + *drawinfo++ = 2; + *drawinfo++ = 0; + *drawinfo++ = 2; + *drawinfo++ = 3; + + *drawinfo++ = 7; + *drawinfo++ = 6; + *drawinfo++ = 5; + *drawinfo++ = 7; + *drawinfo++ = 5; + *drawinfo++ = 4; + + *drawinfo++ = 0; + *drawinfo++ = 1; + *drawinfo++ = 5; + *drawinfo++ = 0; + *drawinfo++ = 5; + *drawinfo++ = 4; + + *drawinfo++ = 2; + *drawinfo++ = 3; + *drawinfo++ = 7; + *drawinfo++ = 2; + *drawinfo++ = 7; + *drawinfo++ = 6; + + *drawinfo++ = 0; + *drawinfo++ = 3; + *drawinfo++ = 7; + *drawinfo++ = 0; + *drawinfo++ = 7; + *drawinfo++ = 4; + + *drawinfo++ = 1; + *drawinfo++ = 2; + *drawinfo++ = 6; + *drawinfo++ = 1; + *drawinfo++ = 6; + *drawinfo++ = 5; + + *drawinfo++ = 0; + *drawinfo++ = LC_COL_EDGES; + *drawinfo++ = 0; + *drawinfo++ = 0; + *drawinfo++ = 24; + + *drawinfo++ = 0; + *drawinfo++ = 1; + *drawinfo++ = 1; + *drawinfo++ = 2; + *drawinfo++ = 2; + *drawinfo++ = 3; + *drawinfo++ = 3; + *drawinfo++ = 0; + + *drawinfo++ = 4; + *drawinfo++ = 5; + *drawinfo++ = 5; + *drawinfo++ = 6; + *drawinfo++ = 6; + *drawinfo++ = 7; + *drawinfo++ = 7; + *drawinfo++ = 4; + + *drawinfo++ = 0; + *drawinfo++ = 4; + *drawinfo++ = 1; + *drawinfo++ = 5; + *drawinfo++ = 2; + *drawinfo++ = 6; + *drawinfo++ = 3; + *drawinfo++ = 7; + + return; + } + FileDisk bin; char filename[LC_MAXPATH]; CONNECTIONINFO* pConnection; diff --git a/common/pieceinf.h b/common/pieceinf.h index e881b6b4..0cc70e5a 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -13,6 +13,7 @@ #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_PLACEHOLDER 0x80 // Placeholder for a piece not in the library. #define LC_PIECE_NAME_LEN 256 @@ -92,6 +93,7 @@ class PieceInfo return m_nBoxList; }; void LoadIndex(File& file); + void CreatePlaceholder(const char* Name); void AddRef(); void DeRef(); diff --git a/common/project.cpp b/common/project.cpp index d3dedccd..f6137fc8 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -822,9 +822,16 @@ bool Project::FileLoad(File* file, bool bUndo, bool bMerge) } } + if (!bMerge) + { + Camera* Cam = GetCamera(LC_CAMERA_MAIN); + for (i = 0; i < m_ViewList.GetSize (); i++) + m_ViewList[i]->m_Camera = Cam; + } + for (i = 0; i < m_ViewList.GetSize (); i++) { - m_ViewList[i]->MakeCurrent (); + m_ViewList[i]->MakeCurrent(); RenderInitialize(); } CalculateStep(); @@ -1037,11 +1044,11 @@ void Project::FileReadLDraw(File* file, Matrix* prevmat, int* nOk, int DefColor, { char buf[1024]; - // Save file offset. - lcuint32 Offset = file->GetPosition(); - file->Seek(0, SEEK_SET); + // Save file offset. + lcuint32 Offset = file->GetPosition(); + file->Seek(0, SEEK_SET); - while (file->ReadLine(buf, 1024)) + while (file->ReadLine(buf, 1024)) { strupr(buf); if (strstr(buf, "STEP")) @@ -1078,7 +1085,7 @@ void Project::FileReadLDraw(File* file, Matrix* prevmat, int* nOk, int DefColor, if (ptr != NULL) *ptr = 0; - // See if it's a piece in the library + // See if it's a piece in the library if (strlen(tmp) < LC_PIECE_NAME_LEN) { char name[LC_PIECE_NAME_LEN]; @@ -1103,36 +1110,56 @@ void Project::FileReadLDraw(File* file, Matrix* prevmat, int* nOk, int DefColor, } } - // Check for MPD files first. - if (read) - { - for (int i = 0; i < FileArray.GetSize(); i++) - { - if (stricmp(FileArray[i]->GetFileName(), pn) == 0) - { - FileReadLDraw(FileArray[i], &tmpmat, nOk, cl, nStep, FileArray); - read = false; - break; - } - } - } + // Check for MPD files first. + if (read) + { + for (int i = 0; i < FileArray.GetSize(); i++) + { + if (stricmp(FileArray[i]->GetFileName(), pn) == 0) + { + FileReadLDraw(FileArray[i], &tmpmat, nOk, cl, nStep, FileArray); + read = false; + break; + } + } + } - // Try to read the file from disk. + // Try to read the file from disk. if (read) { FileDisk tf; - if (tf.Open(pn, "rt")) - { + if (tf.Open(pn, "rt")) + { FileReadLDraw(&tf, &tmpmat, nOk, cl, nStep, FileArray); read = false; - } + } + } + + if (read) + { + // Create a placeholder. + PieceInfo* Info = lcGetPiecesLibrary()->CreatePiecePlaceholder(tmp); + + float x, y, z, rot[4]; + Piece* pPiece = new Piece(Info); + read = false; + + tmpmat.GetTranslation(&x, &y, &z); + pPiece->Initialize(x, y, z, *nStep, 1, cl); + pPiece->CreateName(m_pPieces); + AddPiece(pPiece); + tmpmat.ToAxisAngle(rot); + pPiece->ChangeKey(1, false, false, rot, LC_PK_ROTATION); + pPiece->ChangeKey(1, true, false, rot, LC_PK_ROTATION); + SystemPieceComboAdd(Info->m_strDescription); + (*nOk)++; } } } - // Restore file offset. - file->Seek(Offset, SEEK_SET); + // Restore file offset. + file->Seek(Offset, SEEK_SET); } bool Project::DoFileSave()