Browse Source

Write package file size to the end of package files. If package signature is not found from the file beginning, seek to file end and read the size, then seek backward to check if the package file is concatenated eg. in the executable. Alternatively the start offset can be specified manually when opening a package file. Closes #27.

Lasse Öörni 12 years ago
parent
commit
02df5b2d02

+ 5 - 2
Docs/LuaScriptAPI.dox

@@ -1498,6 +1498,7 @@ Methods:
 - bool SetMode(int width, int height, bool fullscreen, bool resizable, bool vsync, bool tripleBuffer, int multiSample)
 - bool SetMode(int width, int height, bool fullscreen, bool resizable, bool vsync, bool tripleBuffer, int multiSample)
 - bool SetMode(int width, int height)
 - bool SetMode(int width, int height)
 - void SetSRGB(bool enable)
 - void SetSRGB(bool enable)
+- void SetFlushGPU(bool enable)
 - bool ToggleFullscreen()
 - bool ToggleFullscreen()
 - void Close()
 - void Close()
 - bool TakeScreenShot(Image& destImage)
 - bool TakeScreenShot(Image& destImage)
@@ -1513,6 +1514,7 @@ Methods:
 - bool GetVSync() const
 - bool GetVSync() const
 - bool GetTripleBuffer() const
 - bool GetTripleBuffer() const
 - bool GetSRGB() const
 - bool GetSRGB() const
+- bool GetFlushGPU() const
 - bool IsDeviceLost() const
 - bool IsDeviceLost() const
 - unsigned GetNumPrimitives() const
 - unsigned GetNumPrimitives() const
 - unsigned GetNumBatches() const
 - unsigned GetNumBatches() const
@@ -1543,6 +1545,7 @@ Properties:
 - bool vSync (readonly)
 - bool vSync (readonly)
 - bool tripleBuffer (readonly)
 - bool tripleBuffer (readonly)
 - bool sRGB
 - bool sRGB
+- bool flushGPU
 - bool deviceLost (readonly)
 - bool deviceLost (readonly)
 - unsigned numPrimitives (readonly)
 - unsigned numPrimitives (readonly)
 - unsigned numBatches (readonly)
 - unsigned numBatches (readonly)
@@ -2646,9 +2649,9 @@ Properties:
 Methods:
 Methods:
 
 
 - PackageFile(Context* context)
 - PackageFile(Context* context)
-- PackageFile(Context* context, const String fileName)
+- PackageFile(Context* context, const String fileName, unsigned startOffset = 0)
 - ~PackageFile()
 - ~PackageFile()
-- bool Open(const String fileName)
+- bool Open(const String fileName, unsigned startOffset = 0)
 - bool Exists(const String fileName) const
 - bool Exists(const String fileName) const
 - const PackageEntry* GetEntry(const String fileName) const
 - const PackageEntry* GetEntry(const String fileName) const
 - const HashMap<String, PackageEntry>& GetEntries() const
 - const HashMap<String, PackageEntry>& GetEntries() const

+ 2 - 1
Docs/ScriptAPI.dox

@@ -1559,7 +1559,7 @@ Properties:
 Methods:
 Methods:
 
 
 - void SendEvent(const String&, VariantMap& = VariantMap ( ))
 - void SendEvent(const String&, VariantMap& = VariantMap ( ))
-- bool Open(const String&) const
+- bool Open(const String&, uint = 0) const
 - bool Exists(const String&) const
 - bool Exists(const String&) const
 - bool compressed() const
 - bool compressed() const
 
 
@@ -3730,6 +3730,7 @@ Properties:
 - String windowTitle
 - String windowTitle
 - IntVector2 windowPosition
 - IntVector2 windowPosition
 - bool sRGB
 - bool sRGB
+- bool flushGPU
 - int width (readonly)
 - int width (readonly)
 - int height (readonly)
 - int height (readonly)
 - int multiSample (readonly)
 - int multiSample (readonly)

+ 25 - 6
Source/Engine/IO/PackageFile.cpp

@@ -36,20 +36,20 @@ PackageFile::PackageFile(Context* context) :
 {
 {
 }
 }
 
 
