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

+ 2 - 1
Docs/ScriptAPI.dox

@@ -1559,7 +1559,7 @@ Properties:
 Methods:
 
 - void SendEvent(const String&, VariantMap& = VariantMap ( ))
-- bool Open(const String&) const
+- bool Open(const String&, uint = 0) const
 - bool Exists(const String&) const
 - bool compressed() const
 
@@ -3730,6 +3730,7 @@ Properties:
 - String windowTitle
 - IntVector2 windowPosition
 - bool sRGB
+- bool flushGPU
 - int width (readonly)
 - int height (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),
     totalSize_(0),
     checksum_(0),
     compressed_(false)
 {
-    Open(fileName);
+    Open(fileName, startOffset);
 }
 
 PackageFile::~PackageFile()
 {
 }
 
-bool PackageFile::Open(const String& fileName)
+bool PackageFile::Open(const String& fileName, unsigned startOffset)
 {
     #ifdef ANDROID
     if (fileName.StartsWith("/apk/"))
@@ -64,11 +64,30 @@ bool PackageFile::Open(const String& fileName)
         return false;
     
     // Check ID, then read the directory
+    file->Seek(startOffset);
     String id = file->ReadFileID();
     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;
@@ -83,7 +102,7 @@ bool PackageFile::Open(const String& fileName)
     {
         String entryName = file->ReadString();
         PackageEntry newEntry;
-        newEntry.offset_ = file->ReadUInt();
+        newEntry.offset_ = file->ReadUInt() + startOffset;
         newEntry.size_ = file->ReadUInt();
         newEntry.checksum_ = file->ReadUInt();
         if (!compressed_ && newEntry.offset_ + newEntry.size_ > totalSize_)

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

@@ -47,12 +47,12 @@ public:
     /// Construct.
     PackageFile(Context* context);
     /// Construct and open.
-    PackageFile(Context* context, const String& fileName);
+    PackageFile(Context* context, const String& fileName, unsigned startOffset = 0);
     /// Destruct.
     virtual ~PackageFile();
     
     /// 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.
     bool Exists(const String& fileName) const;
     /// 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
 {
     PackageFile(Context* context);
-    PackageFile(Context* context, const String fileName);
+    PackageFile(Context* context, const String fileName, unsigned startOffset = 0);
     ~PackageFile();
     
-    bool Open(const String fileName);
+    bool Open(const String fileName, unsigned startOffset = 0);
     bool Exists(const String fileName) const;
     const PackageEntry* GetEntry(const String fileName) 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());
 }
 
-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)
 {
     RegisterObject<PackageFile>(engine, "PackageFile");
     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", "const String& get_name() const", asMETHOD(PackageFile, GetName), 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
     dest.Seek(0);
     WriteHeader(dest);