Secretchronicles/SMC — pull request #139 by brianvanderburg2 (2014-08-06 04:10:31+00:00)
Title: Feature packages physfs (WIP)

This feature is a continuation of the packages feature, with support for zip archives. The feature itself will require a bit of changes. I'm using PhysFS for the archives, but not directly using the search path features for several reasons:

* Levels, worlds, and campaigns should ideally come only from the selected package and not from "used" packages. The idea of used packages is to be resource packages that can provide graphics, sounds, music, and scripting to other packages.
* Scripting loads from the specific package if loading a package script (SMC.require "feature", "simpletoon/res1"). Directly using PhysFS search path would cause it to search all packages.
* Probably a few other reasons I can't think of

To perform this, I'm taking advantage of mount points for PhysFS. During the package scan, all found packages are added to mount points as follows, and so each mount point only has one directory/zipfile:

* /game/core - The core game data $GAMEDATADIR/
* /user/core - The user game data $USERDATADIR/
* /game/package/$PACKAGE - The game data for a package $GAMEDATADIR/packages/$PACKAGE
* /user/package/$PACKAGE - The user data for a package $USERDATADIR/packages/$PACKAGE

Because this feature is building on top of (and changing) the current packages feature, until it is complete the code is likely to contain a mix of old and new features. The plan is that the package format stays the same while the code is adjusted to use it. This way even while developing the zipfile support, non-zipfile will continue working.

Current progress:

* The package information "package.xml" can be read from directory or zipfile
* The list of levels can be read from directory or zipfile
* The levels can be loaded from directory or zipfile

Behind the scenes, various pieces are changed to no longer use file names (or at least absolute file names). Currently the level code no longer knows the file name of the level, but only the level name. The package manager handles the rest. A level opened from cLevel::Load(level_name) call the package manager to get the input stream.

Issues:

Because of the above, a menu level can only be loaded from within the current package. Currently the menu level is determined in one of three ways:

* The user preference
* If user preference is not set or that level doesn't exist, and a package is in use, the package menu level
* If it is not set or doesn't exist, the default menu level

If the specified level does not exist at all, the menu level create an empty cLevel object. I plan to add a feature that if after the last step the level still doesn't exist to just pick the first level if available from the package.

Because the package name is the same regardless of a file or directory, what I do is create the package as a directory packages/simpletoon/game1.smcpkg, then when I'm ready to make a zip, rename the directory to packages/simpletoon/game1.smcpkg-dir, then do a "cd game1.smcpkg-dir && zip ../game1.smcpkg -r ."

Another issue is that currently the package name is determined by the path to that package This means that if a package uses another package, say simpletoon/res1, then it must be located at $USERDATADIR/packages/simpletoon/res1.smcpkg or $GAMEDATADIR/packages/simpletoon/res1.smcpkg. Eventually I may just have the scanner scan user $USERDATADIR/packages and $GAMEDATADIR/packages and any time it encounters the .smcpkg, read the package.xml file, extract a name from that, then set the user and game search paths based on that. Then, it would not matter where the package is placed or named under $USERORGAMEDATADIR/packages, as long as it wasn't under another package.

* Because