diff --git a/common/lc_application.cpp b/common/lc_application.cpp index aa4433b5..1bf22bb6 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -2,7 +2,7 @@ #include #include "lc_application.h" #include "lc_colors.h" -#include "library.h" +#include "lc_library.h" #include "system.h" #include "console.h" #include "opengl.h" @@ -14,7 +14,7 @@ lcApplication* g_App; -PiecesLibrary* lcGetPiecesLibrary() +lcPiecesLibrary* lcGetPiecesLibrary() { LC_ASSERT(g_App, "g_App not initialized."); return g_App->GetPiecesLibrary(); @@ -51,9 +51,7 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* SysLibPat { // Create an empty library. if (m_Library == NULL) - m_Library = new PiecesLibrary(); - else - m_Library->Unload(); + m_Library = new lcPiecesLibrary(); // Check if the user specified a library path in the command line. if (LibPath != NULL) @@ -83,86 +81,6 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* SysLibPat return false; } -void lcApplication::ConvertPiecesLibrary(const char* SrcPath, const char* DstPath) -{ - ObjArray FileList; - PiecesLibrary Library; - - Library.SetPath(DstPath); - - if (!Library.DeleteAllPieces()) - { - printf("Error: Couldn't open library file for writing."); // TODO: replace printfs with a callback and progress dialog, then delete the duplicate code in libdlg.cpp - return; - } - - Sys_GetFileList(SrcPath, FileList); - - if (!FileList.GetSize()) - { - printf("Error: No files to import."); - return; - } - - char file1[LC_MAXPATH], file2[LC_MAXPATH]; - lcDiskFile 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; - - lcMemFile IdxFile1, IdxFile2, BinFile1, BinFile2; - - IdxFile1.CopyFrom(DiskIdx); - BinFile1.CopyFrom(DiskBin); - - lcMemFile* NewIdx = &IdxFile1; - lcMemFile* NewBin = &BinFile1; - lcMemFile* OldIdx = &IdxFile2; - lcMemFile* OldBin = &BinFile2; - - 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; - - printf("Importing %s\n", Name); - - lcMemFile* 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 ((!DiskIdx.Open(file1, "wb")) || (!DiskBin.Open(file2, "wb"))) - { - printf("Error: Couldn't open library file for writing."); - return; - } - - DiskIdx.CopyFrom(*NewIdx); - DiskBin.CopyFrom(*NewBin); -} - void lcApplication::ParseIntegerArgument(int* CurArg, int argc, char* argv[], int* Value) { if (argc > (*CurArg + 1)) @@ -232,22 +150,6 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* SysLibPath) { ParseStringArgument(&i, argc, argv, &LibPath); } - else if (strcmp(Param, "--convert") == 0) - { - if (argc > i + 2) - { - ParseStringArgument(&i, argc, argv, &LDrawPath); - ParseStringArgument(&i, argc, argv, &LibPath); - - ConvertPiecesLibrary(LDrawPath, LibPath); - } - else - { - printf("Not enough command line arguments.\n"); - } - - return false; - } else if ((strcmp(Param, "-i") == 0) || (strcmp(Param, "--image") == 0)) { SaveImage = true; diff --git a/common/lc_application.h b/common/lc_application.h index 259f1ed0..d4e6241d 100644 --- a/common/lc_application.h +++ b/common/lc_application.h @@ -4,7 +4,7 @@ #include "array.h" class Project; -class PiecesLibrary; +class lcPiecesLibrary; class lcApplication { @@ -16,9 +16,8 @@ public: void Shutdown(); // Pieces library. - void ConvertPiecesLibrary(const char* SrcPath, const char* DstPath); bool LoadPiecesLibrary(const char* LibPath, const char* SysLibPath); - PiecesLibrary* GetPiecesLibrary() const + lcPiecesLibrary* GetPiecesLibrary() const { return m_Library; } @@ -42,11 +41,11 @@ protected: Project* m_ActiveProject; PtrArray m_Projects; - PiecesLibrary* m_Library; + lcPiecesLibrary* m_Library; }; extern lcApplication* g_App; -PiecesLibrary* lcGetPiecesLibrary(); +lcPiecesLibrary* lcGetPiecesLibrary(); Project* lcGetActiveProject(); #endif // _LC_APPLICATION_H_ diff --git a/common/lc_library.cpp b/common/lc_library.cpp index c61b7cb1..94a64810 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -4,6 +4,7 @@ #include "lc_file.h" #include "pieceinf.h" #include "lc_colors.h" +#include "system.h" lcPiecesLibrary::lcPiecesLibrary() { @@ -18,6 +19,57 @@ lcPiecesLibrary::~lcPiecesLibrary() delete mZipFile; } +PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, bool CreatePlaceholderIfMissing) +{ + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + if (!strcmp(PieceName, mPieces[PieceIdx]->m_strName)) + return mPieces[PieceIdx]; + + if (CreatePlaceholderIfMissing) + return CreatePlaceholder(PieceName); + + return NULL; +} + +PieceInfo* lcPiecesLibrary::CreatePlaceholder(const char* PieceName) +{ + PieceInfo* Info = new PieceInfo(); + + Info->CreatePlaceholder(PieceName); + mPieces.Add(Info); + + return Info; +} + +bool lcPiecesLibrary::Load(const char* SearchPath) +{ + char LibraryPath[LC_MAXPATH]; + + strcpy(LibraryPath, SearchPath); + + int i = strlen(LibraryPath) - 1; + if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/')) + strcat(LibraryPath, "/"); + + strcpy(mLibraryPath, LibraryPath); + strcat(LibraryPath, "complete.zip"); + + if (!OpenArchive(LibraryPath)) + return false; + + const char* FileName = Sys_ProfileLoadString("Settings", "Categories", ""); + if (!strlen(FileName) || !LoadCategories(FileName)) + ResetCategories(); + + SystemUpdateCategories(false); + + mCategoriesModified = false; + + Sys_ProfileSaveString("Settings", "PiecesLibrary", mLibraryPath); + + return true; +} + bool lcPiecesLibrary::OpenArchive(const char* FileName) { mZipFile = new lcZipFile(); @@ -579,3 +631,363 @@ void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Dat DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx]); } } + +bool lcPiecesLibrary::PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const +{ + String PieceName = Info->m_strDescription; + PieceName.MakeLower(); + + String Keywords = CategoryKeywords; + Keywords.MakeLower(); + + return PieceName.Match(Keywords); +} + +int lcPiecesLibrary::GetFirstPieceCategory(PieceInfo* Info) const +{ + for (int i = 0; i < mCategories.GetSize(); i++) + if (PieceInCategory(Info, mCategories[i].Keywords)) + return i; + + return -1; +} + +void lcPiecesLibrary::GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrArray& SinglePieces, PtrArray& GroupedPieces) +{ + SinglePieces.RemoveAll(); + GroupedPieces.RemoveAll(); + + // Don't group entries in the search results category. + if (mCategories[CategoryIndex].Name == "Search Results") + GroupPieces = false; + + for (int i = 0; i < mPieces.GetSize(); i++) + { + PieceInfo* Info = mPieces[i]; + + if (!PieceInCategory(Info, mCategories[CategoryIndex].Keywords)) + continue; + + if (!GroupPieces) + { + SinglePieces.Add(Info); + continue; + } + + // Check if it's a patterned piece. + if (Info->IsPatterned()) + { + PieceInfo* Parent; + + // Find the parent of this patterned piece. + char ParentName[LC_PIECE_NAME_LEN]; + strcpy(ParentName, Info->m_strName); + *strchr(ParentName, 'P') = '\0'; + + Parent = FindPiece(ParentName, false); + + if (Parent) + { + // Check if the parent was added as a single piece. + int Index = SinglePieces.FindIndex(Parent); + + if (Index != -1) + SinglePieces.RemoveIndex(Index); + + Index = GroupedPieces.FindIndex(Parent); + + if (Index == -1) + GroupedPieces.Add(Parent); + } + else + { + // Patterned pieces should have a parent but in case they don't just add them anyway. + SinglePieces.Add(Info); + } + } + else + { + // Check if this piece has already been added to this category by one of its children. + int Index = GroupedPieces.FindIndex(Info); + + if (Index == -1) + SinglePieces.Add(Info); + } + } +} + +void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, PtrArray& Pieces) const +{ + char Name[LC_PIECE_NAME_LEN]; + strcpy(Name, Parent->m_strName); + strcat(Name, "P"); + + Pieces.RemoveAll(); + + for (int i = 0; i < mPieces.GetSize(); i++) + { + PieceInfo* Info = mPieces[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 < mPieces.GetSize(); i++) + { + PieceInfo* Info = mPieces[i]; + + if (strncmp(Name, Info->m_strName, strlen(Name)) == 0) + Pieces.Add(Info); + } + } +} + +void lcPiecesLibrary::ResetCategories() +{ + struct CategoryEntry + { + const char* Name; + const char* Keywords; + }; + + // Animal, Antenna, Arch, Arm, Bar, Baseplate, Belville, Boat, Bracket, Brick, + // Car, Cone, Container, Conveyor, Crane, Cylinder, Door, Electric, Exhaust, + // Fence, Flag, Forklift, Freestyle, Garage, Gate, Glass, Grab, Hinge, Homemaker, + // Hose, Jack, Ladder, Lever, Magnet, Minifig, Minifig Accessory, Panel, Plane, + // Plant, Plate, Platform, Propellor, Rack, Roadsign, Rock, Scala, Slope, Staircase, + // Support, Tail, Tap, Technic, Tile, Tipper, Tractor, Trailer, Train, Turntable, + // Tyre, Wedge, Wheel, Winch, Window, Windscreen, Wing + CategoryEntry DefaultCategories[] = + { + { "Animal", "^%Animal" }, + { "Antenna", "^%Antenna" }, + { "Arch", "^%Arch" }, + { "Bar", "^%Bar" }, + { "Baseplate", "^%Baseplate | ^%Platform" }, + { "Boat", "^%Boat" }, + { "Brick", "^%Brick" }, + { "Container", "^%Container | ^%Box | ^Chest | ^%Storage | ^Mailbox" }, + { "Door and Window", "^%Door | ^%Window | ^%Glass | ^%Freestyle | ^%Gate | ^%Garage | ^%Roller" }, + { "Duplo", "^%Duplo | ^%Scala | ^%Belville" }, + { "Electric", "^%Electric | ^%Light | ^%Excavator | ^%Exhaust" }, + { "Hinge and Bracket", "^%Hinge | ^%Bracket | ^%Turntable" }, + { "Hose", "^%Hose" }, + { "Minifig", "^%Minifig" }, + { "Miscellaneous", "^%Arm | ^%Barrel | ^%Brush | ^%Cockpit | ^%Conveyor | ^%Crane | ^%Cupboard | ^%Fabuland | ^%Fence | ^%Homemaker | ^%Jack | ^%Ladder | ^%Rock | ^%Staircase | ^%Stretcher | ^%Tap | ^%Tipper | ^%Trailer | ^%Winch" }, + { "Panel", "^%Panel | ^%Castle Wall | ^%Castle Turret" }, + { "Plant", "^%Plant" }, + { "Plate", "^%Plate" }, + { "Round", "^%Cylinder | ^%Cone | ^%Dish | ^%Round" }, + { "Sign and Flag", "^%Flag | ^%Roadsign | ^%Streetlight | ^%Flagpost | ^%Lamppost | ^%Signpost" }, + { "Slope", "^%Slope" }, + { "Space", "^%Space" }, + { "Sticker", "^%Sticker" }, + { "Support", "^%Support" }, + { "Technic", "^%Technic | ^%Rack" }, + { "Tile", "^%Tile" }, + { "Train", "^%Train | ^%Monorail | ^%Magnet" }, + { "Tyre and Wheel", "^%Tyre | %^Wheel | ^%Castle Wagon" }, + { "Vehicle", "^%Car | ^%Tractor | ^%Bike | ^%Plane | ^%Propellor | ^%Tail | ^%Landing | ^%Forklift | ^%Grab Jaw" }, + { "Windscreen", "^%Windscreen" }, + { "Wedge", "^%Wedge" }, + { "Wing", "^%Wing" }, + }; + const int NumCategories = sizeof(DefaultCategories)/sizeof(DefaultCategories[0]); + + mCategories.RemoveAll(); + for (int i = 0; i < NumCategories; i++) + { + lcLibraryCategory& Category = mCategories.Add(); + + Category.Name = DefaultCategories[i].Name; + Category.Keywords = DefaultCategories[i].Keywords; + } + + strcpy(mCategoriesFile, ""); + Sys_ProfileSaveString("Settings", "Categories", mCategoriesFile); + mCategoriesModified = false; +} + +bool lcPiecesLibrary::LoadCategories(const char* FileName) +{ + char Path[LC_MAXPATH]; + + if (FileName) + { + strcpy(Path, FileName); + } + else + { + LC_FILEOPENDLG_OPTS opts; + + opts.type = LC_FILEOPENDLG_LCF; + strcpy(opts.path, mCategoriesFile); + + if (!SystemDoDialog(LC_DLG_FILE_OPEN, &opts)) + return false; + + strcpy(Path, (char*)opts.filenames); + + free(opts.filenames); + } + + // Load the file. + lcDiskFile File; + + if (!File.Open(Path, "rb")) + return false; + + lcuint32 i; + + File.ReadU32(&i, 1); + if (i != LC_FILE_ID) + return false; + + File.ReadU32(&i, 1); + if (i != LC_CATEGORY_FILE_ID) + return false; + + File.ReadU32(&i, 1); + if (i != LC_CATEGORY_FILE_VERSION) + return false; + + mCategories.RemoveAll(); + + File.ReadU32(&i, 1); + while (i--) + { + lcLibraryCategory& Category = mCategories.Add(); + + File.ReadString(Category.Name); + File.ReadString(Category.Keywords); + } + + strcpy(mCategoriesFile, Path); + Sys_ProfileSaveString("Settings", "Categories", mCategoriesFile); + mCategoriesModified = false; + + return true; +} + +bool lcPiecesLibrary::SaveCategories() +{ + if (mCategoriesModified) + { + switch (SystemDoMessageBox("Save changes to categories?", LC_MB_YESNOCANCEL | LC_MB_ICONQUESTION)) + { + case LC_CANCEL: + return false; + + case LC_YES: + if (!DoSaveCategories(false)) + return false; + break; + + case LC_NO: + return true; + break; + } + } + + return true; +} + +bool lcPiecesLibrary::DoSaveCategories(bool AskName) +{ + // Get the file name. + if (AskName || (strlen(mCategoriesFile) == 0)) + { + LC_FILESAVEDLG_OPTS opts; + + opts.type = LC_FILESAVEDLG_LCF; + strcpy(opts.path, mCategoriesFile); + + if (!SystemDoDialog(LC_DLG_FILE_SAVE, &opts)) + return false; + + strcpy(mCategoriesFile, opts.path); + } + + // Save the file. + lcDiskFile File; + + if (!File.Open(mCategoriesFile, "wb")) + return false; + + File.WriteU32(LC_FILE_ID); + File.WriteU32(LC_CATEGORY_FILE_ID); + File.WriteU32(LC_CATEGORY_FILE_VERSION); + + int NumCategories = mCategories.GetSize(); + int i; + + for (i = 0; i < mCategories.GetSize(); i++) + { + if (mCategories[i].Name == "Search Results") + { + NumCategories--; + break; + } + } + + File.WriteU32(NumCategories); + for (i = 0; i < mCategories.GetSize(); i++) + { + if (mCategories[i].Name == "Search Results") + continue; + + File.WriteString(mCategories[i].Name); + File.WriteString(mCategories[i].Keywords); + } + + Sys_ProfileSaveString("Settings", "Categories", mCategoriesFile); + mCategoriesModified = false; + + return true; +} + +int lcPiecesLibrary::FindCategoryIndex(const String& CategoryName) const +{ + for (int i = 0; i < mCategories.GetSize(); i++) + if (mCategories[i].Name == CategoryName) + return i; + + return -1; +} + +void lcPiecesLibrary::SetCategory(int Index, const String& Name, const String& Keywords) +{ + mCategories[Index].Name = Name; + mCategories[Index].Keywords = Keywords; + + SystemUpdateCategories(true); + + mCategoriesModified = true; +} + +void lcPiecesLibrary::AddCategory(const String& Name, const String& Keywords) +{ + lcLibraryCategory& Category = mCategories.Add(); + + Category.Name = Name; + Category.Keywords = Keywords; + + SystemUpdateCategories(true); + + mCategoriesModified = true; +} + +void lcPiecesLibrary::RemoveCategory(int Index) +{ + mCategories.RemoveIndex(Index); + + mCategoriesModified = true; +} diff --git a/common/lc_library.h b/common/lc_library.h index a400c522..97f3aa61 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -3,10 +3,14 @@ #include "lc_mesh.h" #include "array.h" +#include "str.h" class PieceInfo; class lcZipFile; +#define LC_CATEGORY_FILE_ID LC_FOURCC('C', 'A', 'T', 0) +#define LC_CATEGORY_FILE_VERSION 0x0100 + class lcLibraryMeshSection { public: @@ -57,15 +61,39 @@ public: lcLibraryMeshData mMeshData; }; +struct lcLibraryCategory +{ + String Name; + String Keywords; +}; + class lcPiecesLibrary { public: lcPiecesLibrary(); ~lcPiecesLibrary(); + bool Load(const char* SearchPath); + + PieceInfo* FindPiece(const char* PieceName, bool CreatePlaceholderIfMissing); + PieceInfo* CreatePlaceholder(const char* PieceName); + + bool PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const; + int GetFirstPieceCategory(PieceInfo* Info) const; + void GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrArray& SinglePieces, PtrArray& GroupedPieces); + void GetPatternedPieces(PieceInfo* Parent, PtrArray& Pieces) const; + int FindCategoryIndex(const String& CategoryName) const; + void SetCategory(int Index, const String& Name, const String& Keywords); + void AddCategory(const String& Name, const String& Keywords); + void RemoveCategory(int Index); + void ResetCategories(); + bool LoadCategories(const char* FileName); + bool SaveCategories(); + bool DoSaveCategories(bool AskName); + + + bool OpenArchive(const char* FileName); - - bool LoadPiece(const char* PieceName); bool LoadPiece(int PieceIndex); int FindPrimitiveIndex(const char* Name); @@ -74,8 +102,14 @@ public: PtrArray mPieces; PtrArray mPrimitives; + ObjArray mCategories; + + char mLibraryPath[LC_MAXPATH]; protected: + bool mCategoriesModified; + char mCategoriesFile[LC_MAXPATH]; + lcZipFile* mZipFile; }; diff --git a/common/library.cpp b/common/library.cpp deleted file mode 100755 index 8b54b5db..00000000 --- a/common/library.cpp +++ /dev/null @@ -1,2795 +0,0 @@ -// -// Pieces library management -// - -#include "lc_global.h" -#include -#include "library.h" -#include "lc_colors.h" -#include "lc_file.h" -#include "texture.h" -#include "pieceinf.h" -#include "image.h" -#include "system.h" -#include "console.h" -#include "lc_application.h" - -// ============================================================================= -// PiecesLibrary class - -const char PiecesLibrary::PiecesBinHeader[32] = "LeoCAD piece library data file\0"; -const char PiecesLibrary::PiecesIdxHeader[32] = "LeoCAD piece library index file"; -const int PiecesLibrary::PiecesFileVersion = 5; -const char PiecesLibrary::TexturesBinHeader[32] = "LeoCAD texture data file\0\0\0\0\0\0\0"; -const char PiecesLibrary::TexturesIdxHeader[32] = "LeoCAD texture index file\0\0\0\0\0\0"; -const int PiecesLibrary::TexturesFileVersion = 1; - -PiecesLibrary::PiecesLibrary() -{ - strcpy(m_LibraryPath, ""); - strcpy(m_CategoriesFile, ""); - m_pMovedReference = NULL; - m_nMovedCount = 0; - m_pTextures = NULL; - m_nTextureCount = 0; - m_Modified = false; - m_CategoriesModified = false; -} - -PiecesLibrary::~PiecesLibrary() -{ - Unload(); -} - -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_pTextures; - m_pTextures = NULL; - m_nTextureCount = 0; -} - -void PiecesLibrary::SetPath(const char* LibPath) -{ - strcpy(m_LibraryPath, LibPath); - - // Make sure that the path ends with a '/' - int i = strlen(m_LibraryPath)-1; - if ((m_LibraryPath[i] != '\\') && (m_LibraryPath[i] != '/')) - strcat(m_LibraryPath, "/"); -} - -bool PiecesLibrary::Load(const char *libpath) -{ - lcDiskFile idx, bin; - char filename[LC_MAXPATH]; - lcuint16 count, movedcount; - lcuint32 binsize; -// Texture* pTexture; - int i; - - Unload(); - - SetPath(libpath); - - // Read the piece library index. - strcpy (filename, m_LibraryPath); - strcat (filename, "pieces.idx"); - - if (!idx.Open (filename, "rb")) - { - console.PrintError ("Cannot open Pieces Library file: %s.\n", filename); - return false; - } - - strcpy (filename, m_LibraryPath); - strcat (filename, "pieces.bin"); - - if (!bin.Open (filename, "rb")) - { - console.PrintError ("Cannot open Pieces Library file: %s.\n", filename); - return false; - } - - if (!ValidatePiecesFile (idx, bin)) - return false; - - idx.Seek(-(long)(2*sizeof(count)+sizeof(binsize)), SEEK_END); - idx.ReadU16(&movedcount, 1); - idx.ReadU32(&binsize, 1); - idx.ReadU16(&count, 1); - idx.Seek (34, SEEK_SET); - - // 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) - free(m_pMovedReference); - m_pMovedReference = (char*)malloc(LC_PIECE_NAME_LEN*2*movedcount); - memset (m_pMovedReference, 0, LC_PIECE_NAME_LEN*2*movedcount); - m_nMovedCount = movedcount; - - for (i = 0; i < movedcount; i++) - { - idx.ReadBuffer(&m_pMovedReference[i*LC_PIECE_NAME_LEN*2], LC_PIECE_NAME_LEN); - idx.ReadBuffer(&m_pMovedReference[i*LC_PIECE_NAME_LEN*2+LC_PIECE_NAME_LEN], LC_PIECE_NAME_LEN); - } - - idx.Close(); - bin.Close(); - - // Load groups configuration - const char* FileName = Sys_ProfileLoadString("Settings", "Categories", ""); - if (!strlen(FileName) || !LoadCategories(FileName)) - ResetCategories(); -/* - // Read the texture index. - strcpy(filename, m_LibraryPath); - strcat(filename, "textures.idx"); - - if (m_pTextures != NULL) - { - delete [] m_pTextures; - m_pTextures = NULL; - m_nTextureCount = 0; - } - - if (!idx.Open(filename, "rb")) - { - console.PrintError ("Cannot open Textures Library file: %s.\n", filename); - return false; - } - - strcpy(filename, m_LibraryPath); - strcat(filename, "textures.bin"); - - if (!bin.Open (filename, "rb")) - { - console.PrintError ("Cannot open Textures Library file: %s.\n", filename); - return false; - } - - if (!ValidateTexturesFile (idx, bin)) - return false; - - idx.Seek(-(long)(sizeof(count)+sizeof(binsize)), SEEK_END); - idx.ReadU32(&binsize, 1); - idx.ReadU16(&count, 1); - idx.Seek(34, SEEK_SET); - - m_pTextures = new Texture[count]; - m_nTextureCount = count; - memset(m_pTextures, 0, count * sizeof(Texture)); - - for (pTexture = m_pTextures; count--; pTexture++) - pTexture->LoadIndex(&idx); - - idx.Close(); - bin.Close(); - */ - SystemUpdateCategories(false); - - m_CategoriesModified = false; - m_Modified = false; - - Sys_ProfileSaveString("Settings", "PiecesLibrary", m_LibraryPath); - - return true; -} - -// Make sure the pieces library files are valid -bool PiecesLibrary::ValidatePiecesFile(lcFile& IdxFile, lcFile& BinFile) const -{ - lcuint32 binsize, IdxPos = IdxFile.GetPosition(), BinPos = BinFile.GetPosition(); - lcuint16 count, movedcount; - lcuint8 version, update; - char header[32]; - - IdxFile.Seek(-(long)(2*sizeof(count)+sizeof(binsize)), SEEK_END); - IdxFile.ReadU16(&movedcount, 1); - IdxFile.ReadU32(&binsize, 1); - IdxFile.ReadU16(&count, 1); - IdxFile.Seek(0, SEEK_SET); - IdxFile.ReadBuffer(header, 32); - IdxFile.ReadU8(&version, 1); - IdxFile.ReadU8(&update, 1); - IdxFile.Seek(IdxPos, SEEK_SET); - - if (memcmp (header, PiecesIdxHeader, 32) != 0) - { - console.PrintError ("Invalid Pieces Library file.\n"); - return false; - } - - if (version != PiecesFileVersion) - { - console.PrintError("Wrong version of the Pieces Library files.\n"); - return false; - } - - BinFile.Seek(0, SEEK_SET); - BinFile.ReadBuffer(header, 32); - BinFile.Seek(BinPos, SEEK_SET); - - if (memcmp (header, PiecesBinHeader, 32) != 0) - { - console.PrintError ("Invalid Pieces Library file.\n"); - return false; - } - - if (binsize != BinFile.GetLength ()) - { - console.PrintError ("Wrong size of the Pieces Library file.\n"); - return false; - } - - return true; -} - -// Make sure the textures library files are valid -bool PiecesLibrary::ValidateTexturesFile(lcFile& IdxFile, lcFile& BinFile) const -{ - lcuint32 binsize, IdxPos = IdxFile.GetPosition(), BinPos = BinFile.GetPosition(); - lcuint16 count; - lcuint8 version; - char header[32]; - - IdxFile.Seek(-(long)(sizeof(count)+sizeof(binsize)), SEEK_END); - IdxFile.ReadU32(&binsize, 1); - IdxFile.ReadU16(&count, 1); - IdxFile.Seek(0, SEEK_SET); - IdxFile.ReadBuffer(header, 32); - IdxFile.ReadU8(&version, 1); - IdxFile.Seek(IdxPos, SEEK_SET); - - if (memcmp (header, TexturesIdxHeader, 32) != 0) - { - console.PrintError ("Invalid Textures Library file.\n"); - return false; - } - - if (version != TexturesFileVersion) - { - console.PrintError ("Wrong version of the Textures Library files.\n"); - return false; - } - - BinFile.Seek(0, SEEK_SET); - BinFile.ReadBuffer(header, 32); - BinFile.Seek(BinPos, SEEK_SET); - - if (memcmp (header, TexturesBinHeader, 32) != 0) - { - console.PrintError ("Invalid Textures Library file.\n"); - return false; - } - - if (binsize != BinFile.GetLength ()) - { - console.PrintError ("Wrong size of the Textures Library files.\n"); - return false; - } - - 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 -{ - for (int PieceIdx = 0; PieceIdx < m_Pieces.GetSize(); PieceIdx++) - if (!strcmp(name, m_Pieces[PieceIdx]->m_strName)) - return m_Pieces[PieceIdx]; - - 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]; - return FindPieceInfo(tmp); - } - } - - return NULL; -} - -PieceInfo* PiecesLibrary::GetPieceInfo(int index) const -{ - if (index < 0 || index >= m_Pieces.GetSize()) - return NULL; - - return m_Pieces[index]; -} - -int PiecesLibrary::GetPieceIndex(PieceInfo *pInfo) const -{ - return m_Pieces.FindIndex(pInfo); -} - -Texture* PiecesLibrary::FindTexture(const char* name) const -{ - for (int i = 0; i < m_nTextureCount; i++) - if (!strcmp (name, m_pTextures[i].m_strName)) - return &m_pTextures[i]; - - return NULL; -} - -Texture* PiecesLibrary::GetTexture (int index) const -{ - return &m_pTextures[index]; -} - -// ============================================================================= -// Category functions. - -void PiecesLibrary::ResetCategories() -{ - struct CategoryEntry - { - const char* Name; - const char* Keywords; - }; - - // Animal, Antenna, Arch, Arm, Bar, Baseplate, Belville, Boat, Bracket, Brick, - // Car, Cone, Container, Conveyor, Crane, Cylinder, Door, Electric, Exhaust, - // Fence, Flag, Forklift, Freestyle, Garage, Gate, Glass, Grab, Hinge, Homemaker, - // Hose, Jack, Ladder, Lever, Magnet, Minifig, Minifig Accessory, Panel, Plane, - // Plant, Plate, Platform, Propellor, Rack, Roadsign, Rock, Scala, Slope, Staircase, - // Support, Tail, Tap, Technic, Tile, Tipper, Tractor, Trailer, Train, Turntable, - // Tyre, Wedge, Wheel, Winch, Window, Windscreen, Wing - CategoryEntry DefaultCategories[] = - { - { "Animal", "^%Animal" }, - { "Antenna", "^%Antenna" }, - { "Arch", "^%Arch" }, - { "Bar", "^%Bar" }, - { "Baseplate", "^%Baseplate | ^%Platform" }, - { "Boat", "^%Boat" }, - { "Brick", "^%Brick" }, - { "Container", "^%Container | ^%Box | ^Chest | ^%Storage | ^Mailbox" }, - { "Door and Window", "^%Door | ^%Window | ^%Glass | ^%Freestyle | ^%Gate | ^%Garage | ^%Roller" }, - { "Duplo", "^%Duplo | ^%Scala | ^%Belville" }, - { "Electric", "^%Electric | ^%Light | ^%Excavator | ^%Exhaust" }, - { "Hinge and Bracket", "^%Hinge | ^%Bracket | ^%Turntable" }, - { "Hose", "^%Hose" }, - { "Minifig", "^%Minifig" }, - { "Miscellaneous", "^%Arm | ^%Barrel | ^%Brush | ^%Cockpit | ^%Conveyor | ^%Crane | ^%Cupboard | ^%Fabuland | ^%Fence | ^%Homemaker | ^%Jack | ^%Ladder | ^%Rock | ^%Staircase | ^%Stretcher | ^%Tap | ^%Tipper | ^%Trailer | ^%Winch" }, - { "Panel", "^%Panel | ^%Castle Wall | ^%Castle Turret" }, - { "Plant", "^%Plant" }, - { "Plate", "^%Plate" }, - { "Round", "^%Cylinder | ^%Cone | ^%Dish | ^%Round" }, - { "Sign and Flag", "^%Flag | ^%Roadsign | ^%Streetlight | ^%Flagpost | ^%Lamppost | ^%Signpost" }, - { "Slope", "^%Slope" }, - { "Space", "^%Space" }, - { "Sticker", "^%Sticker" }, - { "Support", "^%Support" }, - { "Technic", "^%Technic | ^%Rack" }, - { "Tile", "^%Tile" }, - { "Train", "^%Train | ^%Monorail | ^%Magnet" }, - { "Tyre and Wheel", "^%Tyre | %^Wheel | ^%Castle Wagon" }, - { "Vehicle", "^%Car | ^%Tractor | ^%Bike | ^%Plane | ^%Propellor | ^%Tail | ^%Landing | ^%Forklift | ^%Grab Jaw" }, - { "Windscreen", "^%Windscreen" }, - { "Wedge", "^%Wedge" }, - { "Wing", "^%Wing" }, - }; - const int NumCategories = sizeof(DefaultCategories)/sizeof(DefaultCategories[0]); - - m_Categories.RemoveAll(); - for (int i = 0; i < NumCategories; i++) - { - PiecesLibraryCategory Cat; - - Cat.Name = DefaultCategories[i].Name; - Cat.Keywords = DefaultCategories[i].Keywords; - - m_Categories.Add(Cat); - } - - strcpy(m_CategoriesFile, ""); - Sys_ProfileSaveString("Settings", "Categories", m_CategoriesFile); - m_CategoriesModified = false; -} - -bool PiecesLibrary::LoadCategories(const char* FileName) -{ - char Path[LC_MAXPATH]; - - if (FileName) - { - strcpy(Path, FileName); - } - else - { - LC_FILEOPENDLG_OPTS opts; - - opts.type = LC_FILEOPENDLG_LCF; - strcpy(opts.path, m_CategoriesFile); - - if (!SystemDoDialog(LC_DLG_FILE_OPEN, &opts)) - return false; - - strcpy(Path, (char*)opts.filenames); - - free(opts.filenames); - } - - // Load the file. - lcDiskFile File; - - if (!File.Open(Path, "rb")) - return false; - - lcuint32 i; - - File.ReadU32(&i, 1); - if (i != LC_FILE_ID) - return false; - - File.ReadU32(&i, 1); - if (i != LC_CATEGORY_FILE_ID) - return false; - - File.ReadU32(&i, 1); - if (i != LC_CATEGORY_FILE_VERSION) - return false; - - m_Categories.RemoveAll(); - - File.ReadU32(&i, 1); - while (i--) - { - PiecesLibraryCategory Cat; - - File.ReadString(Cat.Name); - File.ReadString(Cat.Keywords); - - m_Categories.Add(Cat); - } - - strcpy(m_CategoriesFile, Path); - Sys_ProfileSaveString("Settings", "Categories", m_CategoriesFile); - m_CategoriesModified = false; - - return true; -} - -// Returns true if it's ok to continue. -bool PiecesLibrary::SaveCategories() -{ - if (m_CategoriesModified) - { - switch (SystemDoMessageBox("Save category changes ?", LC_MB_YESNOCANCEL|LC_MB_ICONQUESTION)) - { - case LC_CANCEL: - return false; - - case LC_YES: - if (!DoSaveCategories(false)) - return false; - break; - - case LC_NO: - return true; - break; - } - } - - return true; -} - -bool PiecesLibrary::DoSaveCategories(bool AskName) -{ - // Get the file name. - if (AskName || (strlen(m_CategoriesFile) == 0)) - { - LC_FILESAVEDLG_OPTS opts; - - opts.type = LC_FILESAVEDLG_LCF; - strcpy(opts.path, m_CategoriesFile); - - if (!SystemDoDialog(LC_DLG_FILE_SAVE, &opts)) - return false; - - strcpy(m_CategoriesFile, opts.path); - } - - // Save the file. - lcDiskFile File; - - if (!File.Open(m_CategoriesFile, "wb")) - return false; - - File.WriteU32(LC_FILE_ID); - File.WriteU32(LC_CATEGORY_FILE_ID); - File.WriteU32(LC_CATEGORY_FILE_VERSION); - - int NumCategories = m_Categories.GetSize(); - int i; - - for (i = 0; i < m_Categories.GetSize(); i++) - { - if (m_Categories[i].Name == "Search Results") - { - NumCategories--; - break; - } - } - - - File.WriteU32(NumCategories); - for (i = 0; i < m_Categories.GetSize(); i++) - { - if (m_Categories[i].Name == "Search Results") - continue; - - File.WriteString(m_Categories[i].Name); - File.WriteString(m_Categories[i].Keywords); - } - - Sys_ProfileSaveString("Settings", "Categories", m_CategoriesFile); - m_CategoriesModified = false; - - return true; -} - -// ============================================================================= - -// Check if the piece belongs to a category. -bool PiecesLibrary::PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const -{ - String PieceName = Info->m_strDescription; - PieceName.MakeLower(); - - String Keywords = CategoryKeywords; - Keywords.MakeLower(); - - return PieceName.Match(Keywords); -} - -int PiecesLibrary::GetFirstCategory(PieceInfo* Info) const -{ - for (int i = 0; i < m_Categories.GetSize(); i++) - if (PieceInCategory(Info, m_Categories[i].Keywords)) - return i; - - return -1; -} - -void PiecesLibrary::GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrArray& SinglePieces, PtrArray& GroupedPieces) const -{ - SinglePieces.RemoveAll(); - GroupedPieces.RemoveAll(); - - // Don't group entries in the search results category. - if (m_Categories[CategoryIndex].Name == "Search Results") - GroupPieces = false; - - for (int i = 0; i < m_Pieces.GetSize(); i++) - { - PieceInfo* Info = m_Pieces[i]; - - if (!PieceInCategory(Info, m_Categories[CategoryIndex].Keywords)) - continue; - - if (!GroupPieces) - { - SinglePieces.Add(Info); - continue; - } - - // Check if it's a patterned piece. - if (Info->IsPatterned()) - { - PieceInfo* Parent; - - // Find the parent of this patterned piece. - char ParentName[LC_PIECE_NAME_LEN]; - strcpy(ParentName, Info->m_strName); - *strchr(ParentName, 'P') = '\0'; - - Parent = FindPieceInfo(ParentName); - - if (Parent) - { - // Check if the parent was added as a single piece. - int Index = SinglePieces.FindIndex(Parent); - - if (Index != -1) - SinglePieces.RemoveIndex(Index); - - Index = GroupedPieces.FindIndex(Parent); - - if (Index == -1) - GroupedPieces.Add(Parent); - } - else - { - // Patterned pieces should have a parent but in case they don't just add them anyway. - SinglePieces.Add(Info); - } - } - else - { - // Check if this piece has already been added to this category by one of its children. - int Index = GroupedPieces.FindIndex(Info); - - if (Index == -1) - SinglePieces.Add(Info); - } - } -} - -void PiecesLibrary::GetPatternedPieces(PieceInfo* Parent, PtrArray& Pieces) const -{ - char Name[LC_PIECE_NAME_LEN]; - strcpy(Name, Parent->m_strName); - strcat(Name, "P"); - - Pieces.RemoveAll(); - - 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); - } - - // 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) -{ - m_Categories[Index].Name = Name; - m_Categories[Index].Keywords = Keywords; - - SystemUpdateCategories(true); - - m_CategoriesModified = true; -} - -void PiecesLibrary::AddCategory(const String& Name, const String& Keywords) -{ - PiecesLibraryCategory Cat; - - Cat.Name = Name; - Cat.Keywords = Keywords; - - m_Categories.Add(Cat); - - SystemUpdateCategories(true); - - m_CategoriesModified = true; -} - -void PiecesLibrary::RemoveCategory(int Index) -{ - m_Categories.RemoveIndex(Index); - - m_CategoriesModified = true; -} - -// ============================================================================= -// Pieces handling stuff - -bool PiecesLibrary::DeleteAllPieces() -{ - lcDiskFile BinFile, IdxFile; - char file1[LC_MAXPATH], file2[LC_MAXPATH]; - - strcpy(file1, m_LibraryPath); - strcat(file1, "pieces-b.old"); - remove(file1); - strcpy(file2, m_LibraryPath); - strcat(file2, "pieces.bin"); - rename(file2, file1); - - if (!BinFile.Open(file2, "wb")) - return false; - - BinFile.WriteBuffer(PiecesBinHeader, 32); - - strcpy(file1, m_LibraryPath); - strcat(file1, "pieces-i.old"); - remove(file1); - strcpy(file2, m_LibraryPath); - strcat(file2, "pieces.idx"); - rename(file2, file1); - - if (!IdxFile.Open(file2, "wb")) - return false; - - lcuint8 Version = PiecesFileVersion; - lcuint8 Update = 0; - - IdxFile.WriteBuffer(PiecesIdxHeader, 32); - IdxFile.WriteU8(&Version, 1); - IdxFile.WriteU8(&Update, 1); - - lcuint16 Moved = 0; - lcuint32 BinSize = 32; - lcuint16 Count = 0; - - IdxFile.WriteU16(&Moved, 1); - IdxFile.WriteU32(&BinSize, 1); - IdxFile.WriteU16(&Count, 1); - - m_Modified = true; - - return true; -} - -// Remove pieces from the library -bool PiecesLibrary::DeletePieces(PtrArray& Pieces) -{ - lcDiskFile newbin, newidx, oldbin, oldidx; - char file1[LC_MAXPATH], file2[LC_MAXPATH], tmp[200]; - lcuint16 count, deleted = 0, j; - void* membuf; - - 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(-2, SEEK_END); - oldidx.ReadU16(&count, 1); - oldidx.Seek(0, SEEK_SET); - oldidx.ReadBuffer(tmp, 34); - newidx.WriteBuffer(tmp, 34); - oldbin.ReadBuffer(tmp, 32); - newbin.WriteBuffer(tmp, 32); - -// CProgressDlg dlg("Deleting"); -// dlg.Create(this); -// dlg.SetRange (0, count); - - for (j = 0; j < count; j++) - { -// dlg.StepIt(); -// dlg.SetStatus(m_Parts[j].info->m_strDescription); - -// if (dlg.CheckCancelButton()) -// if (AfxMessageBox(IDS_CANCEL_PROMPT, MB_YESNO) == IDYES) -// break; - - char name[LC_PIECE_NAME_LEN]; - int i; - - oldidx.ReadBuffer(&name, LC_PIECE_NAME_LEN); - - for (i = 0; i < Pieces.GetSize(); i++) - if (strcmp(name, Pieces[i]) == 0) - break; - - if (i != Pieces.GetSize()) - { - oldidx.Seek(64+12+1+4+4+4, SEEK_CUR); - deleted++; - continue; - } - - newidx.WriteBuffer(name, LC_PIECE_NAME_LEN); - oldidx.ReadBuffer(tmp, 64+12+1+4); - newidx.WriteBuffer(tmp, 64+12+1+4); - - lcuint32 binoff = newbin.GetLength(), size; - newidx.WriteU32(&binoff, 1); - oldidx.ReadU32(&binoff, 1); - oldidx.ReadU32(&size, 1); - newidx.WriteU32(&size, 1); - - membuf = malloc(size); - oldbin.Seek(binoff, SEEK_SET); - oldbin.ReadBuffer(membuf, size); - newbin.WriteBuffer(membuf, size); - free(membuf); - } - - // list of moved pieces - lcuint16 moved, cs; - - oldidx.Seek(-(2+4+2), SEEK_END); - oldidx.ReadU16(&moved, 1); - cs = 2+(moved*16); - oldidx.Seek(-(long)cs, SEEK_CUR); - membuf = malloc(cs); - oldidx.ReadBuffer(membuf, cs); - newidx.WriteBuffer(membuf, cs); - free(membuf); - - // info at the end - lcuint32 binoff = newbin.GetPosition(); - newidx.WriteU32(&binoff, 1); - count -= deleted; - newidx.WriteU16(&count, 1); - - m_Modified = true; - - return true; -} - -// Load update -bool PiecesLibrary::LoadUpdate (const char* update) -{ - lcDiskFile newbin, newidx, oldbin, oldidx, up; - char file1[LC_MAXPATH], file2[LC_MAXPATH], tmp[200]; - lcuint16 changes, moved, count, i, j, newcount = 0; - lcuint32 cs, group, binoff; - lcuint8 bt; - void* membuf; - - struct LC_UPDATE_INFO - { - char Name[LC_PIECE_NAME_LEN]; - lcuint8 Type; - lcuint32 Offset; - }; - LC_UPDATE_INFO* upinfo; - - 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; - - if (!up.Open(update, "rb")) - return false; - - up.Seek(32, SEEK_SET); - up.ReadU8(&bt, 1); - if (bt != 2) - return false; // wrong version - - up.ReadU8(&bt, 1); // update number - - up.Seek(-2, SEEK_END); - up.ReadU16(&changes, 1); - up.Seek(34, SEEK_SET); - - oldidx.Seek(-2, SEEK_END); - oldidx.ReadU16(&count, 1); - oldidx.Seek(0, SEEK_SET); - oldidx.ReadBuffer(tmp, 34); - newidx.WriteBuffer(tmp, 33); // skip update byte - newidx.WriteU8(&bt, 1); - oldbin.ReadBuffer(tmp, 32); - newbin.WriteBuffer(tmp, 32); - - upinfo = (LC_UPDATE_INFO*)malloc(sizeof(LC_UPDATE_INFO)*changes); - memset(upinfo, 0, sizeof(LC_UPDATE_INFO)*changes); - - for (i = 0; i < changes; i++) - { - up.ReadBuffer(&upinfo[i].Name, 8); - up.ReadU8(&upinfo[i].Type, 1); - upinfo[i].Offset = up.GetPosition(); - - if ((upinfo[i].Type & LC_UPDATE_DESCRIPTION) || - (upinfo[i].Type & LC_UPDATE_NEWPIECE)) - up.Seek(64+4, SEEK_CUR); - - if ((upinfo[i].Type & LC_UPDATE_DRAWINFO) || - (upinfo[i].Type & LC_UPDATE_NEWPIECE)) - { - up.Seek(12+1, SEEK_CUR); - up.ReadU32(&cs, 1); - up.Seek(cs, SEEK_CUR); - } - } - -// CProgressDlg dlg(_T("Updating Library")); -// dlg.Create(this); -// dlg.SetRange (0, count); - - for (i = 0; i < count; i++) - { - char Name[LC_PIECE_NAME_LEN]; - oldidx.ReadBuffer(&Name, LC_PIECE_NAME_LEN); - -// dlg.StepIt(); -// if(dlg.CheckCancelButton()) -// if(AfxMessageBox(IDS_CANCEL_PROMPT, MB_YESNO) == IDYES) -// { -// free(upinfo); -// return TRUE; -// } - - for (j = 0; j < changes; j++) - { - if (strcmp(Name, upinfo[j].Name)) - continue; - - if (upinfo[j].Type == LC_UPDATE_DELETE) - { - oldidx.Seek(64+12+1+4+4+4, SEEK_CUR); - break; - } - - newcount++; - up.Seek(upinfo[j].Offset, SEEK_SET); - newidx.WriteBuffer(Name, LC_PIECE_NAME_LEN); - - // description - if (upinfo[j].Type & LC_UPDATE_DESCRIPTION) - { - up.ReadBuffer(&tmp, 64); - up.ReadBuffer(&group, 4); - oldidx.Seek(64, SEEK_CUR); - } - else - oldidx.ReadBuffer(&tmp, 64); - newidx.WriteBuffer(tmp, 64); -// dlg.SetStatus(tmp); - - // bounding box & flags - if (upinfo[j].Type & LC_UPDATE_DRAWINFO) - { - up.ReadBuffer(&tmp, 12+1); - oldidx.Seek(12+1, SEEK_CUR); - } - else - oldidx.ReadBuffer(&tmp, 12+1); - newidx.WriteBuffer(tmp, 12+1); - - // group - if (upinfo[j].Type & LC_UPDATE_DESCRIPTION) - oldidx.Seek(4, SEEK_CUR); - else - oldidx.ReadBuffer(&group, 4); - newidx.WriteBuffer(&group, 4); - - binoff = newbin.GetLength(); - newidx.WriteU32(&binoff, 1); - - if (upinfo[j].Type & LC_UPDATE_DRAWINFO) - { - up.ReadU32(&cs, 1); - oldidx.Seek(4+4, SEEK_CUR); - - membuf = malloc(cs); - up.ReadBuffer(membuf, cs); - newbin.WriteBuffer(membuf, cs); - free(membuf); - } - else - { - oldidx.ReadU32(&binoff, 1); - oldidx.ReadU32(&cs, 1); - - membuf = malloc(cs); - oldbin.Seek(binoff, SEEK_SET); - oldbin.ReadBuffer(membuf, cs); - newbin.WriteBuffer(membuf, cs); - free(membuf); - } - newidx.WriteU32(&cs, 1); - break; - } - - // not changed, just copy - if (j == changes) - { - newcount++; - newidx.WriteBuffer(Name, LC_PIECE_NAME_LEN); - oldidx.ReadBuffer(tmp, 64+12+1+4); - newidx.WriteBuffer(tmp, 64+12+1+4); - binoff = newbin.GetLength(); - newidx.WriteU32(&binoff, 1); - oldidx.ReadU32(&binoff, 1); - oldidx.ReadU32(&cs, 1); - newidx.WriteU32(&cs, 1); - -// tmp[64] = 0; -// dlg.SetStatus(tmp); - - membuf = malloc(cs); - oldbin.Seek(binoff, SEEK_SET); - oldbin.ReadBuffer(membuf, cs); - newbin.WriteBuffer(membuf, cs); - free(membuf); - } - } - - // now add new pieces - for (j = 0; j < changes; j++) - if (upinfo[j].Type == LC_UPDATE_NEWPIECE) - { - newcount++; - newidx.WriteBuffer(upinfo[j].Name, LC_PIECE_NAME_LEN); - up.Seek(upinfo[j].Offset, SEEK_SET); - up.ReadBuffer(&tmp, 64+12); - newidx.WriteBuffer(tmp, 64+12); - up.ReadBuffer(&group, 4); - up.ReadBuffer(&bt, 1); - newidx.WriteBuffer(&bt, 1); - newidx.WriteBuffer(&group, 4); - binoff = newbin.GetLength(); - newidx.WriteU32(&binoff, 1); - - up.ReadU32(&cs, 1); - membuf = malloc(cs); - up.ReadBuffer(membuf, cs); - newbin.WriteBuffer(membuf, cs); - up.WriteU32(&cs, 1); - newidx.WriteU32(&cs, 1); - free (membuf); - } - - up.Seek(-(2+2), SEEK_END); - up.ReadU16(&moved, 1); - cs = 2+moved*16; - up.Seek(-(long)(cs), SEEK_CUR); - membuf = malloc(cs); - up.ReadBuffer(membuf, cs); - newidx.WriteBuffer(membuf, cs); - free(membuf); - - binoff = newbin.GetLength(); - newidx.WriteU32(&binoff, 1); - newidx.WriteU16(&newcount, 1); - - free(upinfo); - - m_Modified = true; - - return true; -} - -// ============================================================================= -// Textures handling stuff - -bool PiecesLibrary::DeleteTextures (char** Names, int NumTextures) -{ - char file1[LC_MAXPATH], file2[LC_MAXPATH]; - lcDiskFile newbin, newidx, oldbin, oldidx; - lcuint32 binsize, offset = 0; - lcuint16 count, deleted = 0, i, j; - lcuint8 version, bt; - - // Backup files - strcpy(file1, m_LibraryPath); - strcat(file1, "tex-b.old"); - remove(file1); - strcpy(file2, m_LibraryPath); - strcat(file2, "textures.bin"); - rename(file2, file1); - - if ((!oldbin.Open(file1, "rb")) || (!newbin.Open(file2, "wb"))) - return false; - - strcpy(file1, m_LibraryPath); - strcat(file1, "tex-i.old"); - remove(file1); - strcpy(file2, m_LibraryPath); - strcat(file2, "textures.idx"); - rename(file2, file1); - - if ((!oldidx.Open(file1, "rb")) || (!newidx.Open(file2, "wb"))) - return false; - - // Write the headers - newidx.WriteBuffer(TexturesIdxHeader, sizeof (TexturesIdxHeader)); - bt = 1; // version - newidx.WriteU8(&bt, 1); - bt = 0; // last update (unused for now) - newidx.WriteU8(&bt, 1); - - newbin.WriteBuffer(TexturesBinHeader, sizeof (TexturesBinHeader)); - offset += sizeof(TexturesBinHeader); - - oldidx.Seek(-(long)(sizeof(count)+sizeof(binsize)), SEEK_END); - oldidx.ReadU32(&binsize, 1); - oldidx.ReadU16(&count, 1); - oldidx.Seek(32, SEEK_SET); - oldidx.ReadU8(&version, 1); - - if ((version != TexturesFileVersion) || (count == 0)) - return false; - - oldidx.Seek(34, SEEK_SET); // skip update byte - - for (i = 0; i < count; i++) - { - lcuint32 OldOffset, FileSize = 0; - lcuint16 Width, Height; - char TexName[9]; - TexName[8] = 0; - - oldidx.ReadBuffer(TexName, 8); - oldidx.ReadU16(&Width, 1); - oldidx.ReadU16(&Height, 1); - oldidx.ReadU8(&bt, 1); - - switch (bt) - { - case LC_INTENSITY: - FileSize = Width*Height; - break; - - case LC_RGB: - FileSize = Width*Height*3; - break; - - case LC_RGBA: - FileSize = Width*Height*4; - break; - } - - oldidx.ReadU32(&OldOffset, 1); - - for (j = 0; j < NumTextures; j++) - if (strcmp(TexName, Names[j]) == 0) - break; - - if (j != NumTextures) - { - deleted++; - continue; - } - - // Write index for this texture - newidx.WriteBuffer(TexName, 8); - newidx.WriteU16(&Width, 1); - newidx.WriteU16(&Height, 1); - newidx.WriteU8(&bt, 1); - newidx.WriteU32(&offset, 1); - - offset += FileSize; - - // Copy texture data - void *membuf = malloc(FileSize); - oldbin.Seek(OldOffset, SEEK_SET); - oldbin.ReadBuffer(membuf, FileSize); - newbin.WriteBuffer(membuf, FileSize); - free(membuf); - } - - newidx.WriteU32(&offset, 1); - count -= deleted; - newidx.WriteU16(&count, 1); - - m_Modified = true; - - return true; -} - -bool PiecesLibrary::ImportTexture(const char* Name) -{ - char file1[LC_MAXPATH], file2[LC_MAXPATH]; - lcDiskFile newbin, newidx, oldbin, oldidx; - lcuint32 FileSize = 0, binsize, offset = 0; - lcuint16 Width, Height, count, deleted = 0, i; - lcuint8 version, bt; - Image img; - - if (!img.FileLoad (Name)) - return false; - - // Backup files - strcpy(file1, m_LibraryPath); - strcat(file1, "tex-b.old"); - remove(file1); - strcpy(file2, m_LibraryPath); - strcat(file2, "textures.bin"); - rename(file2, file1); - - if ((!oldbin.Open(file1, "rb")) || (!newbin.Open(file2, "wb"))) - return false; - - strcpy(file1, m_LibraryPath); - strcat(file1, "tex-i.old"); - remove(file1); - strcpy(file2, m_LibraryPath); - strcat(file2, "textures.idx"); - rename(file2, file1); - - if ((!oldidx.Open(file1, "rb")) || (!newidx.Open(file2, "wb"))) - return false; - - // Get the file name - char* p, NewTexName[9]; - - strcpy(file1, Name); - p = strrchr(file1, '.'); - *p = 0; - p = strrchr(file1, '\\'); - if (!p) - p = strrchr(file1, '/'); - if (!p) - p = file1; - strupr(p); - p++; - - memset(NewTexName, 0, 9); - strcpy(NewTexName, p); - - if (FindTexture (NewTexName) != NULL) - Sys_MessageBox ("Texture already exists in the library !"); - - // Write the headers - newidx.WriteBuffer(TexturesIdxHeader, sizeof (TexturesIdxHeader)); - bt = 1; // version - newidx.WriteU8(&bt, 1); - bt = 0; // last update (unused for now) - newidx.WriteU8(&bt, 1); - - newbin.WriteBuffer(TexturesBinHeader, sizeof (TexturesBinHeader)); - offset += sizeof (TexturesBinHeader); - - oldidx.Seek(-(long)(sizeof(count)+sizeof(binsize)), SEEK_END); - oldidx.ReadU32(&binsize, 1); - oldidx.ReadU16(&count, 1); - oldidx.Seek(32, SEEK_SET); - oldidx.ReadU8(&version, 1); - - if (version != TexturesFileVersion) - return false; - - oldidx.Seek(34, SEEK_SET); // skip update byte - - for (i = 0; i < count; i++) - { - lcuint32 OldOffset; - lcuint16 Width, Height; - char TexName[9]; - TexName[8] = 0; - - oldidx.ReadBuffer(TexName, 8); - oldidx.ReadU16(&Width, 1); - oldidx.ReadU16(&Height, 1); - oldidx.ReadU8(&bt, 1); - - switch (bt) - { - case LC_INTENSITY: - FileSize = Width*Height; - break; - - case LC_RGB: - FileSize = Width*Height*3; - break; - - case LC_RGBA: - FileSize = Width*Height*4; - break; - } - - oldidx.ReadU32(&OldOffset, 1); - - if (strcmp(TexName, NewTexName) == 0) - { - deleted++; - continue; - } - - // Write index for this texture - newidx.WriteBuffer(TexName, 8); - newidx.WriteU16(&Width, 1); - newidx.WriteU16(&Height, 1); - newidx.WriteU8(&bt, 1); - newidx.WriteU32(&offset, 1); - - offset += FileSize; - - // Copy texture data - void *membuf = malloc (FileSize); - oldbin.Seek(OldOffset, SEEK_SET); - oldbin.ReadBuffer(membuf, FileSize); - newbin.WriteBuffer(membuf, FileSize); - free (membuf); - } - - // Save the new texture - Width = img.Width (); - Height = img.Height (); - count++; - - // TODO: The texture type should be an option when you choose the file but I'll leave it hardcoded for now. - if (!strcmp (NewTexName, "SYSFONT")) - { - lcuint8* buf = img.GetData(); - int w = img.Alpha () ? 4 : 3; - - for (i = 0; i < Width*Height; i++) - { - if (buf[i*w] > 0 || buf[i*w+1] > 0 || buf[i*w+2] > 0) - bt = 255; - else - bt = 0; - - newbin.WriteU8(&bt, 1); - } - - FileSize = Width*Height; - bt = LC_INTENSITY; - } - else - { - if (img.Alpha ()) - { - FileSize = Width*Height*4; - bt = LC_RGBA; - } - else - { - FileSize = Width*Height*3; - bt = LC_RGB; - } - - newbin.WriteBuffer(img.GetData(), FileSize); - } - - newidx.WriteBuffer(NewTexName, 8); - newidx.WriteU16(&Width, 1); - newidx.WriteU16(&Height, 1); - newidx.WriteU8(&bt, 1); - newidx.WriteU32(&offset, 1); - - offset += FileSize; - - newidx.WriteU32(&offset, 1); - count -= deleted; - newidx.WriteU16(&count, 1); - - m_Modified = true; - - return true; -} - -// ============================================================================= -// LDraw support - -bool PiecesLibrary::ImportLDrawPiece(const char* Filename, lcFile* NewIdxFile, lcFile* NewBinFile, lcFile* OldIdxFile, lcFile* OldBinFile) -{ - LC_LDRAW_PIECE piece; - - SystemDoWaitCursor(1); - - if (ReadLDrawPiece (Filename, &piece)) - { - char* Moved = strstr(piece.description, "~Moved to "); - if (Moved) - { - lcuint16 Count; - OldIdxFile->Seek(-(2+4+2), SEEK_END); - OldIdxFile->ReadU16(&Count, 1); - lcuint32 cs = Count * 2 * LC_PIECE_NAME_LEN; - OldIdxFile->Seek(-(long)(cs+2), SEEK_CUR); - - lcuint32 Length = OldIdxFile->GetPosition(); - void* Buffer = malloc(Length); - OldIdxFile->Seek(0, SEEK_SET); - OldIdxFile->ReadBuffer(Buffer, Length); - NewIdxFile->Seek(0, SEEK_SET); - NewIdxFile->WriteBuffer(Buffer, Length); - free(Buffer); - - Buffer = malloc(cs); - OldIdxFile->ReadBuffer(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->WriteBuffer(Reference, Count*2*LC_PIECE_NAME_LEN); - NewIdxFile->WriteU16(&Count, 1); - free(Buffer); - - Buffer = malloc(4+2); - OldIdxFile->Seek(-(4+2), SEEK_END); - OldIdxFile->ReadBuffer(Buffer, 4+2); - NewIdxFile->WriteBuffer(Buffer, 4+2); - free(Buffer); - - OldBinFile->Seek(0, SEEK_END); - Length = OldBinFile->GetPosition(); - Buffer = malloc(Length); - OldBinFile->Seek(0, SEEK_SET); - OldBinFile->ReadBuffer(Buffer, Length); - NewBinFile->Seek(0, SEEK_SET); - NewBinFile->WriteBuffer(Buffer, Length); - free(Buffer); - - // Delete existing piece. -// lcPtrArray 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->ReadBuffer(Buffer, Length); - NewBinFile->Seek(0, SEEK_SET); - NewBinFile->WriteBuffer(Buffer, Length); - free(Buffer); - - OldIdxFile->Seek(0, SEEK_END); - Length = OldIdxFile->GetPosition(); - Buffer = malloc(Length); - OldIdxFile->Seek(0, SEEK_SET); - OldIdxFile->ReadBuffer(Buffer, Length); - NewIdxFile->Seek(0, SEEK_SET); - NewIdxFile->WriteBuffer(Buffer, Length); - free(Buffer); - - fprintf(stderr, "Error reading file %s\n", Filename); - Sys_MessageBox ("Error reading file."); - } - - FreeLDrawPiece(&piece); - - SystemDoWaitCursor(-1); - - return true; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// ============================================================================= -// Stuff that needs to be reorganized - - -#include -#include -#include "globals.h" -#include "project.h" -#include "matrix.h" - - -// ============================================================================= -// LibraryDialog class - -static const char ver_str[32] = "LeoCAD Group Configuration File"; -static const float ver_flt = 0.3f; - - - - -// ======================================================== -// Import LDraw piece - -#define LC_MESH 1 -#define LC_STUD 2 -#define LC_STUD2 3 -#define LC_STUD3 4 -#define LC_STUD4 5 - -// stud, technic stud, stud under 1x? plate, stud under ?x? plate -static const char* valid[12] = { "stud.dat", "stud2.dat", "stud3.dat", "stud4.dat" }; -static const unsigned char numvalid = 4; - -static 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; -} - -static 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 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 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 float Dot3(float q1[], float q2[]) -{ - return q1[0]*q2[0]+q1[1]*q2[1]+q1[2]*q2[2]; -} - -static 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 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 void FixQuads(float quad[]) -{ - float t[4][3]; - memcpy(t, quad, sizeof(t)); - TestQuads(t); - memcpy(quad, t, sizeof(t)); -} - -static group_t* NewGroup(LC_LDRAW_PIECE* piece) -{ - group_t* group; - - if (piece->groups) - { - group = piece->groups; - while (group->next) - group = group->next; - group->next = (group_t*)malloc(sizeof(group_t)); - group = group->next; - } - else - { - group = piece->groups = (group_t*)malloc(sizeof(group_t)); - } - - memset(group, 0, sizeof(group_t)); - - return group; -} - -static connection_t* AddConnection(connection_t* newcon, LC_LDRAW_PIECE* piece) -{ - connection_t* con; - - con = piece->connections; - while (con) - { - if ((con->type == newcon->type) && - FloatPointsClose(con->pos, newcon->pos) && - FloatPointsClose(con->up, newcon->up)) - { - free(newcon); - return con; - } - - con = con->next; - } - - if (piece->connections) - { - con = piece->connections; - while (con->next) - con = con->next; - con->next = newcon; - } - else - { - piece->connections = newcon; - newcon->next = NULL; - } - - return newcon; -} - -struct ColorGroup -{ - lcuint32 Color; - lineinfo_t* Prims[3]; - lineinfo_t* LastPrims[3]; - lcuint32 NumPrims[3]; -}; - -int ColorGroupCompare(const ColorGroup& a, const ColorGroup& b, void* data) -{ - if (a.Color == b.Color) - return 0; - - if (a.Color == 16) - return -1; - - if (b.Color == 16) - return 1; - - return a.Color > b.Color ? 1 : -1; -} - -static void CreateMesh(group_t* pGroup, lineinfo_t* info, LC_LDRAW_PIECE* piece) -{ - lcuint32 NumPrims[3] = { 0, 0, 0 }; - lcuint32 NumIndices = 0; - ObjArray ColorGroups; - - lineinfo_t* Line = info->next; - - while (Line) - { - ColorGroup* Group = NULL; - - for (int GroupIdx = 0; GroupIdx < ColorGroups.GetSize(); GroupIdx++) - { - if (ColorGroups[GroupIdx].Color != Line->color) - continue; - - Group = &ColorGroups[GroupIdx]; - break; - } - - if (!Group) - { - ColorGroup NewEntry; - - memset(&NewEntry, 0, sizeof(NewEntry)); - NewEntry.Color = Line->color; - - ColorGroups.AddSorted(NewEntry, ColorGroupCompare, NULL); - continue; - } - - lineinfo_t* NextLine = Line->next; - Line->next = NULL; - int Type = Line->type - 2; - - if (Group->Prims[Type]) - Group->LastPrims[Type]->next = Line; - else - Group->Prims[Type] = Line; - - Group->LastPrims[Type] = Line; - Group->NumPrims[Type] += Line->type; - - NumPrims[Type] += Line->type; - NumIndices += Line->type; - - Line = NextLine; - } - - if (piece->verts_count > 65535 || NumPrims[0] > 65535 || NumPrims[1] > 65535 || NumPrims[2] > 65535) - { - piece->long_info = true; - pGroup->infosize = sizeof(lcuint32) * (ColorGroups.GetSize() + 2 + 1) + sizeof(lcuint32) * (NumIndices + 3 * ColorGroups.GetSize()); - } - else - { - piece->long_info = false; - pGroup->infosize = sizeof(lcuint32) * (ColorGroups.GetSize() + 2 + 1) + sizeof(lcuint16) * (NumIndices + 3 * ColorGroups.GetSize()); - } - - pGroup->drawinfo = malloc(pGroup->infosize); - lcuint32* drawinfo = (lcuint32*)pGroup->drawinfo; - *drawinfo++ = LC_MESH; - *drawinfo++ = ColorGroups.GetSize(); - - if (piece->long_info) - { - for (int EntryIdx = 0; EntryIdx < ColorGroups.GetSize(); EntryIdx++) - { - ColorGroup* Group = &ColorGroups[EntryIdx]; - *drawinfo++ = Group->Color; - - for (int PrimIdx = 2; PrimIdx >= 0; PrimIdx--) - { - lcuint32* indices = (lcuint32*)drawinfo; - *indices++ = Group->NumPrims[PrimIdx]; - - lineinfo_t* Line = Group->Prims[PrimIdx]; - while (Line) - { - for (int Idx = 0; Idx < Line->type; Idx++) - *indices++ = Line->indices[Idx]; - - lineinfo_t* NextLine = Line->next; - free(Line); - Line = NextLine; - } - - drawinfo = (lcuint32*)indices; - } - } - - *drawinfo++ = 0; - } - else - { - for (int EntryIdx = 0; EntryIdx < ColorGroups.GetSize(); EntryIdx++) - { - ColorGroup* Group = &ColorGroups[EntryIdx]; - *drawinfo++ = Group->Color; - - for (int PrimIdx = 2; PrimIdx >= 0; PrimIdx--) - { - lcuint16* indices = (lcuint16*)drawinfo; - *indices++ = Group->NumPrims[PrimIdx]; - - lineinfo_t* Line = Group->Prims[PrimIdx]; - while (Line) - { - for (int Idx = 0; Idx < Line->type; Idx++) - *indices++ = Line->indices[Idx]; - - lineinfo_t* NextLine = Line->next; - free(Line); - Line = NextLine; - } - - drawinfo = (lcuint32*)indices; - } - } - - *drawinfo++ = 0; - } -} - -static void DecodeFile(FILE *F, Matrix *mat, lcuint32 CurColor, lineinfo_t* info, char* dir, LC_LDRAW_PIECE* piece) -{ - char buf[1024], fn[LC_MAXPATH], filename[LC_MAXPATH]; - lcuint32 ColorCode, ColorCodeHex; - int Dummy; - unsigned char val; - int type; - float fm[12]; - 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; - - if (sscanf(buf, "%d", &type) != 1) - continue; - - if (type < 1 || type > 4) - continue; - - if (sscanf(buf, "%d %d", &type, &ColorCode) != 2) - continue; - - if (ColorCode == 0) - { - sscanf(buf, "%d %i", &type, &ColorCodeHex); - - if (ColorCode != ColorCodeHex) - ColorCode = ColorCodeHex | LC_COLOR_DIRECT; - } - - if (ColorCode == 16) - ColorCode = CurColor; - - if (type >= 2 && type <= 4) - { - lineinfo_t* newinfo = (lineinfo_t*)malloc(sizeof(lineinfo_t)); - info->next = newinfo; - newinfo->next = 0; - newinfo->type = type; - newinfo->color = ColorCode; - info = newinfo; - } - - switch (type) - { - case 1: - { - sscanf (buf, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f %s", - &type, &Dummy, &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); - - strlwr(filename); - - for (unsigned int i = 0; i < strlen(filename); i++) - if (filename[i] == '\\') - filename[i] = '/'; - - for (val = 0; val < numvalid; val++) - if (strcmp(filename, valid[val]) == 0) - break; - - if (val != numvalid) - break; - - strcpy(fn, dir); - strcat(fn, "p/"); - strcat(fn, filename); - - 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; - m1.FromLDraw(fm); - m2.Multiply(*mat, m1); - - DecodeFile(tf, &m2, ColorCode, info, dir, piece); - while (info->next) - info = info->next; - fclose(tf); - } - else - printf("Could not find file \"%s\".\n", filename); - - } break; - - case 2: - { - sscanf (buf, "%d %i %f %f %f %f %f %f", &type, &Dummy, - &info->points[0], &info->points[1], &info->points[2], - &info->points[3], &info->points[4], &info->points[5]); - ConvertPoints(info->points, 2); - mat->TransformPoints(info->points, 2); - } break; - - case 3: - { - sscanf (buf, "%d %i %f %f %f %f %f %f %f %f %f", &type, &Dummy, - &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]); - ConvertPoints(info->points, 3); - mat->TransformPoints(info->points, 3); - } break; - - case 4: - { - sscanf (buf, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f", &type, &Dummy, - &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]); - ConvertPoints(info->points, 4); - mat->TransformPoints(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)); - } -} - -static void decodeconnections(FILE *F, Matrix *mat, lcuint32 CurColor, char* dir, LC_LDRAW_PIECE* piece) -{ - char buf[1024], fn[LC_MAXPATH], filename[32]; - float fm[12], *floats; - int type, Dummy; - group_t* group; - connection_t* con; - Matrix m1, m2; - FILE *tf; - lcuint32 ColorCode, ColorCodeHex; - - 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; - } - - if (sscanf(buf, "%d %d", &type, &ColorCode) != 2) - continue; - - if (ColorCode == 0) - { - sscanf(buf, "%d %i", &type, &ColorCodeHex); - - if (ColorCode != ColorCodeHex) - ColorCode = ColorCodeHex | LC_COLOR_DIRECT; - } - - if (ColorCode == 16) - ColorCode = CurColor; - - sscanf (buf, "%d %i %f %f %f %f %f %f %f %f %f %f %f %f %s", - &type, &Dummy, &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); - - strlwr(filename); - - int val; - for (val = 0; val < numvalid; val++) - if (!strcmp(filename, valid[val])) - break; - - if (val != numvalid) - { - m1.LoadIdentity(); - m2.LoadIdentity(); - m1.FromLDraw(fm); - m2.Multiply(*mat, m1); - - if (val == 0) // STUD.DAT - { - group = NewGroup(piece); - con = (connection_t*)malloc(sizeof(connection_t)); - memset(con, 0, sizeof(connection_t)); - - group->infosize = 3*sizeof(lcuint32) + 12*sizeof(float); - group->drawinfo = malloc(group->infosize); - lcuint32* info = (lcuint32*)group->drawinfo; - floats = (float*)(info+2); - - info[0] = LC_STUD; - info[1] = ColorCode; - 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]; - info[14] = 0; - - con->type = 0; // stud - con->pos[0] = m2.m[12]; - con->pos[1] = m2.m[13]; - con->pos[2] = m2.m[14]; - con->up[2] = 1; - m2.TransformPoints(con->up, 1); - con->up[0] -= m2.m[12]; - con->up[1] -= m2.m[13]; - con->up[2] -= m2.m[14]; - - con = AddConnection(con, piece); - group->connections[0] = con; - } - else if (val == 1) // STUD2.DAT - { - group = NewGroup(piece); - con = (connection_t*)malloc(sizeof(connection_t)); - memset(con, 0, sizeof(connection_t)); - - group->infosize = 3*sizeof(lcuint32) + 12*sizeof(float); - group->drawinfo = malloc(group->infosize); - lcuint32* info = (lcuint32*)group->drawinfo; - floats = (float*)(info+2); - - info[0] = LC_STUD2; - info[1] = ColorCode; - 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]; - info[14] = 0; - - con->type = 0; // stud - con->pos[0] = m2.m[12]; - con->pos[1] = m2.m[13]; - con->pos[2] = m2.m[14]; - con->up[2] = 1; - m2.TransformPoints(con->up, 1); - con->up[0] -= m2.m[12]; - con->up[1] -= m2.m[13]; - con->up[2] -= m2.m[14]; - - con = AddConnection(con, piece); - group->connections[0] = con; - } - else if (val == 2) // STUD3.DAT - { - group = NewGroup(piece); - group->infosize = 3*sizeof(lcuint32) + 12*sizeof(float); - group->drawinfo = malloc(group->infosize); - lcuint32* info = (lcuint32*)group->drawinfo; - floats = (float*)(info+2); - - info[0] = LC_STUD3; - info[1] = ColorCode; - 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]; - info[14] = 0; - } - else 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; - - group = NewGroup(piece); - group->infosize = 3*sizeof(lcuint32) + 12*sizeof(float); - group->drawinfo = malloc(group->infosize); - lcuint32* info = (lcuint32*)group->drawinfo; - floats = (float*)(info+2); - - info[0] = LC_STUD4; - info[1] = ColorCode; - 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]; - info[14] = 0; - - for (c = 0; c < 4; c++) - { - con = (connection_t*)malloc(sizeof(connection_t)); - memset(con, 0, sizeof(connection_t)); - con->type = 1; // inv stud - m2.TransformPoint(con->pos, t[c]); - con->pos[2] -= 0.16f; - - con->up[2] = 1; - m2.TransformPoints(con->up, 1); - con->up[0] -= m2.m[12]; - con->up[1] -= m2.m[13]; - con->up[2] -= m2.m[14]; - - group->connections[c] = AddConnection(con, piece); - } - - con = (connection_t*)malloc(sizeof(connection_t)); - memset(con, 0, sizeof(connection_t)); - con->type = 1; // inv stud - con->pos[2] -= 0.16f; - - con->up[2] = 1; - m2.TransformPoints(con->up, 1); - con->up[0] -= m2.m[12]; - con->up[1] -= m2.m[13]; - con->up[2] -= m2.m[14]; - - AddConnection(con, piece); - } - - memset(buf, 0, sizeof(buf)); - continue; - } - - for (unsigned int i = 0; i < strlen(filename); i++) - if (filename[i] == '\\') - filename[i] = '/'; - - strcpy(fn, dir); - strcat(fn, "p/"); - strcat(fn, filename); - - 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) - { - m1.LoadIdentity(); - m2.LoadIdentity(); - m1.FromLDraw(fm); - m2.Multiply(*mat, m1); - - decodeconnections(tf, &m2, ColorCode, dir, piece); - fclose(tf); - } - else - printf("Could not find file \"%s\".\n", filename); - - memset(buf, 0, sizeof(buf)); - } -} - -bool ReadLDrawPiece(const char* filename, LC_LDRAW_PIECE* piece) -{ - lcuint32 unique; - char tmp[LC_MAXPATH], *ptr; - lineinfo_t info, *lf; - float* verts; - Matrix mat; - FILE *f; - - memset(piece, 0, sizeof(LC_LDRAW_PIECE)); - info.next = 0; - info.type = 0; - - // First we read the name and description - strcpy(tmp, filename); - ptr = strrchr(tmp, '.'); - if (ptr != NULL) - *ptr = 0; - ptr = strrchr(tmp, '\\'); - if (ptr == NULL) - ptr = strrchr(tmp, '/'); - - if (ptr == NULL) - ptr = tmp; - else - ptr++; - - memset(piece->name, 0, sizeof(piece->name)); - strcpy(piece->name, ptr); - strupr(piece->name); - - f = fopen(filename, "rt"); - if (f == NULL) - return false; - - 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(piece->description, tmp+2); - } - - // Get LDraw directory, piece must be /ldraw/pieces/foo.dat - strcpy(tmp, filename); - ptr = strrchr(tmp, '\\'); - if (ptr == NULL) - ptr = strrchr(tmp, '/'); - *ptr = 0; - ptr = strrchr(tmp, '\\'); - if (ptr == NULL) - ptr = strrchr(tmp, '/'); - *(ptr+1) = 0; - - DecodeFile(f, &mat, 16, &info, tmp, piece); - fclose (f); - - // Create array of unique vertices - verts = (float*)malloc(sizeof(float)*1500); - unique = 0; - - for (lf = info.next; lf; lf = lf->next) - { - for (int j = 0; j < lf->type; j++) - { - int i; - for (i = unique-1; i != -1; i--) - if (FloatPointsClose(&verts[i*3], &lf->points[j*3])) - break; - - if (i == -1) - { - if ((unique % 500) == 0) - verts = (float*)realloc(verts, sizeof(float)*3*(unique+500)); - memcpy(&verts[unique*3], &lf->points[j*3], sizeof(float)*3); - i = unique; - unique++; - } - - lf->indices[j] = i; - } - } - - piece->verts = verts; - piece->long_info = false; - piece->verts_count = unique; - - // Main group - piece->groups = (group_t*)malloc(sizeof(group_t)); - memset(piece->groups, 0, sizeof(group_t)); - CreateMesh(piece->groups, &info, piece); - - // Included files - f = fopen (filename, "rt"); - mat.LoadIdentity(); - decodeconnections(f, &mat, 16, tmp, piece); - fclose(f); - - return true; -} - -bool SaveLDrawPiece(LC_LDRAW_PIECE* piece, lcFile* NewIdxFile, lcFile* NewBinFile, lcFile* OldIdxFile, lcFile* OldBinFile) -{ - lcuint16 count, moved; - lcuint32 i, j, cs, binoff = 0, delta; - void* membuf; - lcuint16 scale, sb[6]; - - lcFile& NewIdx = *NewIdxFile; - lcFile& NewBin = *NewBinFile; - lcFile& OldIdx = *OldIdxFile; - lcFile& OldBin = *OldBinFile; - - OldIdx.Seek(0, SEEK_SET); - OldBin.Seek(0, SEEK_SET); - - OldIdx.Seek(-2, SEEK_END); - OldIdx.ReadU16(&count, 1); - OldIdx.Seek(34, SEEK_SET); - - for (j = 0; j < count; j++) - { - char name[LC_PIECE_NAME_LEN]; - OldIdx.ReadBuffer(name, LC_PIECE_NAME_LEN); - - if (strcmp(name, piece->name) == 0) - { - OldIdx.Seek(64+12+1+4, SEEK_CUR); - OldIdx.ReadU32(&binoff, 1); - OldIdx.ReadU32(&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); - } - - if (binoff == 0) - binoff = OldBin.GetLength(); - - cs = OldIdx.GetPosition(); - membuf = malloc(cs); - if (membuf == NULL) - { - SystemDoMessageBox("Not Enough Memory !", LC_MB_OK|LC_MB_ICONWARNING); - return false; - } - - OldIdx.Seek(0, SEEK_SET); - OldIdx.ReadBuffer(membuf, cs); - NewIdx.WriteBuffer(membuf, cs); - free(membuf); - - membuf = malloc (binoff); - if (membuf == NULL) - { - SystemDoMessageBox("Not Enough Memory !", LC_MB_OK|LC_MB_ICONWARNING); - return false; - } - - OldBin.Seek(0, SEEK_SET); - OldBin.ReadBuffer(membuf, binoff); - NewBin.WriteBuffer(membuf, binoff); - free(membuf); - - // Save piece - float maxdim, box[6] = { -100, -100, -100, 100, 100, 100 }; - unsigned short s; - unsigned char bt; - connection_t* con; - group_t* group; - Matrix mat; - - // First we calculate the bounding box - group = piece->groups; - while (group) - { - lcuint32* info = (lcuint32*)group->drawinfo; - float* floats; - - while (*info) - { - if (*info == LC_MESH) - { - info++; - lcuint32 colors = *info; - info++; - - while (colors--) - { - info++; - - if (piece->long_info) - { - lcuint32* indices = (lcuint32*)info; - - indices += *indices + 1; - indices += *indices + 1; - indices += *indices + 1; - - info = (lcuint32*)indices; - } - else - { - lcuint16* indices = (lcuint16*)info; - - indices += *indices + 1; - indices += *indices + 1; - indices += *indices + 1; - - info = (lcuint32*)indices; - } - } - } - else if ((*info == LC_STUD) || (*info == LC_STUD2)) - { - float stud[6] = { 0.16f, 0.16f, 0.16f, -0.16f, -0.16f, 0 }; - floats = (float*)(info + 2); - - mat.LoadIdentity(); - 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]; - mat.TransformPoints(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]; - } - - info += 2 + 12; - } - else if ((*info == LC_STUD4) || (*info == LC_STUD3)) - info += 2 + 12; - } - - group = group->next; - } - - for (i = 0; i < piece->verts_count; i++) - { - if (piece->verts[(3*i)] > box[0]) box[0] = piece->verts[(3*i)]; - if (piece->verts[(3*i)+1] > box[1]) box[1] = piece->verts[(3*i)+1]; - if (piece->verts[(3*i)+2] > box[2]) box[2] = piece->verts[(3*i)+2]; - if (piece->verts[(3*i)] < box[3]) box[3] = piece->verts[(3*i)]; - if (piece->verts[(3*i)+1] < box[4]) box[4] = piece->verts[(3*i)+1]; - if (piece->verts[(3*i)+2] < box[5]) box[5] = piece->verts[(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 - NewBin.WriteU32(&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] }; - lcint16 sh[3] = { (short)tmp[0], (short)tmp[1], (short)tmp[2] }; - NewBin.WriteS16(sh, 3); - } - - // Write the connections information - for (s = 0, con = piece->connections; con; con = con->next) - s++; - NewBin.WriteU16(&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.WriteU8(&con->type, 1); - NewBin.WriteS16(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.WriteS16(sh, 3); - } - - // Textures - bt = 0; - NewBin.WriteU8(&bt, 1); - - for (s = 0, group = piece->groups; group; group = group->next) - s++; - NewBin.WriteU16(&s, 1); - - for (group = piece->groups; group; group = group->next) - { - for (bt = 0; bt < 5; bt++) - if (!group->connections[bt]) - break; - NewBin.WriteU8(&bt, 1); - - for (bt = 0; bt < 5; bt++) - { - if (!group->connections[bt]) - break; - - for (s = 0, con = piece->connections; con; con = con->next, s++) - if (con == group->connections[bt]) - break; - NewBin.WriteU16(&s, 1); - } -// TODO: make this endian-safe - NewBin.WriteBuffer(group->drawinfo, group->infosize); - } - - // Now write the index - NewIdx.WriteBuffer(piece->name, LC_PIECE_NAME_LEN); - NewIdx.WriteBuffer(piece->description, 64); - - 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; - } - NewIdx.WriteU16(sb, 6); - - // Calculate flags. - bt = LC_PIECE_COUNT; - - if (scale == 10000) - bt |= LC_PIECE_SMALL; - else if (scale == 1000) - bt |= LC_PIECE_MEDIUM; - - if (piece->long_info) - bt |= LC_PIECE_LONGDATA_FILE; - - NewIdx.WriteU8(&bt, 1); - - i = 0;//PiecesLibrary::GetDefaultPieceGroup(piece->description); - NewIdx.WriteU32(&i, 1); - NewIdx.WriteU32(&binoff, 1); - - i = NewBin.GetLength() - binoff; - NewIdx.WriteU32(&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); - for (j++; j < count; j++) - { - lcuint32 dw; - char buf[LC_PIECE_NAME_LEN+64+12+1+4]; - OldIdx.ReadBuffer(buf, LC_PIECE_NAME_LEN+64+12+1+4); - OldIdx.ReadU32(&dw, 1); - dw += d; - NewIdx.WriteBuffer(buf, LC_PIECE_NAME_LEN+64+12+1+4); - NewIdx.WriteU32(&dw, 1); - OldIdx.ReadU32(&dw, 1); - NewIdx.WriteU32(&dw, 1); - } - - d = OldBin.GetLength()-delta; - membuf = malloc (d); - OldBin.Seek(delta, SEEK_SET); - OldBin.ReadBuffer(membuf, d); - NewBin.WriteBuffer(membuf, d); - free(membuf); - } - else - count++; - - // Fix the end of the index - OldIdx.Seek(-(2+4+2), SEEK_END); - OldIdx.ReadU16(&moved, 1); - cs = 2+(moved*LC_PIECE_NAME_LEN*2); - OldIdx.Seek(-(long)cs, SEEK_CUR); - membuf = malloc(cs); - OldIdx.ReadBuffer(membuf, cs); - NewIdx.WriteBuffer(membuf, cs); - free(membuf); - - binoff = NewBin.GetPosition(); - NewIdx.WriteU32(&binoff, 1); - NewIdx.WriteU16(&count, 1); - - return true; -} - -void FreeLDrawPiece(LC_LDRAW_PIECE* piece) -{ - group_t *tmp, *pg = piece->groups; - connection_t *ctmp, *pc = piece->connections; - - free(piece->verts); - - while (pg != NULL) - { - free (pg->drawinfo); - tmp = pg; - pg = pg->next; - free (tmp); - } - - while (pc != NULL) - { - ctmp = pc; - pc = pc->next; - free (ctmp); - } -} - -// ======================================================== - diff --git a/common/library.h b/common/library.h deleted file mode 100755 index e0448960..00000000 --- a/common/library.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef _LIBRARY_H_ -#define _LIBRARY_H_ - -#include "str.h" -#include "array.h" - -class Texture; -class PieceInfo; - -#define LC_CATEGORY_FILE_ID LC_FOURCC('C', 'A', 'T', 0) -#define LC_CATEGORY_FILE_VERSION 0x0100 - -struct PiecesLibraryCategory -{ - String Name; - String Keywords; -}; - -class PiecesLibrary -{ -public: - PiecesLibrary(); - ~PiecesLibrary(); - - const char* GetLibraryPath() const - { - 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; - int GetFirstCategory(PieceInfo* Info) const; - void GetCategoryEntries(int CategoryIndex, bool GroupPieces, PtrArray& SinglePieces, PtrArray& GroupedPieces) const; - void GetPatternedPieces(PieceInfo* Parent, PtrArray& Pieces) const; - void SetCategory(int Index, const String& Name, const String& Keywords); - void AddCategory(const String& Name, const String& Keywords); - void RemoveCategory(int Index); - void ResetCategories(); - bool SaveCategories(); - bool DoSaveCategories(bool AskName); - bool LoadCategories(const char* FileName); - - const String& GetCategoryName(int Index) const - { return m_Categories[Index].Name; } - - const String& GetCategoryKeywords(int Index) const - { return m_Categories[Index].Keywords; } - - int GetNumCategories() const - { return m_Categories.GetSize(); } - - int FindCategoryIndex(const String& CategoryName) const - { - for (int i = 0; i < m_Categories.GetSize(); i++) - if (m_Categories[i].Name == CategoryName) - return i; - - return -1; - } - - bool Load(const char* libpath); - void Unload(); - void SetPath(const char* LibPath); - - // Search for pieces. - PieceInfo* FindPieceInfo(const char* name) const; - PieceInfo* GetPieceInfo(int index) const; - int GetPieceIndex(PieceInfo *pInfo) const; - Texture* FindTexture(const char* name) const; - Texture* GetTexture(int index) const; - - PieceInfo* CreatePiecePlaceholder(const char* Name); - - // File operations. - bool DeleteAllPieces(); - bool DeletePieces(PtrArray& Pieces); - bool LoadUpdate(const char* update); - bool DeleteTextures(char** Names, int NumTextures); - bool ImportTexture(const char* Name); - bool ImportLDrawPiece(const char* Filename, lcFile* NewIdxFile, lcFile* NewBinFile, lcFile* OldIdxFile, lcFile* OldBinFile); - - // Set when pieces are added/removed from the library. - bool m_Modified; - -protected: - PtrArray m_Pieces; - - char m_LibraryPath[LC_MAXPATH]; // path to the library files - - int m_nMovedCount; // number of moved pieces - char* m_pMovedReference; // moved pieces list - int m_nTextureCount; // number of textures - Texture* m_pTextures; // textures array - - // Categories. - ObjArray m_Categories; - - bool m_CategoriesModified; - char m_CategoriesFile[LC_MAXPATH]; - - bool ValidatePiecesFile(lcFile& IdxFile, lcFile& BinFile) const; - bool ValidateTexturesFile(lcFile& IdxFile, lcFile& BinFile) const; - - // File headers - static const char PiecesBinHeader[32]; - static const char PiecesIdxHeader[32]; - static const int PiecesFileVersion; - static const char TexturesBinHeader[32]; - static const char TexturesIdxHeader[32]; - static const int TexturesFileVersion; -}; - - - - -// ============================================================================ - -// This should be cleaned and moved to the PiecesLibrary class -struct connection_t -{ - unsigned char type; - float pos[3]; - float up[3]; - connection_t* next; -}; - -struct group_t -{ - connection_t* connections[5]; - void* drawinfo; - unsigned long infosize; - group_t* next; -}; - -struct lineinfo_t -{ - int type; - lcuint32 color; - float points[12]; - int indices[4]; - lineinfo_t* next; -}; - -struct LC_LDRAW_PIECE -{ - float* verts; - unsigned int verts_count; - bool long_info; - connection_t* connections; - group_t* groups; - char name[LC_MAXPATH]; - char description[256]; -}; - -bool ReadLDrawPiece(const char* filename, LC_LDRAW_PIECE* piece); -bool SaveLDrawPiece(LC_LDRAW_PIECE* piece, lcFile* NewIdxFile, lcFile* NewBinFile, lcFile* OldIdxFile, lcFile* OldBinFile); -void FreeLDrawPiece(LC_LDRAW_PIECE* piece); - -#endif // _LIBRARY_H_ diff --git a/common/minifig.cpp b/common/minifig.cpp index da312ad3..c00104f7 100644 --- a/common/minifig.cpp +++ b/common/minifig.cpp @@ -15,7 +15,7 @@ #include "globals.h" #include "project.h" #include "system.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" // ============================================================================= @@ -858,11 +858,11 @@ static int lcGetMinifigSettings(lcMemFile& File) // ============================================================================= // MinifigWizard class -MinifigWizard::MinifigWizard (GLWindow *share) +MinifigWizard::MinifigWizard(GLWindow *share) : GLWindow (share) { char Filename[LC_MAXPATH]; - strcpy(Filename, lcGetPiecesLibrary()->GetLibraryPath()); + strcpy(Filename, lcGetPiecesLibrary()->mLibraryPath); strcat(Filename, "mlcad.ini"); lcDiskFile DiskSettings; @@ -932,7 +932,7 @@ void MinifigWizard::OnInitialUpdate() m_Colors[i] = lcGetColorIndex(ColorCodes[i]); m_Angles[i] = 0; - m_Info[i] = lcGetPiecesLibrary()->FindPieceInfo(Pieces[i]); + m_Info[i] = lcGetPiecesLibrary()->FindPiece(Pieces[i], false); if (m_Info[i] != NULL) m_Info[i]->AddRef(); } @@ -1081,7 +1081,7 @@ void MinifigWizard::ParseSettings(lcFile& Settings) *Ext = 0; } - PieceInfo* Info = lcGetPiecesLibrary()->FindPieceInfo(NameStart); + PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(NameStart, false); if (!Info && *NameStart) continue; @@ -1440,7 +1440,7 @@ bool MinifigWizard::LoadMinifig(const char* name) endptr = strchr(ptr, ' '); *endptr = '\0'; - m_Info[j] = lcGetPiecesLibrary()->FindPieceInfo(ptr); + m_Info[j] = lcGetPiecesLibrary()->FindPiece(ptr, false); *endptr = ' '; ptr = endptr; diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index ca6a6211..dd96d23d 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -10,7 +10,7 @@ #include "texture.h" #include "pieceinf.h" #include "project.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" #define SIDES 16 @@ -172,624 +172,18 @@ void PieceInfo::CreateBoxDisplayList() glEndList(); } -inline lcuint16 EndianSwap(lcuint16 Val) -{ - return LCUINT16(Val); -} - -inline lcuint32 EndianSwap(lcuint32 Val) -{ - return LCUINT32(Val); -} - -template -static void WriteMeshDrawInfo(lcuint32*& Data, lcMesh* Mesh, float*& OutVertex, int* SectionIndices, lcMeshSection** DstSections) -{ - int NumColors = EndianSwap(*Data); - Data++; - - for (int Color = 0; Color < NumColors; Color++) - { - int ColorIdx = lcGetColorIndex(EndianSwap(*Data)); - Data++; - - SrcType* SrcPtr = (SrcType*)Data; - int NumQuads = EndianSwap(*SrcPtr); - SrcPtr++; - int NumTris = EndianSwap(*(SrcPtr + NumQuads)); - - if (NumTris || NumQuads) - { - lcMeshSection* Section = DstSections[ColorIdx * 2 + 0]; - DstType* OutIndex = (DstType*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(DstType) + Section->NumIndices; - - for (int i = 0; i < NumQuads; i += 4) - { - *OutIndex++ = EndianSwap(SrcPtr[0]); - *OutIndex++ = EndianSwap(SrcPtr[1]); - *OutIndex++ = EndianSwap(SrcPtr[2]); - *OutIndex++ = EndianSwap(SrcPtr[0]); - *OutIndex++ = EndianSwap(SrcPtr[2]); - *OutIndex++ = EndianSwap(SrcPtr[3]); - SrcPtr += 4; - } - - SrcPtr++; - - for (int i = 0; i < NumTris; i++) - { - *OutIndex++ = EndianSwap(*SrcPtr); - SrcPtr++; - } - - Section->NumIndices += NumQuads / 4 * 6 + NumTris; - } - else - SrcPtr++; - - int NumLines = EndianSwap(*SrcPtr); - SrcPtr++; - - if (NumLines) - { - lcMeshSection* Section = DstSections[ColorIdx * 2 + 1]; - DstType* OutIndex = (DstType*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(DstType) + Section->NumIndices; - - for (int i = 0; i < NumLines; i++) - { - *OutIndex++ = EndianSwap(*SrcPtr); - SrcPtr++; - } - - Section->NumIndices += NumLines; - } - - Data = (lcuint32*)SrcPtr; - } -} - -template -static void WriteStudDrawInfo(int ColorIdx, const lcMatrix44& Mat, lcMesh* Mesh, float*& OutVertex, float Radius, int* SectionIndices, lcMeshSection** DstSections) -{ - // Build vertices. - int BaseVertex = (OutVertex - (float*)Mesh->mVertexBuffer.mData) / 3; - lcVector3 Vert; - - for (int i = 0; i < SIDES; i++) - { - Vert = lcMul31(lcVector3(Radius * costbl[i], Radius * sintbl[i], 0.0f), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - Vert = lcMul31(lcVector3(Radius * costbl[i], Radius * sintbl[i], LC_STUD_HEIGHT), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - } - - Vert = lcMul31(lcVector3(0.0f, 0.0f, LC_STUD_HEIGHT), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - - int v0 = BaseVertex + 2 * SIDES; - - // Triangles. - lcMeshSection* Section = DstSections[ColorIdx * 2 + 0]; - DstType* OutIndex = (DstType*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(DstType) + Section->NumIndices; - - for (int i = 0; i < SIDES; i++) - { - int i1 = BaseVertex + (i % SIDES) * 2; - int i2 = BaseVertex + ((i + 1) % SIDES) * 2; - - int v1 = i1; - int v2 = i1 + 1; - int v3 = i2; - int v4 = i2 + 1; - - *OutIndex++ = v0; - *OutIndex++ = v2; - *OutIndex++ = v4; - - *OutIndex++ = v1; - *OutIndex++ = v3; - *OutIndex++ = v2; - - *OutIndex++ = v3; - *OutIndex++ = v4; - *OutIndex++ = v2; - } - - Section->NumIndices += 9 * SIDES; - - // Lines. - Section = DstSections[gEdgeColor * 2 + 1]; - OutIndex = (DstType*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(DstType) + Section->NumIndices; - - for (int i = 0; i < SIDES; i++) - { - int i1 = BaseVertex + (i % SIDES) * 2; - int i2 = BaseVertex + ((i + 1) % SIDES) * 2; - - int v1 = i1; - int v2 = i1 + 1; - int v3 = i2; - int v4 = i2 + 1; - - *OutIndex++ = v1; - *OutIndex++ = v3; - - *OutIndex++ = v2; - *OutIndex++ = v4; - } - - Section->NumIndices += 4 * SIDES; -} - -template -static void WriteHollowStudDrawInfo(int ColorIdx, const lcMatrix44& Mat, lcMesh* Mesh, float*& OutVertex, float InnerRadius, float OuterRadius, int* SectionIndices, lcMeshSection** DstSections) -{ - // Build vertices. - int BaseVertex = (OutVertex - (float*)Mesh->mVertexBuffer.mData) / 3; - lcVector3 Vert; - - for (int i = 0; i < SIDES; i++) - { - // Outside. - Vert = lcMul31(lcVector3(OuterRadius * costbl[i], OuterRadius * sintbl[i], 0.0f), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - Vert = lcMul31(lcVector3(OuterRadius * costbl[i], OuterRadius * sintbl[i], LC_STUD_HEIGHT), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - - // Inside. - Vert = lcMul31(lcVector3(InnerRadius * costbl[i], InnerRadius * sintbl[i], LC_STUD_HEIGHT), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - Vert = lcMul31(lcVector3(InnerRadius * costbl[i], InnerRadius * sintbl[i], 0.0f), Mat); - *OutVertex++ = Vert[0]; - *OutVertex++ = Vert[1]; - *OutVertex++ = Vert[2]; - } - - // Triangles. - lcMeshSection* Section = DstSections[ColorIdx * 2 + 0]; - DstType* OutIndex = (DstType*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(DstType) + Section->NumIndices; - - for (int i = 0; i < SIDES; i++) - { - int i1 = BaseVertex + (i % SIDES) * 4; - int i2 = BaseVertex + ((i + 1) % SIDES) * 4; - - int v1 = i1; - int v2 = i1 + 1; - int v3 = i1 + 2; - int v4 = i1 + 3; - int v5 = i2; - int v6 = i2 + 1; - int v7 = i2 + 2; - int v8 = i2 + 3; - - *OutIndex++ = v1; - *OutIndex++ = v5; - *OutIndex++ = v2; - - *OutIndex++ = v5; - *OutIndex++ = v6; - *OutIndex++ = v2; - - *OutIndex++ = v2; - *OutIndex++ = v6; - *OutIndex++ = v3; - - *OutIndex++ = v6; - *OutIndex++ = v7; - *OutIndex++ = v3; - - *OutIndex++ = v3; - *OutIndex++ = v7; - *OutIndex++ = v4; - - *OutIndex++ = v7; - *OutIndex++ = v8; - *OutIndex++ = v4; - } - - Section->NumIndices += 18 * SIDES; - - // Lines. - Section = DstSections[gEdgeColor * 2 + 1]; - OutIndex = (DstType*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(DstType) + Section->NumIndices; - - for (int i = 0; i < SIDES; i++) - { - int i1 = BaseVertex + (i % SIDES) * 4; - int i2 = BaseVertex + ((i + 1) % SIDES) * 4; - - int v1 = i1; - int v2 = i1 + 1; - int v3 = i1 + 2; - int v4 = i1 + 3; - int v5 = i2; - int v6 = i2 + 1; - int v7 = i2 + 2; - int v8 = i2 + 3; - - *OutIndex++ = v1; - *OutIndex++ = v5; - - *OutIndex++ = v2; - *OutIndex++ = v6; - - *OutIndex++ = v3; - *OutIndex++ = v7; - - *OutIndex++ = v4; - *OutIndex++ = v8; - } - - Section->NumIndices += 8 * SIDES; -} - -template -void PieceInfo::BuildMesh(void* Data, int* SectionIndices) -{ - // Create empty sections. - lcMeshSection** DstSections = new lcMeshSection*[gColorList.GetSize() * 2]; - memset(DstSections, 0, sizeof(DstSections[0]) * gColorList.GetSize() * 2); - - int IndexOffset = 0; - int NumSections = 0; - - for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++) - { - if (SectionIndices[ColorIdx * 2 + 0]) - { - lcMeshSection* Section = &mMesh->mSections[NumSections]; - DstSections[ColorIdx * 2 + 0] = Section; - - Section->PrimitiveType = GL_TRIANGLES; - Section->ColorIndex = ColorIdx; - Section->IndexOffset = IndexOffset; - Section->NumIndices = 0; - - IndexOffset += SectionIndices[ColorIdx * 2 + 0] * sizeof(DstType); - NumSections++; - - if (ColorIdx == gDefaultColor) - m_nFlags |= LC_PIECE_HAS_DEFAULT; - else - { - if (lcIsColorTranslucent(ColorIdx)) - m_nFlags |= LC_PIECE_HAS_TRANSLUCENT; - else - m_nFlags |= LC_PIECE_HAS_SOLID; - } - } - - if (SectionIndices[ColorIdx * 2 + 1]) - { - lcMeshSection* Section = &mMesh->mSections[NumSections]; - DstSections[ColorIdx * 2 + 1] = Section; - - Section->PrimitiveType = GL_LINES; - Section->ColorIndex = ColorIdx; - Section->IndexOffset = IndexOffset; - Section->NumIndices = 0; - - IndexOffset += SectionIndices[ColorIdx * 2 + 1] * sizeof(DstType); - NumSections++; - - m_nFlags |= LC_PIECE_HAS_LINES; - } - } - - // Read groups - lcuint32* longs = (lcuint32*)Data; - int NumVertices = LCUINT32(*longs); - float* OutVertex = (float*)mMesh->mVertexBuffer.mData + NumVertices * 3; - lcuint8* bytes = (lcuint8*)(longs + 1); - bytes += NumVertices * sizeof(lcint16) * 3; - - lcuint16 ConnectionCount = LCUINT16(*((lcuint16*)bytes)); - bytes += 2 + (1 + 6 * 2) * ConnectionCount; - bytes++; // TextureCount - lcuint16 GroupCount = LCUINT16(*((lcuint16*)bytes)); - bytes += sizeof(lcuint16); - - while (GroupCount--) - { - bytes += 1 + 2 * *bytes; - lcuint32* info = (lcuint32*)bytes; - lcuint32 type = *info; - - switch (type) - { - case LC_MESH: - { - info++; - - if (m_nFlags & LC_PIECE_LONGDATA_FILE) - WriteMeshDrawInfo(info, mMesh, OutVertex, SectionIndices, DstSections); - else - WriteMeshDrawInfo(info, mMesh, OutVertex, SectionIndices, DstSections); - } break; - - case LC_STUD: - case LC_STUD3: - { - info++; - int ColorIdx = lcGetColorIndex(LCUINT32(*info)); - float* MatFloats = (float*)(info + 1); - info += 1 + 12; - - for (int i = 0; i < 12; i++) - MatFloats[i] = LCFLOAT(MatFloats[i]); - - lcMatrix44 Mat(lcVector4(MatFloats[0], MatFloats[1], MatFloats[2], 0.0f), - lcVector4(MatFloats[3], MatFloats[4], MatFloats[5], 0.0f), - lcVector4(MatFloats[6], MatFloats[7], MatFloats[8], 0.0f), - lcVector4(MatFloats[9], MatFloats[10], MatFloats[11], 1.0f)); - - if (type == LC_STUD) - WriteStudDrawInfo(ColorIdx, Mat, mMesh, OutVertex, LC_STUD_RADIUS, SectionIndices, DstSections); - else - WriteStudDrawInfo(ColorIdx, Mat, mMesh, OutVertex, 0.16f, SectionIndices, DstSections); - } break; - - case LC_STUD2: - case LC_STUD4: - { - info++; - int ColorIdx = lcGetColorIndex(LCUINT32(*info)); - float* MatFloats = (float*)(info + 1); - info += 1 + 12; - - for (int i = 0; i < 12; i++) - MatFloats[i] = LCFLOAT(MatFloats[i]); - - lcMatrix44 Mat(lcVector4(MatFloats[0], MatFloats[1], MatFloats[2], 0.0f), - lcVector4(MatFloats[3], MatFloats[4], MatFloats[5], 0.0f), - lcVector4(MatFloats[6], MatFloats[7], MatFloats[8], 0.0f), - lcVector4(MatFloats[9], MatFloats[10], MatFloats[11], 1.0f)); - - if (type == LC_STUD2) - WriteHollowStudDrawInfo(ColorIdx, Mat, mMesh, OutVertex, 0.16f, LC_STUD_RADIUS, SectionIndices, DstSections); - else - WriteHollowStudDrawInfo(ColorIdx, Mat, mMesh, OutVertex, LC_STUD_RADIUS, 0.32f, SectionIndices, DstSections); - } break; - } - - info++; // should be 0 - bytes = (lcuint8*)info; - } - - delete[] DstSections; -} - void PieceInfo::LoadInformation() { if (m_nFlags & LC_PIECE_PLACEHOLDER) { mMesh = new lcMesh(); mMesh->CreateBox(); - return; } - - lcDiskFile bin; - char filename[LC_MAXPATH]; - void* buf; - lcuint32 verts, *longs, fixverts; - lcuint8 *bytes, *tmp, bt; - float scale, shift; - lcint16* shorts; - - FreeInformation(); - - // Open pieces.bin and buffer the information we need. - strcpy (filename, lcGetPiecesLibrary()->GetLibraryPath()); - strcat (filename, "pieces.bin"); - if (!bin.Open (filename, "rb")) - return; - - buf = malloc(m_nSize); - bin.Seek(m_nOffset, SEEK_SET); - bin.ReadBuffer(buf, m_nSize); - - shift = 1.0f/(1<<14); - scale = 0.01f; - if (m_nFlags & LC_PIECE_MEDIUM) scale = 0.001f; - if (m_nFlags & LC_PIECE_SMALL) scale = 0.0001f; - longs = (lcuint32*)buf; - fixverts = verts = LCUINT32(*longs); - bytes = (unsigned char*)(longs + 1); - bytes += verts * sizeof(lcint16) * 3; - - lcuint16 ConnectionCount = LCUINT16(*((lcuint16*)bytes)); - bytes += 2 + (1 + 6 * 2) * ConnectionCount; - bytes++; // TextureCount - - // Read groups. - lcuint16 GroupCount = LCUINT16(*((lcuint16*)bytes)); - bytes += sizeof(lcuint16); - - // Count sections, vertices and indices. - tmp = bytes; - - int NumSections = 0; - int NumVertices = fixverts; - int NumIndices = 0; - ObjArray SectionIndices(gColorList.GetSize() * 2); - SectionIndices.SetSize(gColorList.GetSize() * 2); - memset(&SectionIndices[0], 0, SectionIndices.GetSize() * sizeof(int)); - - while (GroupCount--) - { - bt = *bytes; - bytes++; - bytes += bt*sizeof(lcuint16); - - lcuint32* info = (lcuint32*)bytes; - - while (*info) - { - if (*info == LC_MESH) - { - info++; - lcuint32 NumColors = LCUINT32(*info); - info++; - - while (NumColors--) - { - int ColorIndex = lcGetColorIndex(LCUINT32(*info)); - info++; - - if (SectionIndices.GetSize() < (ColorIndex + 1) * 2) - { - int OldSize = SectionIndices.GetSize(); - SectionIndices.SetSize((ColorIndex + 1) * 2); - memset(&SectionIndices[OldSize], 0, (SectionIndices.GetSize() - OldSize) * sizeof(int)); - } - - if (m_nFlags & LC_PIECE_LONGDATA_FILE) - { - lcuint32* Indices = (lcuint32*)info; - int Triangles = LCUINT32(*Indices) / 4 * 6; - Indices += LCUINT32(*Indices) + 1; - Triangles += LCUINT32(*Indices); - Indices += LCUINT32(*Indices) + 1; - - if (Triangles) - { - if (!SectionIndices[ColorIndex * 2 + 0]) - NumSections++; - - SectionIndices[ColorIndex * 2 + 0] += Triangles; - NumIndices += Triangles; - } - - int Lines = LCUINT32(*Indices); - Indices += LCUINT32(*Indices) + 1; - - if (Lines) - { - if (!SectionIndices[ColorIndex * 2 + 1]) - NumSections++; - - SectionIndices[ColorIndex * 2 + 1] += Lines; - NumIndices += Lines; - } - - info = (lcuint32*)Indices; - } - else - { - lcuint16* Indices = (lcuint16*)info; - int Triangles = LCUINT16(*Indices) / 4 * 6; - Indices += LCUINT16(*Indices) + 1; - Triangles += LCUINT16(*Indices); - Indices += LCUINT16(*Indices) + 1; - - if (Triangles) - { - if (!SectionIndices[ColorIndex * 2 + 0]) - NumSections++; - - SectionIndices[ColorIndex * 2 + 0] += Triangles; - NumIndices += Triangles; - } - - int Lines = LCUINT16(*Indices); - Indices += LCUINT16(*Indices) + 1; - - if (Lines) - { - if (!SectionIndices[ColorIndex * 2 + 1]) - NumSections++; - - SectionIndices[ColorIndex * 2 + 1] += Lines; - NumIndices += Lines; - } - - info = (lcuint32*)Indices; - } - } - } - else if ((*info == LC_STUD) || (*info == LC_STUD3)) - { - info++; - int ColorIndex = lcGetColorIndex(LCUINT32(*info)); - info += 1 + 12; - - NumVertices += (2 * SIDES) + 1; - - if (!SectionIndices[ColorIndex * 2 + 0]) - NumSections++; - - SectionIndices[ColorIndex * 2 + 0] += 9 * SIDES; - NumIndices += 9 * SIDES; - - if (!SectionIndices[gEdgeColor * 2 + 1]) - NumSections++; - - SectionIndices[gEdgeColor * 2 + 1] += 4 * SIDES; - NumIndices += 4 * SIDES; - } - else if ((*info == LC_STUD2) || (*info == LC_STUD4)) - { - info++; - int ColorIndex = lcGetColorIndex(LCUINT32(*info)); - info += 1 + 12; - - NumVertices += 4 * SIDES; - - if (!SectionIndices[ColorIndex * 2 + 0]) - NumSections++; - - SectionIndices[ColorIndex * 2 + 0] += 18 * SIDES; - NumIndices += 18 * SIDES; - - if (!SectionIndices[gEdgeColor * 2 + 1]) - NumSections++; - - SectionIndices[gEdgeColor * 2 + 1] += 8 * SIDES; - NumIndices += 8 * SIDES; - } - } - - info++; // should be 0 - bytes = (lcuint8*)info; - } - - mMesh = new lcMesh(); - mMesh->Create(NumSections, NumVertices, NumIndices); - - float* OutVertex = (float*)mMesh->mVertexBuffer.mData; - - shorts = (lcint16*)(longs + 1); - for (verts = 0; verts < LCUINT32(*longs); verts++) - { - *OutVertex++ = (float)LCINT16(*shorts)*scale; - shorts++; - *OutVertex++ = (float)LCINT16(*shorts)*scale; - shorts++; - *OutVertex++ = (float)LCINT16(*shorts)*scale; - shorts++; - } - - if (NumVertices < 0x10000) - BuildMesh(buf, &SectionIndices[0]); else - BuildMesh(buf, &SectionIndices[0]); - - mMesh->UpdateBuffers(); - - free(buf); + { + FreeInformation(); + lcGetPiecesLibrary()->LoadPiece(m_strName); + } } void PieceInfo::FreeInformation() diff --git a/common/pieceinf.h b/common/pieceinf.h index edeac50f..111ebe2a 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -72,9 +72,6 @@ class PieceInfo void AddRef(); void DeRef(); - template - void BuildMesh(void* Data, int* SectionIndices); - public: lcMesh* mMesh; diff --git a/common/project.cpp b/common/project.cpp index f1708a01..63e76249 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -28,7 +28,7 @@ #include "curve.h" #include "mainwnd.h" #include "view.h" -#include "library.h" +#include "lc_library.h" #include "texfont.h" #include "debug.h" #include "lc_application.h" @@ -417,7 +417,7 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) char name[LC_PIECE_NAME_LEN]; Piece* pPiece = new Piece(NULL); pPiece->FileLoad(*file, name); - PieceInfo* pInfo = lcGetPiecesLibrary()->FindPieceInfo(name); + PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, true); if (pInfo) { pPiece->SetPieceInfo(pInfo); @@ -453,7 +453,7 @@ bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge) file->ReadU8(&step, 1); file->ReadU8(&group, 1); - PieceInfo* pInfo = lcGetPiecesLibrary()->FindPieceInfo(name); + PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, true); if (pInfo != NULL) { Piece* pPiece = new Piece(pInfo); @@ -1001,7 +1001,7 @@ void Project::FileReadLDraw(lcFile* file, Matrix* prevmat, int* nOk, int DefColo char name[LC_PIECE_NAME_LEN]; strcpy(name, tmp); - PieceInfo* pInfo = lcGetPiecesLibrary()->FindPieceInfo(name); + PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, false); if (pInfo != NULL) { float x, y, z, rot[4]; @@ -1050,7 +1050,7 @@ void Project::FileReadLDraw(lcFile* file, Matrix* prevmat, int* nOk, int DefColo if (read) { // Create a placeholder. - PieceInfo* Info = lcGetPiecesLibrary()->CreatePiecePlaceholder(tmp); + PieceInfo* Info = lcGetPiecesLibrary()->CreatePlaceholder(tmp); float x, y, z, rot[4]; Piece* pPiece = new Piece(Info); @@ -3250,11 +3250,11 @@ void Project::CreateHTMLPieceList(FILE* f, int nStep, bool bImages, const char* fputs("\n",f); PieceInfo* pInfo; - for (int j = 0; j < lcGetPiecesLibrary()->GetPieceCount (); j++) + for (int j = 0; j < lcGetPiecesLibrary()->mPieces.GetSize(); j++) { bool Add = false; memset(PiecesUsed, 0, sizeof(PiecesUsed[0]) * gColorList.GetSize()); - pInfo = lcGetPiecesLibrary()->GetPieceInfo(j); + pInfo = lcGetPiecesLibrary()->mPieces[j]; for (Piece* pPiece = m_pPieces; pPiece; pPiece = pPiece->m_pNext) { @@ -3853,14 +3853,14 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) break; } - PiecesLibrary* Library = lcGetPiecesLibrary(); - char* PieceTable = new char[Library->GetPieceCount() * LC_PIECE_NAME_LEN]; - int* PieceFlags = new int[Library->GetPieceCount()]; + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + char* PieceTable = new char[Library->mPieces.GetSize() * LC_PIECE_NAME_LEN]; + int* PieceFlags = new int[Library->mPieces.GetSize()]; int NumColors = gColorList.GetSize(); char* ColorTable = new char[NumColors * LC_MAX_COLOR_NAME]; - memset(PieceTable, 0, Library->GetPieceCount() * LC_PIECE_NAME_LEN); - memset(PieceFlags, 0, Library->GetPieceCount() * sizeof(int)); + memset(PieceTable, 0, Library->mPieces.GetSize() * LC_PIECE_NAME_LEN); + memset(PieceFlags, 0, Library->mPieces.GetSize() * sizeof(int)); memset(ColorTable, 0, NumColors * LC_MAX_COLOR_NAME); enum @@ -3915,11 +3915,11 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) strupr(Src); - PieceInfo* Info = Library->FindPieceInfo(Src); + PieceInfo* Info = Library->FindPiece(Src, false); if (!Info) continue; - int Index = Library->GetPieceIndex(Info); + int Index = Library->mPieces.FindIndex(Info); if (strchr(Flags, 'L')) { @@ -3986,7 +3986,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) if (FirstPiece != piece) break; - int Index = Library->GetPieceIndex(Info); + int Index = Library->mPieces.FindIndex(Info); if (PieceTable[Index * LC_PIECE_NAME_LEN]) { @@ -4031,7 +4031,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) for (Piece* piece = m_pPieces; piece; piece = piece->m_pNext) { PieceInfo* Info = piece->mPieceInfo; - int Index = Library->GetPieceIndex(Info); + int Index = Library->mPieces.FindIndex(Info); if (PieceTable[Index * LC_PIECE_NAME_LEN]) continue; @@ -4066,7 +4066,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) for (Piece* piece = m_pPieces; piece; piece = piece->m_pNext) { - int Index = Library->GetPieceIndex(piece->mPieceInfo); + int Index = Library->mPieces.FindIndex(piece->mPieceInfo); float fl[12]; int Color; @@ -4256,7 +4256,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) case LC_FILE_PROPERTIES: { - PiecesLibrary* Library = lcGetPiecesLibrary(); + lcPiecesLibrary* Library = lcGetPiecesLibrary(); LC_PROPERTIESDLG_OPTS opts; opts.strTitle = m_strTitle; @@ -4265,18 +4265,18 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) strcpy(opts.strComments, m_strComments); opts.strFilename = m_strPathName; - opts.NumPieces = Library->GetPieceCount(); + opts.NumPieces = Library->mPieces.GetSize(); opts.NumColors = gColorList.GetSize(); opts.PieceColorCount = new int[(opts.NumPieces + 1) * (opts.NumColors + 1)]; memset(opts.PieceColorCount, 0, (opts.NumPieces + 1) * (opts.NumColors + 1) * sizeof(opts.PieceColorCount[0])); opts.PieceNames = new const char*[opts.NumPieces]; for (int i = 0; i < opts.NumPieces; i++) - opts.PieceNames[i] = Library->GetPieceInfo(i)->m_strDescription; + opts.PieceNames[i] = Library->mPieces[i]->m_strDescription; for (Piece* pPiece = m_pPieces; pPiece; pPiece = pPiece->m_pNext) { - int idx = Library->GetPieceIndex(pPiece->mPieceInfo); + int idx = Library->mPieces.FindIndex(pPiece->mPieceInfo); opts.PieceColorCount[idx * (opts.NumColors + 1) + pPiece->mColorIndex]++; opts.PieceColorCount[idx * (opts.NumColors + 1) + opts.NumColors]++; opts.PieceColorCount[opts.NumPieces * (opts.NumColors + 1) + pPiece->mColorIndex]++; @@ -4315,17 +4315,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) case LC_FILE_LIBRARY: { - lcMemFile file; - FileSave(&file, true); - - if (SystemDoDialog(LC_DLG_LIBRARY, NULL)) - { - if (lcGetPiecesLibrary()->m_Modified) - { - DeleteContents(true); - FileLoad(&file, true, false); - } - } + SystemDoDialog(LC_DLG_LIBRARY, NULL); } break; case LC_FILE_RECENT: @@ -4474,7 +4464,7 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam) char name[LC_PIECE_NAME_LEN]; Piece* pPiece = new Piece(NULL); pPiece->FileLoad(*file, name); - PieceInfo* pInfo = lcGetPiecesLibrary()->FindPieceInfo(name); + PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, true); if (pInfo) { pPiece->SetPieceInfo(pInfo); diff --git a/common/project.h b/common/project.h index 6c2e03ef..593648bc 100644 --- a/common/project.h +++ b/common/project.h @@ -52,7 +52,6 @@ class PieceInfo; class Matrix; class View; class Image; -class PiecesLibrary; class TexFont; // Undo support diff --git a/common/texture.cpp b/common/texture.cpp index 280a4f97..b2af35e2 100644 --- a/common/texture.cpp +++ b/common/texture.cpp @@ -10,7 +10,7 @@ #include "project.h" #include "globals.h" #include "image.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" // ============================================================================= @@ -129,6 +129,7 @@ void Texture::Unload() // Load from textures.bin file void Texture::Load(bool bFilter) { + /* char filename[LC_MAXPATH]; lcDiskFile bin; void* bits; @@ -149,6 +150,7 @@ void Texture::Load(bool bFilter) FinishLoadImage (bFilter, bits); free(bits); + */ } bool Texture::LoadFromFile (char* strFilename, bool bFilter) diff --git a/win/Leocad.cpp b/win/Leocad.cpp index 705e8717..07268771 100644 --- a/win/Leocad.cpp +++ b/win/Leocad.cpp @@ -11,7 +11,7 @@ #include "system.h" #include "pieceinf.h" // TODO: remove #include "mainwnd.h" -#include "library.h" +#include "lc_library.h" #include "keyboard.h" #include "lc_application.h" @@ -96,7 +96,7 @@ static void CheckForUpdates(void* Data) else str = "You are using the latest version of LeoCAD.\n"; - if (lib > lcGetPiecesLibrary()->GetPieceCount ()) + if (lib > lcGetPiecesLibrary()->mPieces.GetSize()) { str += "There are new pieces available.\n\n"; Update = true; @@ -213,9 +213,9 @@ BOOL CCADApp::InitInstance() MainFrame->UpdateMenuAccelerators(); // Show something in the piece preview window. - PieceInfo* Info = lcGetPiecesLibrary()->FindPieceInfo("3005"); - if (!Info) - Info = lcGetPiecesLibrary()->GetPieceInfo(0); + PieceInfo* Info = lcGetPiecesLibrary()->FindPiece("3005", false); + if (!Info && lcGetPiecesLibrary()->mPieces.GetSize()) + Info = lcGetPiecesLibrary()->mPieces[0]; if (Info) { diff --git a/win/Libdlg.cpp b/win/Libdlg.cpp index 3b8db5f6..06410d29 100644 --- a/win/Libdlg.cpp +++ b/win/Libdlg.cpp @@ -9,7 +9,7 @@ #include "pieceinf.h" #include "globals.h" #include "system.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" #ifdef _DEBUG @@ -206,7 +206,7 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam) if (Item == NULL) break; - PiecesLibrary* Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); CString CategoryName = m_Tree.GetItemText(Item); int Index = Lib->FindCategoryIndex((const char*)CategoryName); @@ -214,8 +214,8 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam) break; char Msg[1024]; - String Name = Lib->GetCategoryName(Index); - sprintf(Msg, "Are you sure you want to remove the %s category?", Name); + const String& Name = Lib->mCategories[Index].Name; + sprintf(Msg, "Are you sure you want to remove the '%s' category?", Name); if (SystemDoMessageBox(Msg, LC_MB_YESNO | LC_MB_ICONQUESTION) == LC_YES) { @@ -234,7 +234,7 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam) if (Item == NULL) break; - PiecesLibrary* Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); CString CategoryName = m_Tree.GetItemText(Item); int Index = Lib->FindCategoryIndex((const char*)CategoryName); @@ -242,12 +242,12 @@ BOOL CLibraryDlg::OnCommand(WPARAM wParam, LPARAM lParam) break; LC_CATEGORYDLG_OPTS Opts; - Opts.Name = Lib->GetCategoryName(Index); - Opts.Keywords = Lib->GetCategoryKeywords(Index); + Opts.Name = Lib->mCategories[Index].Name; + Opts.Keywords = Lib->mCategories[Index].Keywords; if (SystemDoDialog(LC_DLG_EDITCATEGORY, &Opts)) { - String OldName = Lib->GetCategoryName(Index); + String OldName = Lib->mCategories[Index].Name; Lib->SetCategory(Index, Opts.Name, Opts.Keywords); } @@ -275,7 +275,7 @@ void CLibraryDlg::UpdateList() m_List.DeleteAllItems(); m_List.SetRedraw(FALSE); - PiecesLibrary *Lib = lcGetPiecesLibrary(); + lcPiecesLibrary *Lib = lcGetPiecesLibrary(); HTREEITEM CategoryItem = m_Tree.GetSelectedItem(); CString CategoryName = m_Tree.GetItemText(CategoryItem); @@ -307,18 +307,18 @@ void CLibraryDlg::UpdateList() if (CategoryName == "Unassigned") { // Test each piece against all categories. - for (int i = 0; i < Lib->GetPieceCount(); i++) + for (int i = 0; i < Lib->mPieces.GetSize(); i++) { - PieceInfo* Info = Lib->GetPieceInfo(i); + PieceInfo* Info = Lib->mPieces[i]; int j; - for (j = 0; j < Lib->GetNumCategories(); j++) + for (j = 0; j < Lib->mCategories.GetSize(); j++) { - if (Lib->PieceInCategory(Info, Lib->GetCategoryKeywords(j))) + if (Lib->PieceInCategory(Info, Lib->mCategories[j].Keywords)) break; } - if (j == Lib->GetNumCategories()) + if (j == Lib->mCategories.GetSize()) { LVITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; @@ -334,9 +334,9 @@ void CLibraryDlg::UpdateList() } else if (CategoryName == "Pieces") { - for (int i = 0; i < Lib->GetPieceCount(); i++) + for (int i = 0; i < Lib->mPieces.GetSize(); i++) { - PieceInfo* Info = Lib->GetPieceInfo(i); + PieceInfo* Info = Lib->mPieces[i]; LVITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; @@ -362,9 +362,9 @@ void CLibraryDlg::UpdateTree() HTREEITEM Root = m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT, "Pieces", 0, 1, 0, 0, 0, TVI_ROOT, TVI_SORT); - PiecesLibrary *Lib = lcGetPiecesLibrary(); - for (int i = 0; i < Lib->GetNumCategories(); i++) - m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_TEXT, Lib->GetCategoryName(i), 0, 1, 0, 0, 0, Root, TVI_SORT); + lcPiecesLibrary *Lib = lcGetPiecesLibrary(); + for (int i = 0; i < Lib->mCategories.GetSize(); i++) + m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_TEXT, Lib->mCategories[i].Name, 0, 1, 0, 0, 0, Root, TVI_SORT); m_Tree.InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_TEXT, "Unassigned", 0, 1, 0, 0, 0, Root, TVI_LAST); diff --git a/win/Mainfrm.cpp b/win/Mainfrm.cpp index 3980ef11..4a280f19 100644 --- a/win/Mainfrm.cpp +++ b/win/Mainfrm.cpp @@ -11,7 +11,7 @@ #include "console.h" #include "keyboard.h" #include "system.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" #include "Print.h" #include "dynsplit.h" @@ -1052,7 +1052,7 @@ BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) if (Item == NULL) break; - PiecesLibrary* Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); CString CategoryName = m_wndPiecesBar.m_PiecesTree.GetItemText(Item); int Index = Lib->FindCategoryIndex((const char*)CategoryName); @@ -1060,12 +1060,12 @@ BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) break; LC_CATEGORYDLG_OPTS Opts; - Opts.Name = Lib->GetCategoryName(Index); - Opts.Keywords = Lib->GetCategoryKeywords(Index); + Opts.Name = Lib->mCategories[Index].Name; + Opts.Keywords = Lib->mCategories[Index].Keywords; if (SystemDoDialog(LC_DLG_EDITCATEGORY, &Opts)) { - String OldName = Lib->GetCategoryName(Index); + String OldName = Lib->mCategories[Index].Name; Lib->SetCategory(Index, Opts.Name, Opts.Keywords); m_wndPiecesBar.UpdatePiecesTree(OldName, Opts.Name); } @@ -1080,7 +1080,7 @@ BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) if (SystemDoDialog(LC_DLG_EDITCATEGORY, &Opts)) { - PiecesLibrary* Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); Lib->AddCategory(Opts.Name, Opts.Keywords); m_wndPiecesBar.UpdatePiecesTree(NULL, Opts.Name); } @@ -1094,7 +1094,7 @@ BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) if (Item == NULL) break; - PiecesLibrary* Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); CString CategoryName = m_wndPiecesBar.m_PiecesTree.GetItemText(Item); int Index = Lib->FindCategoryIndex((const char*)CategoryName); @@ -1102,8 +1102,8 @@ BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) break; char Msg[1024]; - String Name = Lib->GetCategoryName(Index); - sprintf(Msg, "Are you sure you want to remove the %s category?", Name); + const String& Name = Lib->mCategories[Index].Name; + sprintf(Msg, "Are you sure you want to remove the '%s' category?", Name); if (SystemDoMessageBox(Msg, LC_MB_YESNO | LC_MB_ICONQUESTION) == LC_YES) { diff --git a/win/Piecebar.cpp b/win/Piecebar.cpp index 24930c7a..ef846982 100644 --- a/win/Piecebar.cpp +++ b/win/Piecebar.cpp @@ -1,7 +1,7 @@ #include "lc_global.h" #include "resource.h" #include "piecebar.h" -#include "library.h" +#include "lc_library.h" #include "pieceinf.h" #include "project.h" #include "globals.h" @@ -204,7 +204,7 @@ void CPiecesBar::OnContextMenu(CWnd* pWnd, CPoint point) if (Item != NULL) { - PiecesLibrary *Lib = lcGetPiecesLibrary(); + lcPiecesLibrary *Lib = lcGetPiecesLibrary(); CString CategoryName = m_PiecesTree.GetItemText(Item); int CategoryIndex = Lib->FindCategoryIndex((const char*)CategoryName); @@ -259,7 +259,7 @@ void CPiecesBar::SelectPiece(const char* Category, PieceInfo* Info) strcpy(ParentName, Info->m_strName); *strchr(ParentName, 'P') = '\0'; - Parent = lcGetPiecesLibrary()->FindPieceInfo(ParentName); + Parent = lcGetPiecesLibrary()->FindPiece(ParentName, false); if (Parent) { @@ -367,7 +367,7 @@ void CPiecesBar::UpdatePiecesTree(const char* OldCategory, const char* NewCatego void CPiecesBar::UpdatePiecesTree(bool SearchOnly) { - PiecesLibrary *Lib = lcGetPiecesLibrary(); + lcPiecesLibrary *Lib = lcGetPiecesLibrary(); if (SearchOnly) { @@ -413,12 +413,12 @@ void CPiecesBar::UpdatePiecesTree(bool SearchOnly) Insert.item.mask = TVIF_CHILDREN|TVIF_PARAM|TVIF_TEXT; Insert.item.cChildren = 1; - for (int i = 0; i < Lib->GetNumCategories(); i++) + for (int i = 0; i < Lib->mCategories.GetSize(); i++) { - if (Lib->GetCategoryName(i) == "Search Results") + if (Lib->mCategories[i].Name == "Search Results") continue; - Insert.item.pszText = (LPSTR)Lib->GetCategoryName(i); + Insert.item.pszText = (LPSTR)Lib->mCategories[i].Name; m_PiecesTree.InsertItem(&Insert); } @@ -495,7 +495,7 @@ BOOL CPiecesBar::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { m_PiecesTree.SetRedraw(FALSE); - PiecesLibrary *Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); // Remove all children. HTREEITEM Item = Notify->itemNew.hItem; @@ -590,7 +590,7 @@ BOOL CPiecesBar::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) if (CategoryIndex != -1) { - if (!Lib->PieceInCategory(Info, Lib->GetCategoryKeywords(CategoryIndex))) + if (!Lib->PieceInCategory(Info, Lib->mCategories[CategoryIndex].Keywords)) continue; } diff --git a/win/Piececmb.cpp b/win/Piececmb.cpp index d4442372..d7b44fc7 100644 --- a/win/Piececmb.cpp +++ b/win/Piececmb.cpp @@ -5,7 +5,7 @@ #include "pieceinf.h" #include "project.h" #include "globals.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" #ifdef _DEBUG @@ -43,7 +43,7 @@ void CPiecesCombo::OnEditupdate() return; char str[66]; - PiecesLibrary *pLib = lcGetPiecesLibrary(); + lcPiecesLibrary *pLib = lcGetPiecesLibrary(); CPiecesBar* pBar = (CPiecesBar*)GetParent(); PieceInfo* pInfo; @@ -52,9 +52,9 @@ void CPiecesCombo::OnEditupdate() char newstr[66]; int sel = -1; strcpy (newstr, "Z"); - for (int i = 0; i < pLib->GetPieceCount(); i++) + for (int i = 0; i < pLib->mPieces.GetSize(); i++) { - pInfo = pLib->GetPieceInfo(i); + pInfo = pLib->mPieces[i]; if ((pInfo->m_strDescription[0] == '~') && !pBar->m_bSubParts) continue; @@ -79,9 +79,9 @@ void CPiecesCombo::OnEditupdate() } if (sel >= 0) - SelectPiece(pLib->GetPieceInfo(sel)); + SelectPiece(pLib->mPieces[sel]); - if (strlen (newstr) > 1) + if (strlen(newstr) > 1) { SetWindowText(newstr); SetEditSel(n, -1); @@ -103,7 +103,7 @@ BOOL CPiecesCombo::PreTranslateMessage(MSG* pMsg) } else if (nVirtKey == VK_RETURN) { - PiecesLibrary* Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); CString str; GetWindowText(str); @@ -124,14 +124,14 @@ void CPiecesCombo::OnSelchange() { char str[66]; CPiecesBar* pBar = (CPiecesBar*)GetParent(); - PiecesLibrary *pLib = lcGetPiecesLibrary(); + lcPiecesLibrary* pLib = lcGetPiecesLibrary(); if (!GetLBText (GetCurSel(), str)) return; - for (int i = 0; i < pLib->GetPieceCount(); i++) + for (int i = 0; i < pLib->mPieces.GetSize(); i++) { - PieceInfo* pInfo = pLib->GetPieceInfo(i); + PieceInfo* pInfo = pLib->mPieces[i]; if (strcmp(str, pInfo->m_strDescription) == 0) SelectPiece(pInfo); @@ -140,11 +140,11 @@ void CPiecesCombo::OnSelchange() void CPiecesCombo::SelectPiece(PieceInfo* Info) { - PiecesLibrary *Lib = lcGetPiecesLibrary(); + lcPiecesLibrary* Lib = lcGetPiecesLibrary(); CPiecesBar* Bar = (CPiecesBar*)GetParent(); - int Index = Lib->GetFirstCategory(Info); + int Index = Lib->GetFirstPieceCategory(Info); if (Index != -1) - Bar->SelectPiece(Lib->GetCategoryName(Index), Info); + Bar->SelectPiece(Lib->mCategories[Index].Name, Info); } diff --git a/win/Print.cpp b/win/Print.cpp index c2904fd3..75411666 100644 --- a/win/Print.cpp +++ b/win/Print.cpp @@ -8,7 +8,7 @@ #include "CADView.h" #include "Tools.h" #include "Piece.h" -#include "library.h" +#include "lc_library.h" #include "lc_application.h" // TODO: rewrite everything @@ -17,11 +17,11 @@ static void PrintCatalogThread (CWnd* pParent, CFrameWndEx* pMainFrame) { CCADView* pView = (CCADView*)pMainFrame->GetActiveView(); CPrintDialog* PD = new CPrintDialog(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOSELECTION|PD_ENABLEPRINTHOOK, pParent); - PiecesLibrary *pLib = lcGetPiecesLibrary(); + lcPiecesLibrary *pLib = lcGetPiecesLibrary(); int bricks = 0; - for (int j = 0; j < pLib->GetPieceCount (); j++) - if (pLib->GetPieceInfo(j)->m_strDescription[0] != '~') + for (int j = 0; j < pLib->mPieces.GetSize(); j++) + if (pLib->mPieces[j]->m_strDescription[0] != '~') bricks++; int rows = theApp.GetProfileInt("Default", "Catalog Rows", 10); int cols = theApp.GetProfileInt("Default", "Catalog Columns", 3); @@ -203,9 +203,9 @@ static void PrintCatalogThread (CWnd* pParent, CFrameWndEx* pMainFrame) start.next = NULL; - for (int j = 0; j < pLib->GetPieceCount (); j++) + for (int j = 0; j < pLib->mPieces.GetSize(); j++) { - char* desc = pLib->GetPieceInfo(j)->m_strDescription; + char* desc = pLib->mPieces[j]->m_strDescription; if (desc[0] != '~') continue; @@ -287,7 +287,7 @@ static void PrintCatalogThread (CWnd* pParent, CFrameWndEx* pMainFrame) // dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, node->name); node = node->next; - PieceInfo* pInfo = pLib->GetPieceInfo(node->actual); + PieceInfo* pInfo = pLib->mPieces[node->actual]; pInfo->ZoomExtents(30.0f, (float)aspect); float pos[4] = { 0, 0, 10, 0 }; @@ -407,11 +407,11 @@ static void PrintPiecesThread(void* pv) CFrameWndEx* pFrame = (CFrameWndEx*)pv; CView* pView = pFrame->GetActiveView(); CPrintDialog* PD = new CPrintDialog(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOPAGENUMS|PD_NOSELECTION, pFrame); - PiecesLibrary *pLib = lcGetPiecesLibrary(); + lcPiecesLibrary *pLib = lcGetPiecesLibrary(); Project* project = lcGetActiveProject(); int NumColors = gColorList.GetSize(); - int NumPieces = pLib->GetPieceCount(); + int NumPieces = pLib->mPieces.GetSize(); lcuint32* PiecesUsed = new lcuint32[NumPieces * NumColors]; memset(PiecesUsed, 0, NumPieces * NumColors * sizeof(lcuint32)); @@ -420,7 +420,7 @@ static void PrintPiecesThread(void* pv) for (Piece* tmp = project->m_pPieces; tmp; tmp = tmp->m_pNext) { - int idx = pLib->GetPieceIndex(tmp->mPieceInfo); + int idx = pLib->mPieces.FindIndex(tmp->mPieceInfo); PiecesUsed[(idx * NumColors) + tmp->mColorIndex]++; ColorsUsed[tmp->mColorIndex]++; } @@ -586,7 +586,7 @@ static void PrintPiecesThread(void* pv) for (j = 0; j < NumPieces; j++) { - char* desc = pLib->GetPieceInfo(j)->m_strDescription; + char* desc = pLib->mPieces[j]->m_strDescription; if (desc[0] == '~') continue; @@ -679,7 +679,7 @@ static void PrintPiecesThread(void* pv) lcSetColor(project->m_nCurColor); - PieceInfo* pInfo = pLib->GetPieceInfo(node->actual); + PieceInfo* pInfo = pLib->mPieces[node->actual]; node = node->next; pInfo->ZoomExtents(30.0f, (float)aspect); @@ -701,7 +701,7 @@ static void PrintPiecesThread(void* pv) int rowtotal = 0; char tmp[5]; - int idx = (pLib->GetPieceIndex (pInfo)); + int idx = (pLib->mPieces.FindIndex(pInfo)); for (i = 0; i < NumColors; i++) if (PiecesUsed[(idx*NumColors)+i]) { diff --git a/win/leocad.vcxproj b/win/leocad.vcxproj index bd3d2a89..d47af44f 100644 --- a/win/leocad.vcxproj +++ b/win/leocad.vcxproj @@ -186,7 +186,6 @@ - @@ -384,7 +383,6 @@ - diff --git a/win/leocad.vcxproj.filters b/win/leocad.vcxproj.filters index ac05bedb..5d7669e9 100644 --- a/win/leocad.vcxproj.filters +++ b/win/leocad.vcxproj.filters @@ -206,9 +206,6 @@ Common Source Files - - Common Source Files - Common Source Files @@ -744,9 +741,6 @@ Common Header Files - - Common Header Files - Common Header Files