From: Andrew G. <ag...@em...> - 2003-11-25 17:58:49
|
On Monday, Nov 24, 2003, at 23:31 US/Central, Richard Clark wrote: > Hi Andrew, > > I'm in a bit of a quandry when it comes to working with assets in OS > X executables. I see that you're writing an asset file then Rez-ing it > into the executable. I'm wondering if it's time to consider pulling > the assets into an OS X bundle? Absolutely. And it shouldn't be difficult. First some background. The .zao format is the same on all platforms, we just we use a few different mechanisms to access it. They fall into two broad categories: 1. Using a ZRef<ZStreamerRPos> or ZRef<ZFile>, and reading the data on demand (more or less). 2. Reading or mapping the .zao into memory in its entirety, and interpreting it there (byte swapping as needed). The format is such that if it's read or mapped into memory then all boundaries are 32 bit aligned. On Linux we use the zac compiler both to build the .zao files and to physically append any .zao files to the executable, outside the ELF wrapper (although it would be nice to place it in an appropriate ELF section at some point). At runtime we instantiate a ZAssetTree_POSIX_MemoryMapped to mmap the executable into memory, and then use the ZAssetXXX_Std_Memory stuff to manage it. For Win32 the CodeWarrior zac plugin generates a .rci file for each .zas it compiles. Unfortunately I don't know how LoadResource/LockResource physically manages resources. It might be that they're mmapped into the address space, but I suspect on Win9x they're read from disk when they're loaded. So, as we can't load a resource partially, and to avoid consuming real RAM when we might need to access only a small part of an asset tree, the .rci file consists of a series of resources. Each is a 64K segment of the .zao data, and there's a table of contents indicating where each resource goes in the overall stream. At runtime we instantiate a ZAssetTree_Win_MultiResource, which uses a ZStreamRPos_Win_MultiResource to make the individual resources look like they're all one stream, and use the ZAssetXXX_Std_Stream stuff to manage that stream. BeOS just got updated to put the .zao data into a BResource in the app, which is then loaded into memory, where ZAssetXXX_Std_Memory manages it. And on Linux and Win32 we can also simply mmap a standalone file. And of course there's MacOS. The standard mechanism has been to have a .r file that pulls the .zao file into a Mac resource (as you know) and then we use the ZAssetXXX_Std_Stream stuff, where the stream is based on ReadPartialResource so we don't have to pull in the whole resource (in fact we wrap a ZStreamerRPos_PageBuffered around the ZStreamerRPos_Mac_PartialResource to improve performance). My ideal for MacOS X would be for any .zas file to compile down to a .zao file that's placed appropriately in the bundle. That's the bit I haven't learned enough about to have done anything yet. Then we can update ZUtil_Asset so that ZUtil_Asset:: sGetAssetTreeNamesFromExecutable can return a list of all the .zaos in that location. And as we have the POSIX APIs available, ZUtil_Asset::sGetAssetTreeFromExecutable can be updated to do what we do on POSIX -- mmap the file. A+ -- Andrew Green mailto:ag...@em... Electric Magic Co. Vox/Fax: +1 (408) 907 2101 |