瀏覽代碼

pak large file support (>2GB) - req hl 1.12

Nicolas Cannasse 5 年之前
父節點
當前提交
c51fa4ee1f
共有 5 個文件被更改,包括 37 次插入13 次删除
  1. 9 7
      hxd/fmt/pak/Build.hx
  2. 1 1
      hxd/fmt/pak/Data.hx
  3. 20 3
      hxd/fmt/pak/FileSystem.hx
  4. 1 1
      hxd/fmt/pak/Reader.hx
  5. 6 1
      hxd/fmt/pak/Writer.hx

+ 9 - 7
hxd/fmt/pak/Build.hx

@@ -4,7 +4,7 @@ import hxd.fmt.pak.Data;
 class Build {
 
 	var fs : hxd.fs.LocalFileSystem;
-	var out : { bytes : Array<haxe.io.Bytes>, size : Int };
+	var out : { bytes : Array<haxe.io.Bytes>, size : Float };
 	var configuration : String;
 
 	public var excludedExt : Array<String> = [];
@@ -102,13 +102,13 @@ class Build {
 		}
 		calcRec(pak.root);
 		var out = [];
-		var pos = 0;
+		var pos = 0.;
 		function writeRec(f:File) {
 			if( f.isDirectory ) {
 				for( c in f.content )
 					writeRec(c);
 			} else {
-				out.push(bytes[f.dataPosition]);
+				out.push(bytes[Std.int(f.dataPosition)]);
 				f.dataPosition = pos;
 				pos += f.dataSize;
 			}
@@ -177,8 +177,8 @@ class Build {
 			switch( f ) {
 			case "-x" if( args.length > 0 ):
 				var pakFile = args.shift();
-				var bytes = sys.io.File.getBytes(pakFile);
-				var pak = new hxd.fmt.pak.Reader(new haxe.io.BytesInput(bytes)).readHeader();
+				var fs = sys.io.File.read(pakFile);
+				var pak = new hxd.fmt.pak.Reader(fs).readHeader();
 				var baseDir = pakFile.substr(0,-4);
 				function extractRec(f:hxd.fmt.pak.Data.File, dir) {
 					if( f.isDirectory ) {
@@ -187,7 +187,9 @@ class Build {
 						for( c in f.content )
 							extractRec(c,dir);
 					} else {
-						sys.io.File.saveBytes(dir+"/"+f.name,bytes.sub(pak.headerSize + f.dataPosition,f.dataSize));
+						// todo : seek large
+						fs.seek(Std.int(f.dataPosition+pak.headerSize), SeekBegin);
+						sys.io.File.saveBytes(dir+"/"+f.name,fs.read(f.dataSize));
 					}
 				}
 				extractRec(pak.root, baseDir);
@@ -211,7 +213,7 @@ class Build {
 		}
 		if( b.outPrefix == null ) {
 			b.outPrefix = "res";
-			if( b.configuration != "default" ) b.outPrefix += "."+b.configuration;
+			if( b.configuration != "default" && b.configuration != null ) b.outPrefix += "."+b.configuration;
 		}
 		b.makePak();
 	}

+ 1 - 1
hxd/fmt/pak/Data.hx

@@ -4,7 +4,7 @@ class File {
 	public var name : String;
 	public var isDirectory : Bool;
 	public var content : Array<File>;
-	public var dataPosition : Int;
+	public var dataPosition : Float;
 	public var dataSize : Int;
 	public var checksum : Int;
 	public function new() {

+ 20 - 3
hxd/fmt/pak/FileSystem.hx

@@ -60,8 +60,25 @@ private class PakEntry extends FileEntry {
 		return file.isDirectory;
 	}
 
+	#if (hl && hl_ver >= version("1.12.0"))
+	@:hlNative("std","file_seek2") static function seek2( f : sys.io.File.FileHandle, pos : Float, cur : Int ) : Bool { return false; }
+	#end
+
+	function setPos() {
+		if( file.dataPosition > 0x7FFFFFFF ) {
+			#if (hl && hl_ver >= version("1.12.0"))
+			if( !seek2(@:privateAccess pak.__f,file.dataPosition,0) )
+				throw haxe.io.Error.Custom("seek() failure");
+			#else
+			throw "PAK file is too large: max 2GB or compile with -D hl_ver=1.12.0";
+			#end
+			return;
+		}
+		pak.seek(Std.int(file.dataPosition), SeekBegin);
+	}
+
 	override function getSign() {
-		pak.seek(file.dataPosition, SeekBegin);
+		setPos();
 		fs.totalReadBytes += 4;
 		fs.totalReadCount++;
 		return pak.readInt32();
@@ -70,7 +87,7 @@ private class PakEntry extends FileEntry {
 	override function getBytes() {
 		if( cachedBytes != null )
 			return cachedBytes;
-		pak.seek(file.dataPosition, SeekBegin);
+		setPos();
 		fs.totalReadBytes += file.dataSize;
 		fs.totalReadCount++;
 		return pak.read(file.dataSize);
@@ -83,7 +100,7 @@ private class PakEntry extends FileEntry {
 			fs.totalReadBytes += file.dataSize;
 			fs.totalReadCount++;
 			openedBytes = haxe.io.Bytes.alloc(file.dataSize);
-			pak.seek(file.dataPosition, SeekBegin);
+			setPos();
 			pak.readBytes(openedBytes, 0, file.dataSize);
 		}
 		bytesPosition = 0;

+ 1 - 1
hxd/fmt/pak/Reader.hx

@@ -34,7 +34,7 @@ class Reader {
 			for( i in 0...i.readInt32() )
 				f.content.push(readFile());
 		} else {
-			f.dataPosition = i.readInt32();
+			f.dataPosition = flags & 2 != 0 ? i.readDouble() : i.readInt32();
 			f.dataSize = i.readInt32();
 			f.checksum = i.readInt32();
 		}

+ 6 - 1
hxd/fmt/pak/Writer.hx

@@ -14,13 +14,18 @@ class Writer {
 		o.writeString(f.name);
 		var flags = 0;
 		if( f.isDirectory ) flags |= 1;
+		var p = Std.int(f.dataPosition);
+		if( p != f.dataPosition ) flags |= 2;
 		o.writeByte(flags);
 		if( f.isDirectory ) {
 			o.writeInt32(f.content.length);
 			for( f in f.content )
 				writeFile(f);
 		} else {
-			o.writeInt32(f.dataPosition);
+			if( p == f.dataPosition )
+				o.writeInt32(p);
+			else
+				o.writeDouble(f.dataPosition);
 			o.writeInt32(f.dataSize);
 			o.writeInt32(f.checksum);
 		}