Update file functions to support multibyte strings. Fixes #46.

This commit is contained in:
Leonardo Zide 2017-05-29 13:31:24 -07:00
parent 82a4afb7a9
commit 05e3d7846c
13 changed files with 197 additions and 334 deletions

View file

@ -166,7 +166,7 @@ bool Image::FileLoad(lcMemFile& File)
return true; return true;
} }
bool Image::FileLoad(const char* FileName) bool Image::FileLoad(const QString& FileName)
{ {
QImage Image; QImage Image;

View file

@ -24,7 +24,7 @@ public:
bool HasAlpha() const; bool HasAlpha() const;
bool FileLoad(lcMemFile& File); bool FileLoad(lcMemFile& File);
bool FileLoad(const char* FileName); bool FileLoad(const QString& FileName);
void Resize(int Width, int Height); void Resize(int Width, int Height);
void ResizePow2(); void ResizePow2();

View file

@ -99,7 +99,7 @@ bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryIn
QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY);
if (!CustomPath.isEmpty()) if (!CustomPath.isEmpty())
return mLibrary->Load(CustomPath.toLatin1().constData()); // todo: qstring return mLibrary->Load(CustomPath);
if (LibraryInstallPath && LibraryInstallPath[0]) if (LibraryInstallPath && LibraryInstallPath[0])
{ {
@ -174,6 +174,7 @@ void lcApplication::ParseStringArgument(int* CurArg, int argc, char* argv[], cha
bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstallPath, const char* LDrawPath, bool& ShowWindow) bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstallPath, const char* LDrawPath, bool& ShowWindow)
{ {
// todo: parse command line using Qt to handle multibyte strings.
char* LibPath = nullptr; char* LibPath = nullptr;
// Image output options. // Image output options.

View file

@ -5,20 +5,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "lc_file.h" #include "lc_file.h"
// =============================================================================
// lcFile
lcFile::lcFile()
{
}
lcFile::~lcFile()
{
}
// =============================================================================
// lcMemFile
lcMemFile::lcMemFile() lcMemFile::lcMemFile()
{ {
mGrowBytes = 1024; mGrowBytes = 1024;
@ -64,10 +50,6 @@ size_t lcMemFile::GetLength() const
return mFileSize; return mFileSize;
} }
void lcMemFile::Flush()
{
}
void lcMemFile::Close() void lcMemFile::Close()
{ {
if (!mBuffer) if (!mBuffer)
@ -165,119 +147,3 @@ char* lcMemFile::ReadLine(char* Buffer, size_t BufferSize)
Buffer[BytesRead] = 0; Buffer[BytesRead] = 0;
return Buffer; return Buffer;
} }
void lcMemFile::CopyFrom(lcFile& Source)
{
size_t Length = Source.GetLength();
SetLength(Length);
Seek(0, SEEK_SET);
Source.Seek(0, SEEK_SET);
Source.ReadBuffer(mBuffer, Length);
}
void lcMemFile::CopyFrom(lcMemFile& Source)
{
size_t Length = Source.GetLength();
SetLength(Length);
Seek(0, SEEK_SET);
Source.Seek(0, SEEK_SET);
Source.ReadBuffer(mBuffer, Length);
}
// =============================================================================
// lcDiskFile
lcDiskFile::lcDiskFile()
{
mFile = nullptr;
}
lcDiskFile::~lcDiskFile()
{
Close();
}
long lcDiskFile::GetPosition() const
{
return ftell(mFile);
}
void lcDiskFile::Seek(long Offset, int From)
{
fseek(mFile, Offset, From);
}
void lcDiskFile::SetLength(size_t NewLength)
{
fseek(mFile, (int)NewLength, SEEK_SET);
}
size_t lcDiskFile::GetLength() const
{
struct stat st;
if (fstat(fileno(mFile), &st) < 0 || (st.st_mode & S_IFMT) != S_IFREG)
return 0;
return st.st_size;
}
void lcDiskFile::Flush()
{
if (mFile == nullptr)
return;
fflush(mFile);
}
void lcDiskFile::Close()
{
if (mFile == nullptr)
return;
fclose(mFile);
mFile = nullptr;
}
size_t lcDiskFile::ReadBuffer(void* Buffer, size_t Bytes)
{
return fread(Buffer, 1, Bytes, mFile);
}
size_t lcDiskFile::WriteBuffer(const void* Buffer, size_t Bytes)
{
return fwrite(Buffer, 1, Bytes, mFile);
}
bool lcDiskFile::Open(const QString& FileName, const char* Mode)
{
return Open(FileName.toLatin1().constData(), Mode); // todo: qstring
}
bool lcDiskFile::Open(const char* FileName, const char* Mode)
{
if (*FileName == 0)
return false;
Close();
mFile = fopen(FileName, Mode);
return (mFile != nullptr);
}
char* lcDiskFile::ReadLine(char* Buffer, size_t BufferSize)
{
return fgets(Buffer, (int)BufferSize, mFile);
}
void lcDiskFile::CopyFrom(lcMemFile& Source)
{
size_t Length = Source.GetLength();
Seek(0, SEEK_SET);
WriteBuffer(Source.mBuffer, Length);
}

View file

@ -11,15 +11,18 @@
class lcFile class lcFile
{ {
public: public:
lcFile(); lcFile()
virtual ~lcFile(); {
}
virtual ~lcFile()
{
}
virtual long GetPosition() const = 0; virtual long GetPosition() const = 0;
virtual void Seek(long Offset, int From) = 0; virtual void Seek(long Offset, int From) = 0;
virtual void SetLength(size_t NewLength) = 0;
virtual size_t GetLength() const = 0; virtual size_t GetLength() const = 0;
virtual void Flush() = 0;
virtual void Close() = 0; virtual void Close() = 0;
virtual char* ReadLine(char* Buffer, size_t BufferSize) = 0; virtual char* ReadLine(char* Buffer, size_t BufferSize) = 0;
@ -30,7 +33,6 @@ public:
virtual size_t ReadBuffer(void* Buffer, size_t Bytes) = 0; virtual size_t ReadBuffer(void* Buffer, size_t Bytes) = 0;
virtual size_t WriteBuffer(const void* Buffer, size_t Bytes) = 0; virtual size_t WriteBuffer(const void* Buffer, size_t Bytes) = 0;
virtual void CopyFrom(lcMemFile& Source) = 0;
lcuint8 ReadU8() lcuint8 ReadU8()
{ {
@ -438,20 +440,17 @@ public:
lcMemFile(); lcMemFile();
virtual ~lcMemFile(); virtual ~lcMemFile();
long GetPosition() const; long GetPosition() const override;
void Seek(long Offset, int From); void Seek(long Offset, int From) override;
void SetLength(size_t NewLength); void SetLength(size_t NewLength);
size_t GetLength() const; size_t GetLength() const override;
void Flush(); void Close() override;
void Close();
char* ReadLine(char* Buffer, size_t BufferSize); char* ReadLine(char* Buffer, size_t BufferSize) override;
size_t ReadBuffer(void* Buffer, size_t Bytes); size_t ReadBuffer(void* Buffer, size_t Bytes) override;
size_t WriteBuffer(const void* Buffer, size_t Bytes); size_t WriteBuffer(const void* Buffer, size_t Bytes) override;
void CopyFrom(lcFile& Source);
void CopyFrom(lcMemFile& Source);
void GrowFile(size_t NewLength); void GrowFile(size_t NewLength);
size_t mGrowBytes; size_t mGrowBytes;
@ -464,27 +463,78 @@ public:
class lcDiskFile : public lcFile class lcDiskFile : public lcFile
{ {
public: public:
lcDiskFile(); lcDiskFile()
virtual ~lcDiskFile(); {
}
long GetPosition() const; lcDiskFile(const QString& FileName)
void Seek(long Offset, int From); : mFile(FileName)
void SetLength(size_t NewLength); {
size_t GetLength() const; }
void Flush(); virtual ~lcDiskFile()
void Close(); {
Close();
}
char* ReadLine(char* Buffer, size_t BufferSize); void SetFileName(const QString& FileName)
size_t ReadBuffer(void* Buffer, size_t Bytes); {
size_t WriteBuffer(const void* Buffer, size_t Bytes); mFile.setFileName(FileName);
}
void CopyFrom(lcMemFile& Source); long GetPosition() const override
{
return mFile.pos();
}
bool Open(const char* FileName, const char* Mode); void Seek(long Offset, int From) override
bool Open(const QString& FileName, const char* Mode); {
switch (From)
{
case SEEK_CUR:
Offset += mFile.pos();
break;
case SEEK_END:
Offset += mFile.size();
break;
}
FILE* mFile; mFile.seek(Offset);
}
size_t GetLength() const override
{
return mFile.size();
}
void Close() override
{
mFile.close();
}
char* ReadLine(char* Buffer, size_t BufferSize) override
{
qint64 LineLength = mFile.readLine(Buffer, BufferSize);
return LineLength != -1 ? Buffer : nullptr;
}
size_t ReadBuffer(void* Buffer, size_t Bytes) override
{
return mFile.read((char*)Buffer, Bytes);
}
size_t WriteBuffer(const void* Buffer, size_t Bytes) override
{
return mFile.write((const char*)Buffer, Bytes);
}
bool Open(QIODevice::OpenMode Flags)
{
return mFile.open(Flags);
}
protected:
QFile mFile;
}; };
#endif // _FILE_H_ #endif // _FILE_H_

View file

@ -42,9 +42,6 @@ lcPiecesLibrary::lcPiecesLibrary()
Dir.mkpath(mCachePath); Dir.mkpath(mCachePath);
mNumOfficialPieces = 0; mNumOfficialPieces = 0;
mLibraryPath[0] = 0;
mLibraryFileName[0] = 0;
mUnofficialFileName[0] = 0;
mZipFiles[LC_ZIPFILE_OFFICIAL] = nullptr; mZipFiles[LC_ZIPFILE_OFFICIAL] = nullptr;
mZipFiles[LC_ZIPFILE_UNOFFICIAL] = nullptr; mZipFiles[LC_ZIPFILE_UNOFFICIAL] = nullptr;
mBuffersDirty = false; mBuffersDirty = false;
@ -177,7 +174,7 @@ lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName)
return nullptr; return nullptr;
} }
bool lcPiecesLibrary::Load(const char* LibraryPath) bool lcPiecesLibrary::Load(const QString& LibraryPath)
{ {
Unload(); Unload();
@ -188,36 +185,23 @@ bool lcPiecesLibrary::Load(const char* LibraryPath)
if (!mZipFiles[LC_ZIPFILE_OFFICIAL]->ExtractFile("ldraw/ldconfig.ldr", ColorFile) || !lcLoadColorFile(ColorFile)) if (!mZipFiles[LC_ZIPFILE_OFFICIAL]->ExtractFile("ldraw/ldconfig.ldr", ColorFile) || !lcLoadColorFile(ColorFile))
lcLoadDefaultColors(); lcLoadDefaultColors();
strcpy(mLibraryPath, LibraryPath); mLibraryDir = QFileInfo(LibraryPath).absoluteDir();
char* Slash = lcMax(strrchr(mLibraryPath, '/'), strrchr(mLibraryPath, '\\')); QString UnofficialFileName = mLibraryDir.absoluteFilePath(QLatin1String("ldrawunf.zip"));
if (*Slash)
*(Slash + 1) = 0;
char UnofficialFileName[LC_MAXPATH];
strcpy(UnofficialFileName, mLibraryPath);
strcat(UnofficialFileName, "/ldrawunf.zip");
if (!OpenArchive(UnofficialFileName, LC_ZIPFILE_UNOFFICIAL)) if (!OpenArchive(UnofficialFileName, LC_ZIPFILE_UNOFFICIAL))
UnofficialFileName[0] = 0; UnofficialFileName.clear();
ReadArchiveDescriptions(LibraryPath, UnofficialFileName); ReadArchiveDescriptions(LibraryPath, UnofficialFileName);
} }
else else
{ {
strcpy(mLibraryPath, LibraryPath); mLibraryDir = LibraryPath;
size_t i = strlen(mLibraryPath) - 1; if (OpenDirectory(mLibraryDir))
if ((mLibraryPath[i] != '\\') && (mLibraryPath[i] != '/'))
strcat(mLibraryPath, "/");
if (OpenDirectory(mLibraryPath))
{ {
char FileName[LC_MAXPATH]; lcDiskFile ColorFile(mLibraryDir.absoluteFilePath(QLatin1String("ldconfig.ldr")));
lcDiskFile ColorFile;
sprintf(FileName, "%sldconfig.ldr", mLibraryPath); if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile))
if (!ColorFile.Open(FileName, "rt") || !lcLoadColorFile(ColorFile))
lcLoadDefaultColors(); lcLoadDefaultColors();
} }
else else
@ -230,11 +214,11 @@ bool lcPiecesLibrary::Load(const char* LibraryPath)
return true; return true;
} }
bool lcPiecesLibrary::OpenArchive(const char* FileName, lcZipFileType ZipFileType) bool lcPiecesLibrary::OpenArchive(const QString& FileName, lcZipFileType ZipFileType)
{ {
lcDiskFile* File = new lcDiskFile(); lcDiskFile* File = new lcDiskFile(FileName);
if (!File->Open(FileName, "rb") || !OpenArchive(File, FileName, ZipFileType)) if (!File->Open(QIODevice::ReadOnly) || !OpenArchive(File, FileName, ZipFileType))
{ {
delete File; delete File;
return false; return false;
@ -248,7 +232,7 @@ static int lcPrimitiveCompare(lcLibraryPrimitive* const& a, lcLibraryPrimitive*
return strcmp(a->mName, b->mName); return strcmp(a->mName, b->mName);
} }
bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType) bool lcPiecesLibrary::OpenArchive(lcFile* File, const QString& FileName, lcZipFileType ZipFileType)
{ {
lcZipFile* ZipFile = new lcZipFile(); lcZipFile* ZipFile = new lcZipFile();
@ -261,9 +245,9 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileT
mZipFiles[ZipFileType] = ZipFile; mZipFiles[ZipFileType] = ZipFile;
if (ZipFileType == LC_ZIPFILE_OFFICIAL) if (ZipFileType == LC_ZIPFILE_OFFICIAL)
strcpy(mLibraryFileName, FileName); mLibraryFileName = FileName;
else else
strcpy(mUnofficialFileName, FileName); mUnofficialFileName = FileName;
for (int FileIdx = 0; FileIdx < ZipFile->mFiles.GetSize(); FileIdx++) for (int FileIdx = 0; FileIdx < ZipFile->mFiles.GetSize(); FileIdx++)
{ {
@ -421,15 +405,11 @@ void lcPiecesLibrary::ReadArchiveDescriptions(const QString& OfficialFileName, c
} }
} }
bool lcPiecesLibrary::OpenDirectory(const char* Path) bool lcPiecesLibrary::OpenDirectory(const QDir& LibraryDir)
{ {
char FileName[LC_MAXPATH]; lcDiskFile PartsList(LibraryDir.absoluteFilePath(QLatin1String("parts.lst")));
strcpy(FileName, Path);
strcat(FileName, "parts.lst");
lcDiskFile PartsList; if (PartsList.Open(QIODevice::ReadOnly))
if (PartsList.Open(FileName, "rt"))
{ {
char Line[1024]; char Line[1024];
@ -486,17 +466,13 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
} }
} }
const char* BaseFolders[] = { "unofficial/", "" }; const QLatin1String BaseFolders[] = { QLatin1String("unofficial/"), QLatin1String("") };
if (!mPieces.GetSize()) if (!mPieces.GetSize())
{ {
for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < sizeof(BaseFolders) / sizeof(BaseFolders[0]); BaseFolderIdx++) for (unsigned int BaseFolderIdx = 0; BaseFolderIdx < sizeof(BaseFolders) / sizeof(BaseFolders[0]); BaseFolderIdx++)
{ {
strcpy(FileName, Path); QDir Dir(QDir(LibraryDir.absoluteFilePath(BaseFolders[BaseFolderIdx])).absoluteFilePath(QLatin1String("parts/")), QLatin1String("*.dat"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
strcat(FileName, BaseFolders[BaseFolderIdx]);
strcat(FileName, "parts/");
QDir Dir(FileName, "*.dat", QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
QStringList FileList = Dir.entryList(); QStringList FileList = Dir.entryList();
mPieces.AllocGrow(FileList.size()); mPieces.AllocGrow(FileList.size());
@ -545,8 +521,8 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
continue; continue;
} }
lcDiskFile PieceFile; lcDiskFile PieceFile(Dir.absoluteFilePath(FileList[FileIdx]));
if (!PieceFile.Open(Dir.absoluteFilePath(FileList[FileIdx]), "rt")) if (!PieceFile.Open(QIODevice::ReadOnly))
continue; continue;
char Line[1024]; char Line[1024];
@ -587,14 +563,11 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
{ {
const char* PrimitiveDirectories[] = { "p/", "p/48/", "parts/s/" }; const char* PrimitiveDirectories[] = { "p/", "p/48/", "parts/s/" };
bool SubFileDirectories[] = { false, false, true }; bool SubFileDirectories[] = { false, false, true };
QDir BaseDir(LibraryDir.absoluteFilePath(QLatin1String(BaseFolders[BaseFolderIdx])));
for (int DirectoryIdx = 0; DirectoryIdx < (int)(sizeof(PrimitiveDirectories) / sizeof(PrimitiveDirectories[0])); DirectoryIdx++) for (int DirectoryIdx = 0; DirectoryIdx < (int)(sizeof(PrimitiveDirectories) / sizeof(PrimitiveDirectories[0])); DirectoryIdx++)
{ {
strcpy(FileName, Path); QDir Dir(BaseDir.absoluteFilePath(QLatin1String(PrimitiveDirectories[DirectoryIdx])), QLatin1String("*.dat"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
strcat(FileName, BaseFolders[BaseFolderIdx]);
strcat(FileName, PrimitiveDirectories[DirectoryIdx]);
QDir Dir(FileName, "*.dat", QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
QStringList FileList = Dir.entryList(); QStringList FileList = Dir.entryList();
for (int FileIdx = 0; FileIdx < FileList.size(); FileIdx++) for (int FileIdx = 0; FileIdx < FileList.size(); FileIdx++)
@ -641,10 +614,7 @@ bool lcPiecesLibrary::OpenDirectory(const char* Path)
} }
} }
strcpy(FileName, Path); QDir Dir(LibraryDir.absoluteFilePath(QLatin1String("parts/textures/")), QLatin1String("*.png"), QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
strcat(FileName, "parts/textures/");
QDir Dir(FileName, "*.png", QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files | QDir::Hidden | QDir::Readable);
QStringList FileList = Dir.entryList(); QStringList FileList = Dir.entryList();
mTextures.AllocGrow(FileList.size()); mTextures.AllocGrow(FileList.size());
@ -1104,17 +1074,17 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
if (mHasUnofficial) if (mHasUnofficial)
{ {
sprintf(FileName, "%sunofficial/parts/%s.dat", mLibraryPath, Name); sprintf(FileName, "unofficial/parts/%s.dat", Name);
PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
if (PieceFile.Open(FileName, "rt")) if (PieceFile.Open(QIODevice::ReadOnly))
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true); Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
} }
if (!Loaded) if (!Loaded)
{ {
sprintf(FileName, "%sparts/%s.dat", mLibraryPath, Name); sprintf(FileName, "parts/%s.dat", Name);
PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
if (PieceFile.Open(FileName, "rt")) if (PieceFile.Open(QIODevice::ReadOnly))
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true); Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
} }
} }
@ -1518,9 +1488,9 @@ bool lcPiecesLibrary::LoadTexture(lcTexture* Texture)
} }
else else
{ {
sprintf(FileName, "%sparts/textures/%s.png", mLibraryPath, Name); sprintf(FileName, "parts/textures/%s.png", Name);
if (!Texture->Load(FileName)) if (!Texture->Load(mLibraryDir.absoluteFilePath(QLatin1String(FileName))))
return false; return false;
} }
@ -1615,21 +1585,21 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
if (mHasUnofficial) if (mHasUnofficial)
{ {
if (Primitive->mSubFile) if (Primitive->mSubFile)
sprintf(FileName, "%sunofficial/parts/%s.dat", mLibraryPath, Name); sprintf(FileName, "unofficial/parts/%s.dat", Name);
else else
sprintf(FileName, "%sunofficial/p/%s.dat", mLibraryPath, Name); sprintf(FileName, "unofficial/p/%s.dat", Name);
PrimFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
Found = PrimFile.Open(FileName, "rt"); Found = PrimFile.Open(QIODevice::ReadOnly);
} }
if (!Found) if (!Found)
{ {
if (Primitive->mSubFile) if (Primitive->mSubFile)
sprintf(FileName, "%sparts/%s.dat", mLibraryPath, Name); sprintf(FileName, "parts/%s.dat", Name);
else else
sprintf(FileName, "%sp/%s.dat", mLibraryPath, Name); sprintf(FileName, "p/%s.dat", Name);
PrimFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
Found = PrimFile.Open(FileName, "rt"); Found = PrimFile.Open(QIODevice::ReadOnly);
} }
if (!Found || !ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true)) if (!Found || !ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
@ -1907,23 +1877,22 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (mHasUnofficial) if (mHasUnofficial)
{ {
if (Primitive->mSubFile) if (Primitive->mSubFile)
sprintf(FileName, "%sunofficial/parts/%s.dat", mLibraryPath, Name); sprintf(FileName, "unofficial/parts/%s.dat", Name);
else else
sprintf(FileName, "%sunofficial/p/%s.dat", mLibraryPath, Name); sprintf(FileName, "unofficial/p/%s.dat", Name);
IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
Found = IncludeFile.Open(FileName, "rt"); Found = IncludeFile.Open(QIODevice::ReadOnly);
} }
if (!Found) if (!Found)
{ {
if (Primitive->mSubFile) if (Primitive->mSubFile)
sprintf(FileName, "%sparts/%s.dat", mLibraryPath, Name); sprintf(FileName, "parts/%s.dat", Name);
else else
sprintf(FileName, "%sp/%s.dat", mLibraryPath, Name); sprintf(FileName, "p/%s.dat", Name);
IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
Found = IncludeFile.Open(FileName, "rt"); Found = IncludeFile.Open(QIODevice::ReadOnly);
} }
if (Found) if (Found)
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize); ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
} }
@ -1956,14 +1925,16 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (mHasUnofficial) if (mHasUnofficial)
{ {
sprintf(FileName, "%sunofficial/parts/%s.dat", mLibraryPath, Name); sprintf(FileName, "unofficial/parts/%s.dat", Name);
Found = IncludeFile.Open(FileName, "rt"); IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
Found = IncludeFile.Open(QIODevice::ReadOnly);
} }
if (!Found) if (!Found)
{ {
sprintf(FileName, "%sparts/%s.dat", mLibraryPath, Name); sprintf(FileName, "parts/%s.dat", Name);
Found = IncludeFile.Open(FileName, "rt"); IncludeFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
Found = IncludeFile.Open(QIODevice::ReadOnly);
} }
if (Found) if (Found)

View file

@ -149,7 +149,7 @@ public:
lcPiecesLibrary(); lcPiecesLibrary();
~lcPiecesLibrary(); ~lcPiecesLibrary();
bool Load(const char* LibraryPath); bool Load(const QString& LibraryPath);
void Unload(); void Unload();
void RemoveTemporaryPieces(); void RemoveTemporaryPieces();
void RemovePiece(PieceInfo* Info); void RemovePiece(PieceInfo* Info);
@ -194,7 +194,7 @@ public:
lcArray<lcTexture*> mTextures; lcArray<lcTexture*> mTextures;
char mLibraryPath[LC_MAXPATH]; QDir mLibraryDir;
bool mBuffersDirty; bool mBuffersDirty;
lcVertexBuffer mVertexBuffer; lcVertexBuffer mVertexBuffer;
@ -204,9 +204,9 @@ signals:
void PartLoaded(PieceInfo* Info); void PartLoaded(PieceInfo* Info);
protected: protected:
bool OpenArchive(const char* FileName, lcZipFileType ZipFileType); bool OpenArchive(const QString& FileName, lcZipFileType ZipFileType);
bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType); bool OpenArchive(lcFile* File, const QString& FileName, lcZipFileType ZipFileType);
bool OpenDirectory(const char* Path); bool OpenDirectory(const QDir& LibraryDir);
void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName); void ReadArchiveDescriptions(const QString& OfficialFileName, const QString& UnofficialFileName);
bool ReadCacheFile(const QString& FileName, lcMemFile& CacheFile); bool ReadCacheFile(const QString& FileName, lcMemFile& CacheFile);
@ -225,8 +225,8 @@ protected:
QString mCachePath; QString mCachePath;
qint64 mArchiveCheckSum[4]; qint64 mArchiveCheckSum[4];
char mLibraryFileName[LC_MAXPATH]; QString mLibraryFileName;
char mUnofficialFileName[LC_MAXPATH]; QString mUnofficialFileName;
lcZipFile* mZipFiles[LC_NUM_ZIPFILES]; lcZipFile* mZipFiles[LC_NUM_ZIPFILES];
bool mHasUnofficial; bool mHasUnofficial;
}; };

View file

@ -11,7 +11,7 @@ lcTexture* lcLoadTexture(const QString& FileName, int Flags)
{ {
lcTexture* Texture = new lcTexture(); lcTexture* Texture = new lcTexture();
if (!Texture->Load(FileName.toLatin1().constData(), Flags)) // todo: qstring if (!Texture->Load(FileName, Flags))
{ {
delete Texture; delete Texture;
Texture = nullptr; Texture = nullptr;
@ -160,7 +160,7 @@ bool lcTexture::Load()
return lcGetPiecesLibrary()->LoadTexture(this); return lcGetPiecesLibrary()->LoadTexture(this);
} }
bool lcTexture::Load(const char* FileName, int Flags) bool lcTexture::Load(const QString& FileName, int Flags)
{ {
Image image; Image image;

View file

@ -25,7 +25,7 @@ public:
void CreateGridTexture(); void CreateGridTexture();
bool Load(const char* FileName, int Flags = 0); bool Load(const QString& FileName, int Flags = 0);
bool Load(lcMemFile& File, int Flags = 0); bool Load(lcMemFile& File, int Flags = 0);
bool Load(Image& image, int Flags); bool Load(Image& image, int Flags);
bool Load(Image* images, int NumLevels, int Flags); bool Load(Image* images, int NumLevels, int Flags);

View file

@ -22,12 +22,12 @@ lcZipFile::~lcZipFile()
delete mFile; delete mFile;
} }
bool lcZipFile::OpenRead(const char* FilePath) bool lcZipFile::OpenRead(const QString& FileName)
{ {
lcDiskFile* File = new lcDiskFile(); lcDiskFile* File = new lcDiskFile(FileName);
mFile = File; mFile = File;
if (!File->Open(FilePath, "rb") || !Open()) if (!File->Open(QIODevice::ReadOnly) || !Open())
{ {
delete File; delete File;
mFile = nullptr; mFile = nullptr;
@ -50,34 +50,22 @@ bool lcZipFile::OpenRead(lcFile* File)
return true; return true;
} }
bool lcZipFile::OpenWrite(const char* FilePath, bool Append) bool lcZipFile::OpenWrite(const QString& FileName)
{ {
lcDiskFile* File = new lcDiskFile(); lcDiskFile* File = new lcDiskFile(FileName);
mFile = File; mFile = File;
if (Append) mNumEntries = 0;
{ mCentralDirSize = 0;
if (!File->Open(FilePath, "r+b") || !Open()) mCentralDirOffset = 0;
{ mBytesBeforeZipFile = 0;
delete File; mCentralPos = 0;
mFile = nullptr;
return false;
}
}
else
{
mNumEntries = 0;
mCentralDirSize = 0;
mCentralDirOffset = 0;
mBytesBeforeZipFile = 0;
mCentralPos = 0;
if (!File->Open(FilePath, "wb")) if (!File->Open(QIODevice::WriteOnly))
{ {
delete File; delete File;
mFile = nullptr; mFile = nullptr;
return false; return false;
}
} }
return true; return true;

View file

@ -53,9 +53,9 @@ public:
lcZipFile(); lcZipFile();
~lcZipFile(); ~lcZipFile();
bool OpenRead(const char* FilePath); bool OpenRead(const QString& FileName);
bool OpenRead(lcFile* File); bool OpenRead(lcFile* File);
bool OpenWrite(const char* FilePath, bool Append); bool OpenWrite(const QString& FileName);
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff); bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
bool ExtractFile(const char* FileName, lcMemFile& File, lcuint32 MaxLength = 0xffffffff); bool ExtractFile(const char* FileName, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);

View file

@ -15,15 +15,10 @@
MinifigWizard::MinifigWizard() MinifigWizard::MinifigWizard()
{ {
char Filename[LC_MAXPATH]; lcDiskFile DiskSettings(lcGetPiecesLibrary()->mLibraryDir.absoluteFilePath(QLatin1String("mlcad.ini")));
strcpy(Filename, lcGetPiecesLibrary()->mLibraryPath);
strcat(Filename, "mlcad.ini");
lcDiskFile DiskSettings; if (DiskSettings.Open(QIODevice::ReadOnly))
if (DiskSettings.Open(Filename, "rt"))
{
ParseSettings(DiskSettings); ParseSettings(DiskSettings);
}
else else
{ {
QResource Resource(":/resources/minifig.ini"); QResource Resource(":/resources/minifig.ini");

View file

@ -445,9 +445,9 @@ void Project::Export3DStudio(const QString& FileName)
if (SaveFileName.isEmpty()) if (SaveFileName.isEmpty())
return; return;
lcDiskFile File; lcDiskFile File(SaveFileName);
if (!File.Open(SaveFileName, "wb")) if (!File.Open(QIODevice::WriteOnly))
{ {
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(FileName)); QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(FileName));
return; return;
@ -892,10 +892,10 @@ void Project::ExportBrickLink()
if (SaveFileName.isEmpty()) if (SaveFileName.isEmpty())
return; return;
lcDiskFile BrickLinkFile; lcDiskFile BrickLinkFile(SaveFileName);
char Line[1024]; char Line[1024];
if (!BrickLinkFile.Open(SaveFileName, "wt")) if (!BrickLinkFile.Open(QIODevice::WriteOnly))
{ {
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return; return;
@ -954,10 +954,10 @@ void Project::ExportCSV()
if (SaveFileName.isEmpty()) if (SaveFileName.isEmpty())
return; return;
lcDiskFile CSVFile; lcDiskFile CSVFile(SaveFileName);
char Line[1024]; char Line[1024];
if (!CSVFile.Open(SaveFileName, "wt")) if (!CSVFile.Open(QIODevice::WriteOnly))
{ {
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return; return;
@ -1357,9 +1357,9 @@ void Project::ExportPOVRay()
if (Dialog.exec() != QDialog::Accepted) if (Dialog.exec() != QDialog::Accepted)
return; return;
lcDiskFile POVFile; lcDiskFile POVFile(Dialog.mFileName);
if (!POVFile.Open(Dialog.mFileName, "wt")) if (!POVFile.Open(QIODevice::WriteOnly))
{ {
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(Dialog.mFileName)); QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(Dialog.mFileName));
return; return;
@ -1392,9 +1392,9 @@ void Project::ExportPOVRay()
if (!Dialog.mLGEOPath.isEmpty()) if (!Dialog.mLGEOPath.isEmpty())
{ {
lcDiskFile TableFile, ColorFile; lcDiskFile TableFile(QFileInfo(QDir(Dialog.mLGEOPath), QLatin1String("lg_elements.lst")).absoluteFilePath());
if (!TableFile.Open(QFileInfo(QDir(Dialog.mLGEOPath), QLatin1String("lg_elements.lst")).absoluteFilePath(), "rt")) if (!TableFile.Open(QIODevice::ReadOnly))
{ {
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(Dialog.mLGEOPath)); QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(Dialog.mLGEOPath));
return; return;
@ -1438,7 +1438,9 @@ void Project::ExportPOVRay()
} }
} }
if (!ColorFile.Open(QFileInfo(QDir(Dialog.mLGEOPath), QLatin1String("lg_colors.lst")).absoluteFilePath(), "rt")) lcDiskFile ColorFile(QFileInfo(QDir(Dialog.mLGEOPath), QLatin1String("lg_colors.lst")).absoluteFilePath());
if (!ColorFile.Open(QIODevice::ReadOnly))
{ {
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(Dialog.mLGEOPath)); QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(Dialog.mLGEOPath));
return; return;
@ -1628,57 +1630,47 @@ void Project::ExportWavefront(const QString& FileName)
return; return;
} }
QString SaveFileName = GetExportFileName(FileName, "obj", tr("Export Wavefront"), tr("Wavefront Files (*.obj);;All Files (*.*)")); QString SaveFileName = GetExportFileName(FileName, QLatin1String("obj"), tr("Export Wavefront"), tr("Wavefront Files (*.obj);;All Files (*.*)"));
if (SaveFileName.isEmpty()) if (SaveFileName.isEmpty())
return; return;
lcDiskFile OBJFile; lcDiskFile OBJFile(SaveFileName);
char Line[1024]; char Line[1024];
if (!OBJFile.Open(SaveFileName, "wt")) if (!OBJFile.Open(QIODevice::WriteOnly))
{ {
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName)); QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return; return;
} }
char buf[LC_MAXPATH], *ptr;
lcuint32 vert = 1; lcuint32 vert = 1;
OBJFile.WriteLine("# Model exported from LeoCAD\n"); OBJFile.WriteLine("# Model exported from LeoCAD\n");
strcpy(buf, SaveFileName.toLatin1().constData()); QFileInfo SaveInfo(SaveFileName);
ptr = strrchr(buf, '.'); QString MaterialFileName = QDir(SaveInfo.absolutePath()).absoluteFilePath(SaveInfo.completeBaseName() + QLatin1String(".mtl"));
if (ptr)
*ptr = 0;
strcat(buf, ".mtl"); sprintf(Line, "#\n\nmtllib %s\n\n", QFileInfo(MaterialFileName).fileName().toLatin1().constData());
ptr = strrchr(buf, '\\');
if (ptr)
ptr++;
else
{
ptr = strrchr(buf, '/');
if (ptr)
ptr++;
else
ptr = buf;
}
sprintf(Line, "#\n\nmtllib %s\n\n", ptr);
OBJFile.WriteLine(Line); OBJFile.WriteLine(Line);
FILE* mat = fopen(buf, "wt"); lcDiskFile MaterialFile(MaterialFileName);
fputs("# Colors used by LeoCAD\n\n", mat); if (!MaterialFile.Open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(MaterialFileName));
return;
}
MaterialFile.WriteLine("# Colors used by LeoCAD\n\n");
for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++) for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++)
{ {
lcColor* Color = &gColorList[ColorIdx]; lcColor* Color = &gColorList[ColorIdx];
if (Color->Translucent) if (Color->Translucent)
fprintf(mat, "newmtl %s\nKd %.2f %.2f %.2f\nD %.2f\n\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2], Color->Value[3]); sprintf(Line, "newmtl %s\nKd %.2f %.2f %.2f\nD %.2f\n\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2], Color->Value[3]);
else else
fprintf(mat, "newmtl %s\nKd %.2f %.2f %.2f\n\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]); sprintf(Line, "newmtl %s\nKd %.2f %.2f %.2f\n\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
MaterialFile.WriteLine(Line);
} }
fclose(mat);
for (int PartIdx = 0; PartIdx < ModelParts.GetSize(); PartIdx++) for (int PartIdx = 0; PartIdx < ModelParts.GetSize(); PartIdx++)
{ {