Script loading via physfs which doesn't work: physfslayer
authorunc0rr
Fri, 16 Nov 2012 00:46:33 +0400
branchphysfslayer
changeset 8031 fc40b343c45c
parent 8028 dc30104660d3
child 8034 fc032c0f7b23
Script loading via physfs which doesn't work: - Some scripts just refuse to load for no obvious reason - Some scripts load fine when you set BUFSIZE to a large value, like 64k, but don't load with small values Error messages in both cases don't seem to have relation to lua file contents
hedgewars/uPhysFSLayer.pas
hedgewars/uScript.pas
--- a/hedgewars/uPhysFSLayer.pas	Wed Nov 14 23:27:33 2012 +0400
+++ b/hedgewars/uPhysFSLayer.pas	Fri Nov 16 00:46:33 2012 +0400
@@ -15,10 +15,13 @@
 function rwopsOpenWrite(fname: shortstring): PSDL_RWops;
 
 function pfsOpenRead(fname: shortstring): PFSFile;
-function pfsEOF(f: PFSFile): boolean;
 function pfsClose(f: PFSFile): boolean;
 
 procedure pfsReadLn(f: PFSFile; var s: shortstring);
+function pfsBlockRead(f: PFSFile; buf: pointer; size: Int64): Int64;
+function pfsEOF(f: PFSFile): boolean;
+
+function pfsExists(fname: shortstring): boolean;
 
 implementation
 uses uUtils, uVariables;
@@ -31,8 +34,9 @@
 function PHYSFS_mount(newDir, mountPoint: PChar; appendToPath: LongBool) : LongInt; cdecl; external;
 function PHYSFS_openRead(fname: PChar): PFSFile; cdecl; external;
 function PHYSFS_eof(f: PFSFile): LongBool; cdecl; external;
-function PHYSFS_read(f: PFSFile; buf: pointer; objSize, objCount: Longword): Int64; cdecl; external;
+function PHYSFS_read(f: PFSFile; buf: pointer; objSize: Longword; objCount: Longword): Int64; cdecl; external;
 function PHYSFS_close(f: PFSFile): LongBool; cdecl; external;
+function PHYSFS_exists(fname: PChar): LongBool; cdecl; external;
 
 function rwopsOpenRead(fname: shortstring): PSDL_RWops;
 begin
@@ -59,6 +63,11 @@
     exit(PHYSFS_close(f))
 end;
 
+function pfsExists(fname: shortstring): boolean;
+begin
+    exit(PHYSFS_exists(Str2PChar(fname)))
+end;
+
 
 procedure pfsReadLn(f: PFSFile; var s: shortstring);
 var c: char;
@@ -73,6 +82,17 @@
         end
 end;
 
+function pfsBlockRead(f: PFSFile; buf: pointer; size: Int64): Int64;
+var r: Int64;
+begin
+    r:= PHYSFS_read(f, buf, 1, size);
+
+    if r <= 0 then
+        pfsBlockRead:= 0
+    else
+        pfsBlockRead:= r
+end;
+
 procedure initModule;
 var i: LongInt;
 begin
@@ -81,7 +101,7 @@
 
     i:= PHYSFS_mount(Str2PChar(PathPrefix), nil, true);
     AddFileLog('[PhysFS] mount ' + PathPrefix + ': ' + inttostr(i));
-    i:= PHYSFS_mount(Str2PChar(UserPathPrefix), nil, true);
+    i:= PHYSFS_mount(Str2PChar(UserPathPrefix + '/Data'), nil, true);
     AddFileLog('[PhysFS] mount ' + UserPathPrefix + ': ' + inttostr(i));
 end;
 
--- a/hedgewars/uScript.pas	Wed Nov 14 23:27:33 2012 +0400
+++ b/hedgewars/uScript.pas	Fri Nov 16 00:46:33 2012 +0400
@@ -81,7 +81,9 @@
     uLandGraphics,
     SDLh,
     SysUtils, 
-    uIO;
+    uIO,
+    uPhysFSLayer
+    ;
 
 var luaState : Plua_State;
     ScriptAmmoLoadout : shortstring;
@@ -1964,16 +1966,46 @@
 ScriptCall('onScreenResize');
 end;
 
+// custom script loader via physfs, passed to lua_load
+const BUFSIZE = 16;
+var phyfsReaderBuffer: pointer;
+
+function physfsReader(L: Plua_State; f: PFSFile; sz: Psize_t) : PChar; cdecl;
+var fileSize: Longword;
+begin
+writeln(stdout, '==== reading');
+    if pfsEOF(f) then
+        physfsReader:= nil
+    else
+        begin
+        sz^:= pfsBlockRead(f, phyfsReaderBuffer, BUFSIZE);
+writeln(stdout, '==== read ' + inttostr(sz^));
+        if sz^ = 0 then
+            physfsReader:= nil
+        else
+            physfsReader:= phyfsReaderBuffer
+        end
+end;
+
 
 procedure ScriptLoad(name : shortstring);
 var ret : LongInt;
       s : shortstring;
+      f : PFSFile;
 begin
-s:= cPathz[ptData] + '/' + name;
-if not FileExists(s) then
+s:= cPathz[ptData] + name;
+if not pfsExists(s) then
     exit;
 
-ret:= luaL_loadfile(luaState, Str2PChar(s));
+f:= pfsOpenRead(s);
+if f = nil then 
+    exit;
+
+GetMem(phyfsReaderBuffer, BUFSIZE);
+ret:= lua_load(luaState, @physfsReader, f, Str2PChar(s));
+FreeMem(phyfsReaderBuffer, BUFSIZE);
+pfsClose(f);
+
 if ret <> 0 then
     begin
     LuaError('Lua: Failed to load ' + name + '(error ' + IntToStr(ret) + ')');