-PackageFile::PackageFile(Context* context, const String& fileName) :
+PackageFile::PackageFile(Context* context, const String& fileName, unsigned startOffset) :
     Object(context),
     Object(context),
     totalSize_(0),
     totalSize_(0),
     checksum_(0),
     checksum_(0),
     compressed_(false)
     compressed_(false)
 {
 {
-    Open(fileName);
+    Open(fileName, startOffset);
 }
 }
 
 
 PackageFile::~PackageFile()
 PackageFile::~PackageFile()
 {
 {
 }
 }
 
 
-bool PackageFile::Open(const String& fileName)
+bool PackageFile::Open(const String& fileName, unsigned startOffset)
 {
 {
     #ifdef ANDROID
     #ifdef ANDROID
     if (fileName.StartsWith("/apk/"))
     if (fileName.StartsWith("/apk/"))
@@ -64,11 +64,30 @@ bool PackageFile::Open(const String& fileName)
         return false;
         return false;
     
     
     // Check ID, then read the directory
     // Check ID, then read the directory
+    file->Seek(startOffset);
     String id = file->ReadFileID();
     String id = file->ReadFileID();
     if (id != "UPAK" && id != "ULZ4")
     if (id != "UPAK" && id != "ULZ4")
     {
     {
-        LOGERROR(fileName + " is not a valid package file");
-        return false;
+        // If start offset has not been explicitly specified, also try to read package size from the end of file
+        // to know how much we must rewind to find the package start
+        if (!startOffset)
+        {
+            unsigned fileSize = file->GetSize();
+            file->Seek(fileSize - sizeof(unsigned));
+            unsigned newStartOffset = fileSize - file->ReadUInt();
+            if (newStartOffset < fileSize)
+            {
+                startOffset = newStartOffset;
+                file->Seek(startOffset);
+                id = file->ReadFileID();
+            }
+        }
+        
+        if (id != "UPAK" && id != "ULZ4")
+        {
+            LOGERROR(fileName + " is not a valid package file");
+            return false;
+        }
     }
     }
     
     
     fileName_ = fileName;
     fileName_ = fileName;
@@ -83,7 +102,7 @@ bool PackageFile::Open(const String& fileName)
     {
     {
         String entryName = file->ReadString();
         String entryName = file->ReadString();
         PackageEntry newEntry;
         PackageEntry newEntry;
-        newEntry.offset_ = file->ReadUInt();
+        newEntry.offset_ = file->ReadUInt() + startOffset;
         newEntry.size_ = file->ReadUInt();
         newEntry.size_ = file->ReadUInt();
         newEntry.checksum_ = file->ReadUInt();
         newEntry.checksum_ = file->ReadUInt();
         if (!compressed_ && newEntry.offset_ + newEntry.size_ > totalSize_)
         if (!compressed_ && newEntry.offset_ + newEntry.size_ > totalSize_)

+ 2 - 2
Source/Engine/IO/PackageFile.h

@@ -47,12 +47,12 @@ public:
     /// Construct.
     /// Construct.
     PackageFile(Context* context);
     PackageFile(Context* context);
     /// Construct and open.
     /// Construct and open.
-    PackageFile(Context* context, const String& fileName);
+    PackageFile(Context* context, const String& fileName, unsigned startOffset = 0);
     /// Destruct.
     /// Destruct.
     virtual ~PackageFile();
     virtual ~PackageFile();
     
     
     /// Open the package file. Return true if successful.
     /// Open the package file. Return true if successful.
-    bool Open(const String& fileName);
+    bool Open(const String& fileName, unsigned startOffset = 0);
     /// Check if a file exists within the package file.
     /// Check if a file exists within the package file.
     bool Exists(const String& fileName) const;
     bool Exists(const String& fileName) const;
     /// Return the file entry corresponding to the name, or null if not found.
     /// Return the file entry corresponding to the name, or null if not found.

+ 2 - 2
Source/Engine/LuaScript/pkgs/IO/PackageFile.pkg

@@ -10,10 +10,10 @@ struct PackageEntry
 class PackageFile : public Object
 class PackageFile : public Object
 {
 {
     PackageFile(Context* context);
     PackageFile(Context* context);
-    PackageFile(Context* context, const String fileName);
+    PackageFile(Context* context, const String fileName, unsigned startOffset = 0);
     ~PackageFile();
     ~PackageFile();
     
     
-    bool Open(const String fileName);
+    bool Open(const String fileName, unsigned startOffset = 0);
     bool Exists(const String fileName) const;
     bool Exists(const String fileName) const;
     const PackageEntry* GetEntry(const String fileName) const;
     const PackageEntry* GetEntry(const String fileName) const;
     const HashMap<String, PackageEntry>& GetEntries() const;
     const HashMap<String, PackageEntry>& GetEntries() const;

+ 4 - 4
Source/Engine/Script/IOAPI.cpp

@@ -345,17 +345,17 @@ static PackageFile* ConstructPackageFile()
     return new PackageFile(GetScriptContext());
     return new PackageFile(GetScriptContext());
 }
 }
 
 
-static PackageFile* ConstructAndOpenPackageFile(const String& fileName)
+static PackageFile* ConstructAndOpenPackageFile(const String& fileName, unsigned startOffset)
 {
 {
-    return new PackageFile(GetScriptContext(), fileName);
+    return new PackageFile(GetScriptContext(), fileName, startOffset);
 }
 }
 
 
 static void RegisterPackageFile(asIScriptEngine* engine)
 static void RegisterPackageFile(asIScriptEngine* engine)
 {
 {
     RegisterObject<PackageFile>(engine, "PackageFile");
     RegisterObject<PackageFile>(engine, "PackageFile");
     engine->RegisterObjectBehaviour("PackageFile", asBEHAVE_FACTORY, "PackageFile@+ f()", asFUNCTION(ConstructPackageFile), asCALL_CDECL);
     engine->RegisterObjectBehaviour("PackageFile", asBEHAVE_FACTORY, "PackageFile@+ f()", asFUNCTION(ConstructPackageFile), asCALL_CDECL);
-    engine->RegisterObjectBehaviour("PackageFile", asBEHAVE_FACTORY, "PackageFile@+ f(const String&in)", asFUNCTION(ConstructAndOpenPackageFile), asCALL_CDECL);
-    engine->RegisterObjectMethod("PackageFile", "bool Open(const String&in) const", asMETHOD(PackageFile, Open), asCALL_THISCALL);
+    engine->RegisterObjectBehaviour("PackageFile", asBEHAVE_FACTORY, "PackageFile@+ f(const String&in, uint startOffset = 0)", asFUNCTION(ConstructAndOpenPackageFile), asCALL_CDECL);
+    engine->RegisterObjectMethod("PackageFile", "bool Open(const String&in, uint startOffset = 0) const", asMETHOD(PackageFile, Open), asCALL_THISCALL);
     engine->RegisterObjectMethod("PackageFile", "bool Exists(const String&in) const", asMETHOD(PackageFile, Exists), asCALL_THISCALL);
     engine->RegisterObjectMethod("PackageFile", "bool Exists(const String&in) const", asMETHOD(PackageFile, Exists), asCALL_THISCALL);
     engine->RegisterObjectMethod("PackageFile", "const String& get_name() const", asMETHOD(PackageFile, GetName), asCALL_THISCALL);
     engine->RegisterObjectMethod("PackageFile", "const String& get_name() const", asMETHOD(PackageFile, GetName), asCALL_THISCALL);
     engine->RegisterObjectMethod("PackageFile", "uint get_numFiles() const", asMETHOD(PackageFile, GetNumFiles), asCALL_THISCALL);
     engine->RegisterObjectMethod("PackageFile", "uint get_numFiles() const", asMETHOD(PackageFile, GetNumFiles), asCALL_THISCALL);

+ 4 - 0
Source/Tools/PackageTool/PackageTool.cpp

@@ -236,6 +236,10 @@ void WritePackageFile(const String& fileName, const String& rootDir)
         }
         }
     }
     }
     
     
+    // Write package size to the end of file to allow finding it linked to an executable file
+    unsigned currentSize = dest.GetSize();
+    dest.WriteUInt(currentSize + sizeof(unsigned));
+    
     // Write header again with correct offsets & checksums
     // Write header again with correct offsets & checksums
     dest.Seek(0);
     dest.Seek(0);
     WriteHeader(dest);
     WriteHeader(dest);