#100 ZIP file support

open
nobody
None
5
2012-09-07
2005-07-18
`Moe`
No

This patch adds ZIP file support via PHYSFS. You need to have PHYSFS 1.0 installed (http://icculus.org/physfs/). Usage is quite simple:

mount c mygame.zip:/

mounts the contents of mygame.zip as c:

mount c c:\temp:mygame.zip:/

mounts c:\temp and mygame.zip as c: (files are merged), and all write accesses go to c:\temp.

mount c mygame.zip:/gamedir

mounts the folder "gamedir" inside mygame.zip as c:

general syntax of mount stays the same, -label and -size are supported, -type not (yet - will come)

The source file(s) are specified this way:

<file>:<file>:<file>:...:<base directory="">

where <file> is anything PHYSFS supports (directories, ZIP-files, and some less known game-specific formats). The very first file/directory will be used as write directory, if possible.

For now, you should mount only one drive with PHYSFS. It is possible to mount more than one, but it won't do what you expect. Under construction...

Oh, this patch also fixes two bugs with local drives.

Discussion

  • TaeWoong Yoo
    TaeWoong Yoo
    2005-07-18

    Logged In: YES
    user_id=844698

    To install PHYSFS in MinGW/MSYS, look at this link.
    http://www.libsdl.org/pipermail/sdl/2004-
    November/065727.html

     
  • `Moe`
    `Moe`
    2005-07-18

    Logged In: YES
    user_id=1045474

    Updated version: -t floppy/hdd/cdrom now works as expected. Fixed a little bug with creating files. mount syntax parsing got more robust.

    A little update on usage (was pretty tired last time ;):

    USAGE:

    The basic mount syntax hasn't changed. All PHYSFS configuration happens through the "src-directory" part of the mount command line.

    mount uses physfs when it encounters a colon (:) in the source directory, and it's not the colon after a drive letter. So, mounting "x.zip:\" uses physfs, while mounting "c:\" works like before.

    The source directory is split at every colon. The very last part is a path inside the physfs virtual filesystem which should be mounted as the drive's root directory. Mounting "x.zip:/" as drive c will make all contents of x.zip available via c:, while mounting "x.zip:/civ" will only make the files in subdirectory "civ" in x.zip available.

    All other parts are added to the physfs search path. Mounting "x.zip:/" means physfs will look in x.zip only. Mounting "x.zip:y.zip:/" means physfs will look in x.zip first, and if a file isn't found, it will look in y.zip. The net effect is the same as if you extracted y.zip, then x.zip (overwriting any existing files) and mounted that directory.

    Physfs supports more than just ZIP-files. You can mount some strange game-specific files as well (you'll probably not need this ever), and plain directories. The same rules apply to directories, so mounting "c:\:d:\:\" means all contents of C and D are available as if you copied the whole drive C to D (overwriting existing files) and mounted that instead.

    Of course, mixing is also possible. Mount "x.zip:y.zip:c:\:\" and it looks as if you extracted y.zip, then x.zip to c:.

    Finally, write accesses have to go somewhere. physfs uses a single write directory for all write accesses. The very first part of a source specification is set as write directory (if possible), so mounting "x.zip:/" will make all write accesses fail (no support for writing to ZIP), but mounting "c:\out:x.zip:\" will set "c:\out" as the write directory. Any file that's in there is used. Anything else is taken from x.zip. Short story: If you save a game, things work as expected.

    LIMITATIONS:

    Short: If you want your config files to work even when physfs-2.0 is out, do not mount more than one drive via physfs.

    Long: It is perfectly supported to mount more than one drive via physfs, but the current semantics will change with physfs-2.0 due to missing features in the current physfs-1.0. OTOH, I guess physfs-2.0 is still far away, so feel free to use the current semantics.

    Basically, if you mount a zip file, it will be available on all physfs drives.

    mount c x.zip:/
    mount d y.zip:/

    is the same as

    mount c x.zip:y.zip:/
    mount d x.zip:y.zip:/

    is the same as

    mount c x.zip:y.zip:/
    mount d :/

    Note the last mount: shorthand for "use physfs, don't add anything new"

    You may think this is rather useless, but imagine your game needs C as hard disk and D as CD-ROM. Create two dirs, "c" and "d", put the needed files in, zip them up into one zip file including path names. Then do these mounts:

    mount c game.zip:/c
    mount d :/d -t cdrom

    If you do this, i.e. only the very first mount contains any zip-files/directories, and all other mounts use the shorthand syntax, I will try to ensure it will work even when physfs-2.0 is out.

    Physfs-2.0 will support mounting different zip-files for different drives with no sharing.

     
  • TaeWoong Yoo
    TaeWoong Yoo
    2005-07-18

    Logged In: YES
    user_id=844698

    An error occured though I had installed PHYSFS.

    rm -f ".deps/drive_cache.Tpo"; exit 1; fi
    drive_cache.cpp: In member function `void
    DOS_Drive_Cache::SetBaseDir(const char, DOS_Drive)':
    drive_cache.cpp:161: error: declaration of 'char drive[4]'
    shadows a parameter
    make[3]: *** [drive_cache.o] Error 1


     
  • `Moe`
    `Moe`
    2005-07-18

    Logged In: YES
    user_id=1045474

    Oh, some more notes I forgot:

    • There are a few things on the TODO, "grep TODO drive_physfs.cpp". No show-stoppers - I haven't found a game breaking yet.

    • For maximum ZIP compression, get KZIP.EXE from http://advsys.net/ken/utils.htm, a command-line zip archiver with compression ratio even superior to 7-zip's ZIP mode. Freeware, not open-source, Windows-only, but runs with Wine.

    • The two bugs that were fixed are: a problem with dirCache.AddEntry in localDrive::FileCreate, and a corrected return value for localDrive::Mkdir.

    • Additionally, the patch improves the drives API by making most char* pointers const (leads to better optimizability anywhere drives are used), and moving a few member functions around for more stable inheritance and crash-proofness (not related to my other crash fix patch).

     
  • `Moe`
    `Moe`
    2005-07-18

    Logged In: YES
    user_id=1045474

    Next version: fix win32 compilation bug. note that I didn't test it on win32 yet, although it should work.

     
  • `Moe`
    `Moe`
    2005-07-19

    Logged In: YES
    user_id=1045474

    New version: Added the possibility to specify physfs sources on the dosbox command line. "dosbox x.zip:/" will do the same as if you extracted x.zip into subdir "x" and ran "dosbox x", i.e. it executes "mount c x.zip:/" automatically.

     
  • `Moe`
    `Moe`
    2005-07-20

    Logged In: YES
    user_id=1045474

    Next version, this time with proper copy-on-write support. Handles files opened read-write much more intelligent.

     
  • `Moe`
    `Moe`
    2005-07-21

    Logged In: YES
    user_id=1045474

    Next version: Who is responsible for making DOS_File::Seek's first parameter unsigned? (read: fixed a bug with negative seek offsets)

     
  • `Moe`
    `Moe`
    2005-07-22

    Logged In: YES
    user_id=1045474

    Next version: Another seek bug. (SEEK_END, my very own personal fault ;)

    It now runs all games tested so far, and without noticeable delays. (Well, sometimes noticeable, but barely)

     
  • `Moe`
    `Moe`
    2005-07-23

    Logged In: YES
    user_id=1045474

    Phew, we're getting closer: Copy-on-write works correctly, but the "no need ot copy" case was broken.

    Current stats: 21 games ranging from 200kb to 600MB, 1988 - 1996, all working fine, perfectly playable as if they were extracted.

     
  • `Moe`
    `Moe`
    2005-07-23

    Logged In: YES
    user_id=1045474

    Seems like we're bug-free now. This time I found a bug in PhysFS ;)

    If you get an empty directory in a zip file, where files should be in, use this patch against physfs-1.0.0.

    diff -ru physfs-1.0.0-orig/archivers/zip.c physfs-1.0.0/archivers/zip.c
    --- physfs-1.0.0-orig/archivers/zip.c 2003-07-21 00:05:21.000000000 +0200
    +++ physfs-1.0.0/archivers/zip.c 2005-07-23 20:08:10.000000000 +0200
    @@ -1209,9 +1209,9 @@
    {
    char ch = name[dlen];
    if (ch < '/') / make sure this isn't just a substr match. /
    - rc = -1;
    - else if (ch > '/')
    rc = 1;
    + else if (ch > '/')
    + rc = -1;
    else
    {
    if (stop_on_first_find) / Just checking dir's existance? /

    But it occurs only under very special circumstances, so unless you're running "Settlers 2" from a ZIP file, you should be safe.

    I've attached a new version of the patch nevertheless, no new features, just some cleanups.

     
  • TaeWoong Yoo
    TaeWoong Yoo
    2005-08-01

    Logged In: YES
    user_id=844698

    When I type "dir /w" on command prompt,
    one or more lines appeared with spaces.

     
  • TaeWoong Yoo
    TaeWoong Yoo
    2005-08-01

    Logged In: YES
    user_id=844698

    ah... mistake;
    I had to write the comment about 'dir /w problem'
    in console output.

     
  • `Moe`
    `Moe`
    2005-08-01

    Logged In: YES
    user_id=1045474

    I don't understand, but from our chat I conclude what you reported didn't apply to this patch.

    Sidenote: This patch is still free of known bugs, going through my collection didn't reveal more. Physfs has been released in version 1.0.1, fixing the mentioned bug.

     
  • TaeWoong Yoo
    TaeWoong Yoo
    2005-08-02

    Logged In: YES
    user_id=844698

    No, this patch has no problem I found.
    I meant that I commened wrong explanation here.
    So I asked you how to remove my comments from here.

     
  • `Moe`
    `Moe`
    2005-12-04

    Logged In: YES
    user_id=1045474

    New version: discovered and fixed one bug (in physfs, actually). Updated for current CVS. Nothing else.

     
  • `Moe`
    `Moe`
    2005-12-05

    Latest bug fixed release

     
  • `Moe`
    `Moe`
    2005-12-05

    Logged In: YES
    user_id=1045474

    New Patch: forgot one CVS update conflict in windows-only code