Vaguely PAK like file format supporting compression and read/write operation (as zipfiles are not that well suited to read/write).
The format will assume no fragmentation of smaller files, rather a file is to be moved if it expands beyond the space available to it.

Current default file extension will be "zpk".


Header
{
FOURCC magic;	//'ZPAK'
u32 ents;		//size of directory
u64 offs;		//offset of directory
}

DirEntry
{
char name[32];	//file name, 0 padded
u32 chain;		//next dir entry
u32 date_time;	//date modified
u16 flags;		//file flags (1&=fragmented, 2&=dir)
u16 method;		//method number, 0=store, 8=deflate, 9=deflate(ext)
u32 crc32;		//CRC32 of data (or first entry if dir)
u32 usize;		//uncompressed size of data
u32 csize;		//compressed size of data
u64 offset;		//offset to start of data
}

The name will contain the filename and is limited to 32 characters.
A name beginning with 0 is not allowed, it will signify a free entry. 

For longer names, consider a name mangling scheme. For names exceeding 32 chars, these will be rewritten to consist of:
	The first some-odd chars of the name;
	A hash value for the full name;
	The file extension (if present).

Chain will refer to the next entry in the current directory. A chain value of 0 will indicate that this is the last entry in the directory.

Note that entry 0 is special, and will serve primarily to link to the first root entry.


Vs. the date/time being in dos format:
	date, low 5 bits=day, next 4 bits=month, high 7=year rel 1980;
	time, low 5=seconds/2, next 6 bits=minute, high 5=hour
The date_time field multiplies and adds the values:
	60s, 60m, 24h, 31d, 12m, 133.63y (fails in 2113 vs 2107).
	so:
	s=date_time%60;
	m=(date_time/60)%60;
	h=(date_time/3600)%24;
	...

Considered:
1&=the file is fragmented. Offset/csize refers to a table of spans, each giving the offset and size of each fragment. This could be useful for larger files, where possibly relocating on each write may not be all that efficient. Default chunking will be 64kB.

2&=directory. The CRC field will refer to the first directory entry (or 0 if the directory is empty). Usize, csize, and offset are reserved. Method will be 0.


Method 9 will be deflate with a 64kB window.
The CRC algo will be the same algo used in ZIP and PNG for example.


So, very little extra is stored in the file itself.

The thought for read/write access will be based on building a list of spans. All the empty space will be given to free spans, and all used space given to used spans. Idea here: First, all used spans are accumulated and sorted, and free spans are inferred from any breaks between the spans.

Files will be read in and decompressed on open, and, if modified, recompressed on close. If a file does not fit within a given span, it will be relocated to a span that fits, and, failing that, to the end of the image.

Fragmented Files:
Fragmented files will have the contents refer to an array of spans.

FragmentSpan {
u32 _resv0;		//reserved, 0
u32 _resv1;		//reserved, 0
u16 flags;		//fragment flags
u16 method;		//method number, 0=store, 8=deflate, 9=deflate(ext)
u32 crc32;		//CRC32 of data
u32 usize;		//uncompressed size of data
u32 csize;		//compressed size of data
u64 offset;		//offset to start of data
}

Note that all spans apart from the last span are required to have the same uncompressed size, and this size is required to be a power of 2.
In effect, the uncompressed size of the first span will be used to know the fragment size.


Special Files:
All files with names beginning with '$' are special and will not be visible (or accessible) as directory contents.

Compression:
Could either default to some algo, or try possible algos to determine which is best. Could detect write frequency, and for sufficiently oftenly modified data could default to store.
