/*****************************************************************************
 *	      ______
 *	    /   _   \   _   __    ______
 *	   /  /_ /  / /  //__ / /   _   \
 *	  /   ____ / /   /     /  /  /  /
 *	 /  /       /  /      /  /_ /  /
 *	/_ /       /_ /       \ _____ /
 *	           ______
 *	         /  ____ /  ______     _   __     _    ______
 *	        /  /___   /   _   \  /  //_  \  /_ / /   _   \
 *	       _\___   \ /  /  /  / /   / /  / /  / /  /  /_ /
 *	     /  /_ /  / /  /_ /  / /  /  /  / /  / /  /____ 
 *	     \______ /  \ _____ / /_ /  /_ / /_ /  \ ______/
 *	
 *	
 *	ProSonic Engine
 *	Created by Damian Grove
 *	
 *	Compiled with DJGPP - GCC 2.952 (DOS) / Dev-C++ 4.9.9.2 (Windows)
 *	Libraries used:
 *		- Allegro - 3.9.34		http://www.talula.demon.co.uk/allegro/
 *		- DUMB - 0.9.3			http://dumb.sourceforge.net/
 *		- AllegroOgg - 1.0.3	http://nekros.freeshell.org/delirium/
 *
 ******************************************************************************
 *
 *	NAME:	ProSonic - Read/write zone data
 *
 *	FILE:	zone.c
 *	
 *	DESCRIPTION:
 *		All PZF and zone related functions go here.
 *	
 *****************************************************************************/

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<errno.h>	// Required for ENOMEM since "allegro.h" isn't included
#include	"zone.h"

// #define PZF_COMPILE_INCLUDED


 
void ClearZone(ZONE *z)
{
	if(z){
		if(z->Act)				free(z->Act);
		z->Act = 0;
		
		if(z->OSC)				free(z->OSC);
		if(z->BATT)				free(z->BATT);
		if(z->BDAT)				free(z->BDAT);
		if(z->BLOCK)			free(z->BLOCK);
		if(z->BMAP)				free(z->BMAP);
		if(z->BSOL)				free(z->BSOL);
		if(z->OBJ)				free(z->OBJ);
		if(z->TMAP)				free(z->TMAP);
		if(z->WMAP)				free(z->WMAP);
		if(z->CCYC)				free(z->CCYC);
		if(z->FILTERDISTORTION)	free(z->FILTERDISTORTION);
		if(z->FILTERCOMPOSITE)	free(z->FILTERCOMPOSITE);
		z->OSC = 0;
		z->BATT = 0;
		z->BDAT = 0;
		z->BLOCK = 0;
		z->BMAP = 0;
		z->BSOL = 0;
		z->OBJ = 0;
		z->TMAP = 0;
		z->WMAP = 0;
		z->CCYC = 0;
		z->FILTERDISTORTION = 0;
		z->FILTERCOMPOSITE = 0;
		
		if(z->OSC_SizeTable)				free(z->OSC_SizeTable);
		if(z->BATT_SizeTable)				free(z->BATT_SizeTable);
		if(z->BDAT_SizeTable)				free(z->BDAT_SizeTable);
		if(z->BLOCK_SizeTable)				free(z->BLOCK_SizeTable);
		if(z->BMAP_SizeTable)				free(z->BMAP_SizeTable);
		if(z->BSOL_SizeTable)				free(z->BSOL_SizeTable);
		if(z->OBJ_SizeTable)				free(z->OBJ_SizeTable);
		if(z->TMAP_SizeTable)				free(z->TMAP_SizeTable);
		if(z->WMAP_SizeTable)				free(z->WMAP_SizeTable);
		if(z->CCYC_SizeTable)				free(z->CCYC_SizeTable);
		if(z->FILTERDISTORTION_SizeTable)	free(z->FILTERDISTORTION_SizeTable);
		if(z->FILTERCOMPOSITE_SizeTable)	free(z->FILTERCOMPOSITE_SizeTable);
		z->OSC_SizeTable = 0;
		z->BATT_SizeTable = 0;
		z->BDAT_SizeTable = 0;
		z->BLOCK_SizeTable = 0;
		z->BMAP_SizeTable = 0;
		z->BSOL_SizeTable = 0;
		z->OBJ_SizeTable = 0;
		z->TMAP_SizeTable = 0;
		z->WMAP_SizeTable = 0;
		z->CCYC_SizeTable = 0;
		z->FILTERDISTORTION_SizeTable = 0;
		z->FILTERCOMPOSITE_SizeTable = 0;
		
		if(z->OSC_AddressTable)					free(z->OSC_AddressTable);
		if(z->BATT_AddressTable)				free(z->BATT_AddressTable);
		if(z->BDAT_AddressTable)				free(z->BDAT_AddressTable);
		if(z->BLOCK_AddressTable)				free(z->BLOCK_AddressTable);
		if(z->BMAP_AddressTable)				free(z->BMAP_AddressTable);
		if(z->BSOL_AddressTable)				free(z->BSOL_AddressTable);
		if(z->OBJ_AddressTable)					free(z->OBJ_AddressTable);
		if(z->TMAP_AddressTable)				free(z->TMAP_AddressTable);
		if(z->WMAP_AddressTable)				free(z->WMAP_AddressTable);
		if(z->CCYC_AddressTable)				free(z->CCYC_AddressTable);
		if(z->FILTERDISTORTION_AddressTable)	free(z->FILTERDISTORTION_AddressTable);
		if(z->FILTERCOMPOSITE_AddressTable)		free(z->FILTERCOMPOSITE_AddressTable);
		z->OSC_AddressTable = 0;
		z->BATT_AddressTable = 0;
		z->BDAT_AddressTable = 0;
		z->BLOCK_AddressTable = 0;
		z->BMAP_AddressTable = 0;
		z->BSOL_AddressTable = 0;
		z->OBJ_AddressTable = 0;
		z->TMAP_AddressTable = 0;
		z->WMAP_AddressTable = 0;
		z->CCYC_AddressTable = 0;
		z->FILTERDISTORTION_AddressTable = 0;
		z->FILTERCOMPOSITE_AddressTable = 0;
		
		z->OSC_FileCount = 0;
		z->BATT_FileCount = 0;
		z->BDAT_FileCount = 0;
		z->BLOCK_FileCount = 0;
		z->BMAP_FileCount = 0;
		z->BSOL_FileCount = 0;
		z->OBJ_FileCount = 0;
		z->TMAP_FileCount = 0;
		z->WMAP_FileCount = 0;
		z->CCYC_FileCount = 0;
		z->FILTERDISTORTION_FileCount = 0;
		z->FILTERCOMPOSITE_FileCount = 0;
	}
}

void DeleteZone(ZONE *z)
{
	if(z){
		ClearZone(z);
		free(z);
		z = 0;
	}
}






#ifdef PZF_COMPILE_INCLUDED
// READ WORD //
int ReadWord(ZONE *z, const char *string, ...)
{
	for(a=0; a<24; a++)
		item[a] = 0;
	for(a=0; a<24; a++){
		c = ftell(txt_file);
		if(c < filesize_zone){
			fread(&item[a], 1, 1, txt_file);
		}
		else{
			item[a] = '\0';
			a = 32;
			printf("* EOF *\n");
			return 255;
		}
		
		printf("%c", item[a]);////////////////////
		
		if(item[a] == ' ' || item[a] == 0x9 || item[a] == 0xA || item[a] == 0xD)
		{
			if(a == 0)
				a--;
			
			if(a > 0){
				printf("ERROR 1: Invalid item \"%s\"\n", item);
				
				fclose(txt_file);
				free(z);
				return 1;
			}
		}
		
		else
		{
			if(item[a] == ':'){
				item[a] = '\0';
				printf("----");////////////
				a = 32;
			}
			else if(a == 23){
				printf("ERROR 2: Invalid item \"%s\"\n", item);
				
				fclose(txt_file);
				free(z);
				return 2;
			}
		}
	}
	
	b = 0;
	if(strcmp(&string[0], "ZONE.TXT") == 0)
	{
		if(strcmp(&item[0], "ZONENAME1") == 0)
			b = 1;
		else if(strcmp(&item[0], "ZONENAME2") == 0)
			b = 2;
		else if(strcmp(&item[0], "ACTS") == 0)
			b = 3;
		else if(strcmp(&item[0], "STAGE1A") == 0)
			b = 0x10;
		else if(strcmp(&item[0], "STAGE1B") == 0)
			b = 0x11;
		else if(strcmp(&item[0], "STAGE1C") == 0)
			b = 0x12;
		else if(strcmp(&item[0], "STAGE1D") == 0)
			b = 0x13;
		else if(strcmp(&item[0], "STAGE2A") == 0)
			b = 0x20;
		else if(strcmp(&item[0], "STAGE2B") == 0)
			b = 0x21;
		else if(strcmp(&item[0], "STAGE2C") == 0)
			b = 0x22;
		else if(strcmp(&item[0], "STAGE2D") == 0)
			b = 0x23;
		else if(strcmp(&item[0], "STAGE3A") == 0)
			b = 0x30;
		else if(strcmp(&item[0], "STAGE3B") == 0)
			b = 0x31;
		else if(strcmp(&item[0], "STAGE3C") == 0)
			b = 0x32;
		else if(strcmp(&item[0], "STAGE3D") == 0)
			b = 0x33;
		else if(strcmp(&item[0], "STAGE4A") == 0)
			b = 0x40;
		else if(strcmp(&item[0], "STAGE4B") == 0)
			b = 0x41;
		else if(strcmp(&item[0], "STAGE4C") == 0)
			b = 0x42;
		else if(strcmp(&item[0], "STAGE4D") == 0)
			b = 0x43;
		else if(strcmp(&item[0], "STAGE5A") == 0)
			b = 0x50;
		else if(strcmp(&item[0], "STAGE5B") == 0)
			b = 0x51;
		else if(strcmp(&item[0], "STAGE5C") == 0)
			b = 0x52;
		else if(strcmp(&item[0], "STAGE5D") == 0)
			b = 0x53;
		else if(strcmp(&item[0], "STAGE6A") == 0)
			b = 0x60;
		else if(strcmp(&item[0], "STAGE6B") == 0)
			b = 0x61;
		else if(strcmp(&item[0], "STAGE6C") == 0)
			b = 0x62;
		else if(strcmp(&item[0], "STAGE6D") == 0)
			b = 0x63;
		else if(strcmp(&item[0], "STAGE7A") == 0)
			b = 0x70;
		else if(strcmp(&item[0], "STAGE7B") == 0)
			b = 0x71;
		else if(strcmp(&item[0], "STAGE7C") == 0)
			b = 0x72;
		else if(strcmp(&item[0], "STAGE7D") == 0)
			b = 0x73;
		else if(strcmp(&item[0], "STAGE8A") == 0)
			b = 0x80;
		else if(strcmp(&item[0], "STAGE8B") == 0)
			b = 0x81;
		else if(strcmp(&item[0], "STAGE8C") == 0)
			b = 0x82;
		else if(strcmp(&item[0], "STAGE8D") == 0)
			b = 0x83;
	}
	else if(strcmp(&string[0], "INDEX.TXT") == 0)
	{
		if(strcmp(&item[0], "FILES") == 0)
			b = 0x200;
		else if(item[0] == '0' && item[1] == '\0')
			b = 0x201;
		else if(strtol(&item[0], NULL, 10) < 256 &&
		 strtol(&item[0], NULL, 10) > 0)
			b = strtol(&item[0], NULL, 10) + 0x201;
	}
	else
	{
		if(strcmp(&item[0], "NAME") == 0)
			b = 0x100;
		else if(strcmp(&item[0], "ACTNUMBER") == 0)
			b = 0x101;
		else if(strcmp(&item[0], "MUSICREGULAR") == 0)
			b = 0x102;
		else if(strcmp(&item[0], "MUSICALTERNATIVE") == 0)
			b = 0x103;
		else if(strcmp(&item[0], "OPENINGSCRIPT") == 0)
			b = 0x104;
		else if(strcmp(&item[0], "CLOSINGSCRIPT") == 0)
			b = 0x105;
		else if(strcmp(&item[0], "ACTIVESCRIPT") == 0)
			b = 0x106;
		else if(strcmp(&item[0], "WATERENABLE") == 0)
			b = 0x107;
		else if(strcmp(&item[0], "WRAPPOINT") == 0)
			b = 0x108;
		else if(strcmp(&item[0], "ABOVEWATERFILTERL") == 0)
			b = 0x109;
		else if(strcmp(&item[0], "BELOWWATERFILTERL") == 0)
			b = 0x10A;
		else if(strcmp(&item[0], "ABOVEWATERFILTERSPEED") == 0)
			b = 0x10B;
		else if(strcmp(&item[0], "BELOWWATERFILTERSPEED") == 0)
			b = 0x10C;
		else if(strcmp(&item[0], "CLEARBACKGROUND") == 0)
			b = 0x10D;
		// PLACE HOLDER FOR 0x10E
		else if(strcmp(&item[0], "PALETTE") == 0)
			b = 0x10F;
		else if(strcmp(&item[0], "COLORCYCLER") == 0)
			b = 0x110;
		else if(strcmp(&item[0], "WATERMAP") == 0)
			b = 0x111;
		else if(strcmp(&item[0], "BLOCKMAP") == 0)
			b = 0x112;
		else if(strcmp(&item[0], "BLOCKART") == 0)
			b = 0x113;
		else if(strcmp(&item[0], "BLOCKDATA") == 0)
			b = 0x114;
		else if(strcmp(&item[0], "BLOCKATTRIBUTES") == 0)
			b = 0x115;
		else if(strcmp(&item[0], "BLOCKSOLIDITY") == 0)
			b = 0x116;
		else if(strcmp(&item[0], "TILEMAP") == 0)
			b = 0x117;
		else if(strcmp(&item[0], "OBJECTLAYOUT") == 0)
			b = 0x118;
		else if(strcmp(&item[0], "WATERHEIGHT") == 0)
			b = 0x119;
		else if(strcmp(&item[0], "LEVELXL") == 0)
			b = 0x11A;
		else if(strcmp(&item[0], "LEVELXR") == 0)
			b = 0x11B;
		else if(strcmp(&item[0], "LEVELYT") == 0)
			b = 0x11C;
		else if(strcmp(&item[0], "LEVELYB") == 0)
			b = 0x11D;
		else if(strcmp(&item[0], "START0X") == 0)
			b = 0x11E;
		else if(strcmp(&item[0], "START0Y") == 0)
			b = 0x11F;
		else if(strcmp(&item[0], "START1X") == 0)
			b = 0x120;
		else if(strcmp(&item[0], "START1Y") == 0)
			b = 0x121;
		else if(strcmp(&item[0], "START2X") == 0)
			b = 0x122;
		else if(strcmp(&item[0], "START2Y") == 0)
			b = 0x123;
		else if(strcmp(&item[0], "START3X") == 0)
			b = 0x124;
		else if(strcmp(&item[0], "START3Y") == 0)
			b = 0x125;
		else if(strcmp(&item[0], "START4X") == 0)
			b = 0x126;
		else if(strcmp(&item[0], "START4Y") == 0)
			b = 0x127;
		else if(strcmp(&item[0], "START5X") == 0)
			b = 0x128;
		else if(strcmp(&item[0], "START5Y") == 0)
			b = 0x129;
		else if(strcmp(&item[0], "START6X") == 0)
			b = 0x12A;
		else if(strcmp(&item[0], "START6Y") == 0)
			b = 0x12B;
		else if(strcmp(&item[0], "START7X") == 0)
			b = 0x12C;
		else if(strcmp(&item[0], "START7Y") == 0)
			b = 0x12D;
		else if(strcmp(&item[0], "START8X") == 0)
			b = 0x12E;
		else if(strcmp(&item[0], "START8Y") == 0)
			b = 0x12F;
		else if(strcmp(&item[0], "START9X") == 0)
			b = 0x130;
		else if(strcmp(&item[0], "START9Y") == 0)
			b = 0x131;
		else if(strcmp(&item[0], "STARTAX") == 0)
			b = 0x132;
		else if(strcmp(&item[0], "STARTAY") == 0)
			b = 0x133;
		else if(strcmp(&item[0], "STARTBX") == 0)
			b = 0x134;
		else if(strcmp(&item[0], "STARTBY") == 0)
			b = 0x135;
		else if(strcmp(&item[0], "STARTCX") == 0)
			b = 0x136;
		else if(strcmp(&item[0], "STARTCY") == 0)
			b = 0x137;
		else if(strcmp(&item[0], "STARTDX") == 0)
			b = 0x138;
		else if(strcmp(&item[0], "STARTDY") == 0)
			b = 0x139;
		else if(strcmp(&item[0], "STARTEX") == 0)
			b = 0x13A;
		else if(strcmp(&item[0], "STARTEY") == 0)
			b = 0x13B;
		else if(strcmp(&item[0], "STARTFX") == 0)
			b = 0x13C;
		else if(strcmp(&item[0], "STARTFY") == 0)
			b = 0x13D;
	}
		
	if(b == 0){
		printf("ERROR 3: Invalid item \"%s\"\n", item);
		
		fclose(txt_file);
		free(z);
		return 3;
	}
	
	if(z->Act_FileCount == 0 && b >= 10){
		printf("ERROR 4: \"%s\" defined before \"ACTS\"\n", &item[0]);
		
		fclose(txt_file);
		free(z);
		return 4;
	}
	
	printf("%i\n", b);
	
	return 0;
}



int ReadText(ZONE *z, const char *string, ...)
{
	// READ TEXT //
	for(a=0; a<24; a++)
		item[a] = 0;
	for(a=0; a<24; a++){
		c = ftell(txt_file);
		while(a == 0 && c < filesize_zone && item[0] != '"')
			fread(&item[0], 1, 1, txt_file);
		if(c < filesize_zone)
			fread(&item[a], 1, 1, txt_file);
		else{
			item[a] = '\0';
			a = 32;
			return 255;
		}
		
		printf("%c", item[a]);///////////////////
		
		if(a > 0 && item[a] == '"'){
			item[a] = '\0';
			a = 32;
			printf("----\n");////////////
			return 0;
		}
	}
	
	return 0;
}
	
	

int ReadVar(ZONE *z, const char *string, ...)
{
	// READ VARIABLE //
	for(a=0; a<24; a++)
		item[a] = 0;
	for(a=0; a<11; a++){
		c = ftell(txt_file);
		if(c < filesize_zone)
			fread(&item[a], 1, 1, txt_file);
		else{
			item[a] = '\0';
			a = 32;
			endoffile = 1;
		}
		
		if(item[a] == ' ' || item[a] == 0x9 || item[a] == 0xA || item[a] == 0xD)
		{
			if(a == 0)
				a--;
			else if(a == 2 && (item[1] == 'x' || item[1] == 'X')){
				printf("ERROR 5: Invalid value\n");
				
				fclose(txt_file);
				free(z);
				return 5;
			}
			else if(a > 0){
				item[a] = '\0';
				a = 32;
			}
		}
		
		else
		{
			if(item[a] < '0' || item[a] > '9'){
				if(a == 1){
					if(item[0] != '0' || (item[1] != 'x' && item[1] != 'X')){
						printf("ERROR 6: Invalid value\n");
						
						fclose(txt_file);
						free(z);
						return 6;
					}
				}
				else if(a == 0){
					printf("ERROR 7: Invalid value\n");
					
					fclose(txt_file);
					free(z);
					return 6;
				}
				else if(a > 1 && (item[a] < 'A' || (item[a] > 'F' && item[a] < 'a') || item[a] > 'f')){
				//else if(item[a] != 'x' && item[a] != 'X'){
					printf("ERROR 8: Invalid value\n");
					
					fclose(txt_file);
					free(z);
					return 7;
				}
			}
		}
	}
	
	if(item[0] == '0' && (item[1] == 'x' || item[1] == 'X'))
		d = strtol(&item[2], NULL, 16);
	else
		d = strtol(&item[0], NULL, 10);
		
	if(endoffile == 1){
		endoffile = 0;
		return 255;
	}
	
	printf("VALUE = %i\n", d);
	
	return 0;
}



int ReadFloatVar(ZONE *z, const char *string, ...)
{
	// READ VARIABLE //
	for(a=0; a<24; a++)
		item[a] = 0;
	for(a=0; a<11; a++){
		c = ftell(txt_file);
		if(c < filesize_zone)
			fread(&item[a], 1, 1, txt_file);
		else{
			item[a] = '\0';
			a = 32;
			endoffile = 1;
		}
		
		if(item[a] == ' ' || item[a] == 0x9 || item[a] == 0xA || item[a] == 0xD)
		{
			if(a == 0)
				a--;
			else if(a == 2 && (item[1] == 'x' || item[1] == 'X')){
				printf("ERROR 5: Invalid value\n");
				
				fclose(txt_file);
				free(z);
				return 5;
			}
			else if(a > 0){
				item[a] = '\0';
				a = 32;
			}
		}
		
		else
		{
			if(item[a] < '0' || item[a] > '9'){
				if(a != 1){
					printf("ERROR 6: Invalid value\n");
					
					fclose(txt_file);
					free(z);
					return 6;
				}
				else if(item[a] != '.'){
					printf("ERROR 7: Invalid value\n");
					
					fclose(txt_file);
					free(z);
					return 7;
				}
			}
		}
	}
	
	f = (float)strtod(&item[0], NULL);
		
	if(endoffile == 1){
		endoffile = 0;
		return 255;
	}
	
	printf("VALUE = %f\n", f);
	
	return 0;
}







int CompileZone(ZONE *z, const char *string, ...)
{
	int e;
	
	//CreateZone(z);
	//z = malloc(1);
	z->Act = 0;
	
	z->OSC_SizeTable = 0;
	z->BATT_SizeTable = 0;
	z->BDAT_SizeTable = 0;
	z->BLOCK_SizeTable = 0;
	z->BMAP_SizeTable = 0;
	z->BSOL_SizeTable = 0;
	z->OBJ_SizeTable = 0;
	z->PAL_SizeTable = 0;
	z->TMAP_SizeTable = 0;
	z->WMAP_SizeTable = 0;
	z->CCYC_SizeTable = 0;
	z->FILTERDISTORTION_SizeTable = 0;
	z->FILTERCOMPOSITE_SizeTable = 0;
	
	z->OSC_AddressTable = 0;
	z->BATT_AddressTable = 0;
	z->BDAT_AddressTable = 0;
	z->BLOCK_AddressTable = 0;
	z->BMAP_AddressTable = 0;
	z->BSOL_AddressTable = 0;
	z->OBJ_AddressTable = 0;
	z->PAL_AddressTable = 0;
	z->TMAP_AddressTable = 0;
	z->WMAP_AddressTable = 0;
	z->CCYC_AddressTable = 0;
	z->FILTERDISTORTION_AddressTable = 0;
	z->FILTERCOMPOSITE_AddressTable = 0;
	
	z->OSC = 0;
	z->BATT = 0;
	z->BDAT = 0;
	z->BLOCK = 0;
	z->BMAP = 0;
	z->BSOL = 0;
	z->OBJ = 0;
	z->PAL = 0;
	z->TMAP = 0;
	z->WMAP = 0;
	z->CCYC = 0;
	z->FILTERDISTORTION = 0;
	z->FILTERCOMPOSITE = 0;
	
	txt_file = fopen("ZONE.TXT", "r+b");
	fseek(txt_file, 0, SEEK_END);
	filesize_zone = ftell(txt_file);
	rewind(txt_file);
	
	//////////////
	// ZONE.TXT //
	//////////////
	a = 0;
	b = 0;
	c = 0;
	d = 0;
	
	while(ReadWord(z, "ZONE.TXT") != 255){
		// b = d (b is the item, d is the value)
		
		if(b == 1 || b == 2){	// TEXT
			e = ReadText(z, "ZONE.TXT");
			if(e == 255){
				printf("DONE!\n");
				//free(z);
				fclose(txt_file);
				return 0;
			}
			else if(b == 1){
				for(a=0; a<20; a++)
					z->LevelName1[a] = item[a];
			}
			else{
				for(a=0; a<20; a++)
					z->LevelName2[a] = item[a];
			}
		}
		else if(b > 2){			// VARIABLE
			if(ReadVar(z, "ZONE.TXT") == 255){
				printf("DONE!\n");
				//free(z);
				fclose(txt_file);
				return 0;
			}
			else{
				if(b == 3){
					z->Act_FileCount = d;
					z->Act = (ACT*)realloc(z->Act, sizeof(ACT) * z->Act_FileCount);
				}
				else{
					if(b&3 == 0)
						a = 0xE;
					else if(b&3 == 1)
						a = 0xD;
					else if(b&3 == 2)
						a = 0xB;
					else
						a = 0x7;
					
					z->Act[(b>>4)-1].IncludedStages &= a;
					z->Act[(b>>4)-1].IncludedStages += (d << (b&3));
				}
			}
		}
		else{
			printf("1: Cannot compile because of an error in \"ZONE.TXT\"\n");
			free(z);
			fclose(txt_file);
			return 1;
		}
	}
	fclose(txt_file);
	
	
	
	/////////////////
	// STAGExx.TXT //
	/////////////////
	strcpy(&filename[0], ".\\ACTa\\STAGEc.TXT");
	for(a01=0; a01 < z->Act_FileCount; a01++){
		filename[5] = '1' + a01;
		for(c01=0; c01<4; c01++){
			filename[12] = 'A' + c01;
			if(fopen(&filename[0], "r+b") != 0 && (z->Act[a01].IncludedStages >> c01) & 1 == 1){
				txt_file = fopen(&filename[0], "r+b");
				printf("%s\n", &filename[0]);
				fseek(txt_file, 0, SEEK_END);
				filesize_zone = ftell(txt_file);
				rewind(txt_file);
				
				while(ReadWord(z, &filename[0]) != 255){
					// b = d (b is the item, d is the value)
					switch(b){
						case 0x100:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].Name = d;
							break;
						case 0x101:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].ActNumber = d;
							break;
						case 0x102:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].MusicRegular = d;
							break;
						case 0x103:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].MusicAlternate = d;
							break;
						case 0x104:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].OpeningScript = d;
							break;
						case 0x105:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].ClosingScript = d;
							break;
						case 0x106:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].ActiveScript = d;
							break;
						case 0x107:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].WaterEnable = d;
							break;
						case 0x108:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].WrapPoint = d;
							break;
						case 0x109:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].AboveWaterFilterL = d;
							break;
						case 0x10A:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BelowWaterFilterL = d;
							break;
						case 0x10B:
							ReadFloatVar(z, &filename[0]);
							z->Act[a01].Stage[c01].AboveWaterFilterSpeed = f;
							break;
						case 0x10C:
							ReadFloatVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BelowWaterFilterSpeed = f;
							break;
						case 0x10D:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].ClearBackground = d;
							break;
						// PLACE HOLDER FOR 0x10E
						case 0x10F:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].Palette = d;
							break;
						case 0x110:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].ColorCycle = d;
							break;
						case 0x111:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].WaterMap = d;
							break;
						case 0x112:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BlockMap = d;
							break;
						case 0x113:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BlockArt = d;
							break;
						case 0x114:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BlockData = d;
							break;
						case 0x115:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BlockAttributes = d;
							break;
						case 0x116:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].BlockSolidity = d;
							break;
						case 0x117:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].TileMap = d;
							break;
						case 0x118:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].ObjectLayout = d;
							break;
						case 0x119:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].WaterHeight = d;
							break;
						case 0x11A:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].LevelXL = d;
							break;
						case 0x11B:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].LevelXR = d;
							break;
						case 0x11C:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].LevelYT = d;
							break;
						case 0x11D:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].LevelYB = d;
							break;
						case 0x11E:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[0] = d;
							break;
						case 0x11F:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[0] = d;
							break;
						case 0x120:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[1] = d;
							break;
						case 0x121:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[1] = d;
							break;
						case 0x122:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[2] = d;
							break;
						case 0x123:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[2] = d;
							break;
						case 0x124:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[3] = d;
							break;
						case 0x125:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[3] = d;
							break;
						case 0x126:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[4] = d;
							break;
						case 0x127:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[4] = d;
							break;
						case 0x128:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[5] = d;
							break;
						case 0x129:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[5] = d;
							break;
						case 0x12A:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[6] = d;
							break;
						case 0x12B:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[6] = d;
							break;
						case 0x12C:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[7] = d;
							break;
						case 0x12D:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[7] = d;
							break;
						case 0x12E:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[8] = d;
							break;
						case 0x12F:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[8] = d;
							break;
						case 0x130:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[9] = d;
							break;
						case 0x131:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[9] = d;
							break;
						case 0x132:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[10] = d;
							break;
						case 0x133:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[10] = d;
							break;
						case 0x134:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[11] = d;
							break;
						case 0x135:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[11] = d;
							break;
						case 0x136:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[12] = d;
							break;
						case 0x137:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[12] = d;
							break;
						case 0x138:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[13] = d;
							break;
						case 0x139:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[13] = d;
							break;
						case 0x13A:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[14] = d;
							break;
						case 0x13B:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[14] = d;
							break;
						case 0x13C:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartX[15] = d;
							break;
						case 0x13D:
							ReadVar(z, &filename[0]);
							z->Act[a01].Stage[c01].StartY[15] = d;
							break;
						default:
							printf("1: Cannot compile because of an error in \"STAGExx.TXT\"\n");
							free(z);
							fclose(txt_file);
							return 1;
					}
				}
				fclose(txt_file);
			}
		}
	}
	
	
	
	///////////////
	// INDEX.TXT //
	///////////////
	c01 = 0;
	
	for(a01=0; a01<13; a01++){
		switch(a01){
			case 0:
				strcpy(&filename[0], ".\\OSC\\INDEX.TXT");
				strcpy(&path[0], ".\\OSC\\");
				printf("case %i\n", a01);
				break;
			case 1:
				strcpy(&filename[0], ".\\BATT\\INDEX.TXT");
				strcpy(&path[0], ".\\BATT\\");
				printf("case %i\n", a01);
				break;
			case 2:
				strcpy(&filename[0], ".\\BDAT\\INDEX.TXT");
				strcpy(&path[0], ".\\BDAT\\");
				printf("case %i\n", a01);
				break;
			case 3:
				strcpy(&filename[0], ".\\BLOCK\\INDEX.TXT");
				strcpy(&path[0], ".\\BLOCK\\");
				printf("case %i\n", a01);
				break;
			case 4:
				strcpy(&filename[0], ".\\BMAP\\INDEX.TXT");
				strcpy(&path[0], ".\\BMAP\\");
				printf("case %i\n", a01);
				break;
			case 5:
				strcpy(&filename[0], ".\\BSOL\\INDEX.TXT");
				strcpy(&path[0], ".\\BSOL\\");
				printf("case %i\n", a01);
				break;
			case 6:
				strcpy(&filename[0], ".\\OBJ\\INDEX.TXT");
				strcpy(&path[0], ".\\OBJ\\");
				printf("case %i\n", a01);
				break;
			case 7:
				strcpy(&filename[0], ".\\PAL\\INDEX.TXT");
				strcpy(&path[0], ".\\PAL\\");
				printf("case %i\n", a01);
				break;
			case 8:
				strcpy(&filename[0], ".\\TMAP\\INDEX.TXT");
				strcpy(&path[0], ".\\TMAP\\");
				printf("case %i\n", a01);
				break;
			case 9:
				strcpy(&filename[0], ".\\WMAP\\INDEX.TXT");
				strcpy(&path[0], ".\\WMAP\\");
				printf("case %i\n", a01);
				break;
			case 10:
				strcpy(&filename[0], ".\\CCYC\\INDEX.TXT");
				strcpy(&path[0], ".\\CCYC\\");
				printf("case %i\n", a01);
				break;
			case 11:
				strcpy(&filename[0], ".\\FILTERDISTORTION\\INDEX.TXT");
				strcpy(&path[0], ".\\FILTERDISTORTION\\");
				printf("case %i\n", a01);
				break;
			default:
				strcpy(&filename[0], ".\\FILTERCOMPOSITE\\INDEX.TXT");
				strcpy(&path[0], ".\\FILTERCOMPOSITE\\");
				printf("case %i\n", a01);
		}
		
		txt_file = fopen(&filename[0], "r+b");
		fseek(txt_file, 0, SEEK_END);
		filesize_zone = ftell(txt_file);
		rewind(txt_file);
		
		
		
		while(ReadWord(z, "INDEX.TXT") != 255){
			// b = d (b is the item, d is the value)
			
			if(b > 0x200){		// FILE NAMES
				printf("text\n");
				e = ReadText(z, "INDEX.TXT");
				if(e == 255){
					printf("DONE!\n");
					//free(z);
					fclose(txt_file);
					return 0;
				}
				else{
					for(c=0; c < 24; c++)
						filename[c] = 0;
					strcpy(&filename[0], &path[0]);
					strcat(&filename[0], &item[0]);
					txt_data = fopen(&filename[0], "r+b");
					if(txt_data == NULL)
						printf("ERROR: CANNOT OPEN DATA FILE!\n");
					fseek(txt_data, 0, SEEK_END);
					c = ftell(txt_data);
					//filesize_zone = ftell(txt_file);
					rewind(txt_data);
					
					switch(a01){
						case 0:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->OSC = (unsigned char*)realloc(z->OSC, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->OSC[c01+a], 1, 1, txt_data);
							z->OSC_SizeTable[(b-1) & 0xFF] = c;
							z->OSC_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 1:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->BATT = (unsigned char*)realloc(z->BATT, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->BATT[c01+a], 1, 1, txt_data);
							z->BATT_SizeTable[(b-1) & 0xFF] = c;
							z->BATT_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 2:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->BDAT = (unsigned char*)realloc(z->BDAT, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->BDAT[c01+a], 1, 1, txt_data);
							z->BDAT_SizeTable[(b-1) & 0xFF] = c;
							z->BDAT_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 3:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->BLOCK = (unsigned char*)realloc(z->BLOCK, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->BLOCK[c01+a], 1, 1, txt_data);
							z->BLOCK_SizeTable[(b-1) & 0xFF] = c;
							z->BLOCK_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 4:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->BMAP = (unsigned char*)realloc(z->BMAP, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->BMAP[c01+a], 1, 1, txt_data);
							z->BMAP_SizeTable[(b-1) & 0xFF] = c;
							z->BMAP_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 5:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->BSOL = (unsigned char*)realloc(z->BSOL, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->BSOL[c01+a], 1, 1, txt_data);
							z->BSOL_SizeTable[(b-1) & 0xFF] = c;
							z->BSOL_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 6:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->OBJ = (unsigned char*)realloc(z->OBJ, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->OBJ[c01+a], 1, 1, txt_data);
							z->OBJ_SizeTable[(b-1) & 0xFF] = c;
							z->OBJ_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 7:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->PAL = (unsigned char*)realloc(z->PAL, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->PAL[c01+a], 1, 1, txt_data);
							z->PAL_SizeTable[(b-1) & 0xFF] = c;
							z->PAL_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 8:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->TMAP = (unsigned char*)realloc(z->TMAP, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->TMAP[c01+a], 1, 1, txt_data);
							z->TMAP_SizeTable[(b-1) & 0xFF] = c;
							z->TMAP_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 9:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->WMAP = (unsigned char*)realloc(z->WMAP, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->WMAP[c01+a], 1, 1, txt_data);
							z->WMAP_SizeTable[(b-1) & 0xFF] = c;
							z->WMAP_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 10:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->CCYC = (unsigned char*)realloc(z->CCYC, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->CCYC[c01+a], 1, 1, txt_data);
							z->CCYC_SizeTable[(b-1) & 0xFF] = c;
							z->CCYC_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						case 11:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->FILTERDISTORTION = (unsigned char*)realloc(z->FILTERDISTORTION, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->FILTERDISTORTION[c01+a], 1, 1, txt_data);
							z->FILTERDISTORTION_SizeTable[(b-1) & 0xFF] = c;
							z->FILTERDISTORTION_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
						default:
							printf("    case %i\n", a01);
							printf("    %s\n", &filename[0]);
							printf("    %i bytes\n", c);
							z->FILTERCOMPOSITE = (unsigned char*)realloc(z->FILTERCOMPOSITE, c01 + c);
							for(a=0; a<c; a++)
								fread(&z->FILTERCOMPOSITE[c01+a], 1, 1, txt_data);
							z->FILTERCOMPOSITE_SizeTable[(b-1) & 0xFF] = c;
							z->FILTERCOMPOSITE_AddressTable[(b-1) & 0xFF] = c01;
							c01 += c;
							break;
					}
					printf("\n\n========================================\n\n");
					fclose(txt_data);
				}
			}
			else if(b == 0x200){		// NUMBER OF FILES
				printf("var\n");
				if(ReadVar(z, "INDEX.TXT") == 255){
					printf("DONE!\n");
					//free(z);
					fclose(txt_file);
					return 0;
				}
				else{
					switch(a01){
						case 0:
							z->OSC_FileCount = d;
							z->OSC_SizeTable = (unsigned int*)realloc(z->OSC_SizeTable, d << 2);
							z->OSC_AddressTable = (unsigned int*)realloc(z->OSC_AddressTable, d << 2);
							c01 = 0;
							break;
						case 1:
							z->BATT_FileCount = d;
							z->BATT_SizeTable = (unsigned int*)realloc(z->BATT_SizeTable, d << 2);
							z->BATT_AddressTable = (unsigned int*)realloc(z->BATT_AddressTable, d << 2);
							c01 = 0;
							break;
						case 2:
							z->BDAT_FileCount = d;
							z->BDAT_SizeTable = (unsigned int*)realloc(z->BDAT_SizeTable, d << 2);
							z->BDAT_AddressTable = (unsigned int*)realloc(z->BDAT_AddressTable, d << 2);
							c01 = 0;
							break;
						case 3:
							z->BLOCK_FileCount = d;
							z->BLOCK_SizeTable = (unsigned int*)realloc(z->BLOCK_SizeTable, d << 2);
							z->BLOCK_AddressTable = (unsigned int*)realloc(z->BLOCK_AddressTable, d << 2);
							c01 = 0;
							break;
						case 4:
							z->BMAP_FileCount = d;
							z->BMAP_SizeTable = (unsigned int*)realloc(z->BMAP_SizeTable, d << 2);
							z->BMAP_AddressTable = (unsigned int*)realloc(z->BMAP_AddressTable, d << 2);
							c01 = 0;
							break;
						case 5:
							z->BSOL_FileCount = d;
							z->BSOL_SizeTable = (unsigned int*)realloc(z->BSOL_SizeTable, d << 2);
							z->BSOL_AddressTable = (unsigned int*)realloc(z->BSOL_AddressTable, d << 2);
							c01 = 0;
							break;
						case 6:
							z->OBJ_FileCount = d;
							z->OBJ_SizeTable = (unsigned int*)realloc(z->OBJ_SizeTable, d << 2);
							z->OBJ_AddressTable = (unsigned int*)realloc(z->OBJ_AddressTable, d << 2);
							c01 = 0;
							break;
						case 7:
							z->PAL_FileCount = d;
							z->PAL_SizeTable = (unsigned int*)realloc(z->PAL_SizeTable, d << 2);
							z->PAL_AddressTable = (unsigned int*)realloc(z->PAL_AddressTable, d << 2);
							c01 = 0;
							break;
						case 8:
							z->TMAP_FileCount = d;
							z->TMAP_SizeTable = (unsigned int*)realloc(z->TMAP_SizeTable, d << 2);
							z->TMAP_AddressTable = (unsigned int*)realloc(z->TMAP_AddressTable, d << 2);
							c01 = 0;
							break;
						case 9:
							z->WMAP_FileCount = d;
							z->WMAP_SizeTable = (unsigned int*)realloc(z->WMAP_SizeTable, d << 2);
							z->WMAP_AddressTable = (unsigned int*)realloc(z->WMAP_AddressTable, d << 2);
							c01 = 0;
							break;
						case 10:
							z->CCYC_FileCount = d;
							z->CCYC_SizeTable = (unsigned int*)realloc(z->CCYC_SizeTable, d << 2);
							z->CCYC_AddressTable = (unsigned int*)realloc(z->CCYC_AddressTable, d << 2);
							c01 = 0;
							break;
						case 11:
							z->FILTERDISTORTION_FileCount = d;
							z->FILTERDISTORTION_SizeTable = (unsigned int*)realloc(z->FILTERDISTORTION_SizeTable, d << 2);
							z->FILTERDISTORTION_AddressTable = (unsigned int*)realloc(z->FILTERDISTORTION_AddressTable, d << 2);
							c01 = 0;
							break;
						default:
							z->FILTERCOMPOSITE_FileCount = d;
							z->FILTERCOMPOSITE_SizeTable = (unsigned int*)realloc(z->FILTERCOMPOSITE_SizeTable, d << 2);
							z->FILTERCOMPOSITE_AddressTable = (unsigned int*)realloc(z->FILTERCOMPOSITE_AddressTable, d << 2);
							c01 = 0;
					}
				}
			}
			else{
				printf("1: Cannot compile because of an error in \"INDEX.TXT\"\n");
				free(z);
				fclose(txt_file);
				return 1;
			}
		}
		fclose(txt_file);
	}
	
	
	
	return 0;
}
#endif







int CreateZone(ZONE *z)
{
	//z = malloc(1);
	if(!z) z = malloc(sizeof(ZONE));
	
	z->OSC = 0;
	z->BATT = 0;
	z->BDAT = 0;
	z->BLOCK = 0;
	z->BMAP = 0;
	z->BSOL = 0;
	z->OBJ = 0;
	z->PAL = 0;
	z->TMAP = 0;
	z->WMAP = 0;
	z->CCYC = 0;
	z->FILTERDISTORTION = 0;
	z->FILTERCOMPOSITE = 0;
	
	return 0;	
}	







int LoadZone(ZONE *z, const char *string, ...)
{
	int		a = 0;
	int		b = 0;
	int		c = 0;
	int		d = 0;
	int		x[2];
	long	filesize;
	FILE	*pzf;
	
	pzf = fopen(string, "r+b");
	if(!pzf){
		allegro_message("Could not open file \"%s\".", string);
		return 3;	// error!
	}
	fseek(pzf, 0, SEEK_END);
	filesize = ftell(pzf);
	fseek(pzf, 0, SEEK_SET);
	
	if(filesize >= 109){
		fread(&a, 1, 3, pzf);	// "PZF"
		d = getc(pzf);			// version
	}
	else
		return 1;
		
	if(a != 0x465A50)	// if "PZF" not found in header
		return 2;
	if(d != 0)
		allegro_message("Warning: unrecognized PZF file version!");
	
	
	// Create an instance of a ZONE
	//z = malloc(1);
	
	ClearZone(z);
	
	fread(&z->LevelName1, 1, 20, pzf);
	//fread(&z->LevelName2, 1, 20, pzf);	// unused
	fseek(pzf, 20, SEEK_CUR);
	
	z->Act_FileCount = getc(pzf);
	z->OSC_FileCount = getc(pzf);
	z->BATT_FileCount = getc(pzf);
	z->BDAT_FileCount = getc(pzf);
	z->BLOCK_FileCount = getc(pzf);
	z->BMAP_FileCount = getc(pzf);
	z->BSOL_FileCount = getc(pzf);
	z->OBJ_FileCount = getc(pzf);
	z->PAL_FileCount = getc(pzf);
	z->TMAP_FileCount = getc(pzf);
	z->WMAP_FileCount = getc(pzf);
	z->CCYC_FileCount = getc(pzf);
	z->FILTERDISTORTION_FileCount = getc(pzf);
	z->FILTERCOMPOSITE_FileCount = getc(pzf);
	
	////////////////////
	// READ ACT FILES //
	////////////////////
	z->Act = (ACT*)malloc(sizeof(ACT) * z->Act_FileCount);
	
	fread(&a, 4, 1, pzf);		// Read "Act" table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->Act_FileCount; b++){
		x[1] = ftell(pzf);
		c = getc(pzf);					// Read IncludedStages
		z->Act[b].IncludedStages = c;	// Write IncludedStages
		fread(&a, 4, 1, pzf);			// Read stage address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		for(c=0; c<4; c++){
			switch(c){
				case 0:
					a = (z->Act[b].IncludedStages & 1);
					break;
					
				case 1:
					a = ((z->Act[b].IncludedStages >> 1) & 1);
					break;
					
				case 2:
					a = ((z->Act[b].IncludedStages >> 2) & 1);
					break;
					
				default:
					a = ((z->Act[b].IncludedStages >> 3) & 1);
			}
			
			if(a == 1){
				z->Act[b].Stage[c].Name = getc(pzf);
				z->Act[b].Stage[c].ActNumber = getc(pzf);
				z->Act[b].Stage[c].MusicRegular = getc(pzf);
				z->Act[b].Stage[c].MusicAlternate = getc(pzf);
				z->Act[b].Stage[c].OpeningScript = getc(pzf);
				z->Act[b].Stage[c].ClosingScript = getc(pzf);
				z->Act[b].Stage[c].ActiveScript = getc(pzf);
				z->Act[b].Stage[c].WaterEnable = getc(pzf);
				fread(&z->Act[b].Stage[c].WrapPoint, 2, 1, pzf);
				z->Act[b].Stage[c].AboveWaterFilterL = getc(pzf);
				z->Act[b].Stage[c].BelowWaterFilterL = getc(pzf);
				fread(&z->Act[b].Stage[c].AboveWaterFilterSpeed, 4, 1, pzf);
				fread(&z->Act[b].Stage[c].BelowWaterFilterSpeed, 4, 1, pzf);
				z->Act[b].Stage[c].ClearBackground = getc(pzf);
				// PLACE HOLDER FOR 0x10E
				z->Act[b].Stage[c].Palette = getc(pzf);
				z->Act[b].Stage[c].ColorCycle = getc(pzf);
				z->Act[b].Stage[c].WaterMap = getc(pzf);
				z->Act[b].Stage[c].BlockMap = getc(pzf);
				z->Act[b].Stage[c].BlockArt = getc(pzf);
				z->Act[b].Stage[c].BlockData = getc(pzf);
				z->Act[b].Stage[c].BlockAttributes = getc(pzf);
				z->Act[b].Stage[c].BlockSolidity = getc(pzf);
				z->Act[b].Stage[c].TileMap = getc(pzf);
				z->Act[b].Stage[c].ObjectLayout = getc(pzf);
				fread(&z->Act[b].Stage[c].WaterHeight, 2, 1, pzf);
				fread(&z->Act[b].Stage[c].LevelXL, 2, 1, pzf);
				fread(&z->Act[b].Stage[c].LevelXR, 2, 1, pzf);
				fread(&z->Act[b].Stage[c].LevelYT, 2, 1, pzf);
				fread(&z->Act[b].Stage[c].LevelYB, 2, 1, pzf);
				fread(&z->Act[b].Stage[c].StartX[0], 2, 16, pzf);
				fread(&z->Act[b].Stage[c].StartY[0], 2, 16, pzf);
			}
		}
		
		fseek(pzf, x[1] + 4, SEEK_SET);	// Set it up to read the next act
	}
		
	////////////////////
	// READ OSC FILES //
	////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->OSC_SizeTable = (unsigned int*)malloc(z->OSC_FileCount << 2);
	z->OSC_AddressTable = (unsigned int*)malloc(z->OSC_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->OSC_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->OSC_AddressTable[b] = filesize_data;
		z->OSC_SizeTable[b] = d;
		
		filesize_data += d;
		z->OSC = (unsigned char*)realloc(z->OSC, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->OSC[z->OSC_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	/////////////////////
	// READ BATT FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->BATT_SizeTable = (unsigned int*)malloc(z->BATT_FileCount << 2);
	z->BATT_AddressTable = (unsigned int*)malloc(z->BATT_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->BATT_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->BATT_AddressTable[b] = filesize_data;
		z->BATT_SizeTable[b] = d;
		
		filesize_data += d;
		z->BATT = (unsigned char*)realloc(z->BATT, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->BATT[z->BATT_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	/////////////////////
	// READ BDAT FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->BDAT_SizeTable = (unsigned int*)malloc(z->BDAT_FileCount << 2);
	z->BDAT_AddressTable = (unsigned int*)malloc(z->BDAT_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->BDAT_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->BDAT_AddressTable[b] = filesize_data;
		z->BDAT_SizeTable[b] = d;
		
		filesize_data += d;
		z->BDAT = (unsigned char*)realloc(z->BDAT, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->BDAT[z->BDAT_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
	
	//////////////////////
	// READ BLOCK FILES //
	//////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->BLOCK_SizeTable = (unsigned int*)malloc(z->BLOCK_FileCount << 2);
	z->BLOCK_AddressTable = (unsigned int*)malloc(z->BLOCK_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->BLOCK_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->BLOCK_AddressTable[b] = filesize_data;
		z->BLOCK_SizeTable[b] = d;
		
		filesize_data += d;
		z->BLOCK = (unsigned char*)realloc(z->BLOCK, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->BLOCK[z->BLOCK_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
	
	/////////////////////
	// READ BMAP FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->BMAP_SizeTable = (unsigned int*)malloc(z->BMAP_FileCount << 2);
	z->BMAP_AddressTable = (unsigned int*)malloc(z->BMAP_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->BMAP_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->BMAP_AddressTable[b] = filesize_data;
		z->BMAP_SizeTable[b] = d;
		
		filesize_data += d;
		z->BMAP = (unsigned char*)realloc(z->BMAP, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		//fread(&z->BMAP[z->BMAP_AddressTable[b]], 1, d, pzf);
		
		z->BMAP[z->BMAP_AddressTable[b]] = getc(pzf);
		fread(&z->BMAP[z->BMAP_AddressTable[b]+1], 4, (d-1)>>2, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	/////////////////////
	// READ BSOL FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->BSOL_SizeTable = (unsigned int*)malloc(z->BSOL_FileCount << 2);
	z->BSOL_AddressTable = (unsigned int*)malloc(z->BSOL_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->BSOL_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->BSOL_AddressTable[b] = filesize_data;
		z->BSOL_SizeTable[b] = d;
		
		filesize_data += d;
		z->BSOL = (unsigned char*)realloc(z->BSOL, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->BSOL[z->BSOL_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
	
	////////////////////
	// READ OBJ FILES //
	////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->OBJ_SizeTable = (unsigned int*)malloc(z->OBJ_FileCount << 2);
	z->OBJ_AddressTable = (unsigned int*)malloc(z->OBJ_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->OBJ_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->OBJ_AddressTable[b] = filesize_data;
		z->OBJ_SizeTable[b] = d;
		
		filesize_data += d;
		z->OBJ = (unsigned char*)realloc(z->OBJ, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->OBJ[z->OBJ_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
	
	////////////////////
	// READ PAL FILES //
	////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->PAL_SizeTable = (unsigned int*)malloc(z->PAL_FileCount << 2);
	z->PAL_AddressTable = (unsigned int*)malloc(z->PAL_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->PAL_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->PAL_AddressTable[b] = filesize_data;
		z->PAL_SizeTable[b] = d;
		
		filesize_data += d;
		z->PAL = (unsigned char*)realloc(z->PAL, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->PAL[z->PAL_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
	
	/////////////////////
	// READ TMAP FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->TMAP_SizeTable = (unsigned int*)malloc(z->TMAP_FileCount << 2);
	z->TMAP_AddressTable = (unsigned int*)malloc(z->TMAP_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->TMAP_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->TMAP_AddressTable[b] = filesize_data;
		z->TMAP_SizeTable[b] = d;
		
		filesize_data += d;
		z->TMAP = (unsigned char*)realloc(z->TMAP, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->TMAP[z->TMAP_AddressTable[b]], 2, d>>1, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	/////////////////////
	// READ WMAP FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->WMAP_SizeTable = (unsigned int*)malloc(z->WMAP_FileCount << 2);
	z->WMAP_AddressTable = (unsigned int*)malloc(z->WMAP_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->WMAP_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->WMAP_AddressTable[b] = filesize_data;
		z->WMAP_SizeTable[b] = d;
		
		filesize_data += d;
		z->WMAP = (unsigned char*)realloc(z->WMAP, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->WMAP[z->WMAP_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
	
	/////////////////////
	// READ CCYC FILES //
	/////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->CCYC_SizeTable = (unsigned int*)malloc(z->CCYC_FileCount << 2);
	z->CCYC_AddressTable = (unsigned int*)malloc(z->CCYC_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->CCYC_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->CCYC_AddressTable[b] = filesize_data;
		z->CCYC_SizeTable[b] = d;
		
		filesize_data += d;
		z->CCYC = (unsigned char*)realloc(z->CCYC, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->CCYC[z->CCYC_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	/////////////////////////////////
	// READ FILTERDISTORTION FILES //
	/////////////////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->FILTERDISTORTION_SizeTable = (unsigned int*)malloc(z->FILTERDISTORTION_FileCount << 2);
	z->FILTERDISTORTION_AddressTable = (unsigned int*)malloc(z->FILTERDISTORTION_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->FILTERDISTORTION_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->FILTERDISTORTION_AddressTable[b] = filesize_data;
		z->FILTERDISTORTION_SizeTable[b] = d;
		
		filesize_data += d;
		z->FILTERDISTORTION = (unsigned char*)realloc(z->FILTERDISTORTION, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->FILTERDISTORTION[z->FILTERDISTORTION_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	/////////////////////////////////
	// READ FILTERCOMPOSITE FILES //
	/////////////////////////////////
	fseek(pzf, x[0], SEEK_SET);
	z->FILTERCOMPOSITE_SizeTable = (unsigned int*)malloc(z->FILTERCOMPOSITE_FileCount << 2);
	z->FILTERCOMPOSITE_AddressTable = (unsigned int*)malloc(z->FILTERCOMPOSITE_FileCount << 2);
	filesize_data = 0;
	
	fread(&a, 4, 1, pzf);		// Read table address
	x[0] = ftell(pzf);			// Save current position
	fseek(pzf, a, SEEK_SET);	// Jump to address
	
	for(b=0; b < z->FILTERCOMPOSITE_FileCount; b++){
		x[1] = ftell(pzf);
		d = 0;
		fread(&d, 3, 1, pzf);						// Read file size
		z->FILTERCOMPOSITE_AddressTable[b] = filesize_data;
		z->FILTERCOMPOSITE_SizeTable[b] = d;
		
		filesize_data += d;
		z->FILTERCOMPOSITE = (unsigned char*)realloc(z->FILTERCOMPOSITE, filesize_data);
		fread(&a, 4, 1, pzf);			// Read file address
		fseek(pzf, a, SEEK_SET);		// Jump to address
		
		fread(&z->FILTERCOMPOSITE[z->FILTERCOMPOSITE_AddressTable[b]], 1, d, pzf);
		
		fseek(pzf, x[1] + 7, SEEK_SET);	// Set it up to read the next file
	}
		
	fclose(pzf);
	return 0;
}







int SaveZone(ZONE *z, const char *string, ...)
{
	int		x[13];
	int		y[256];
	FILE	*pzf;
	a = 0;
	b = 0;
	c = 0;
	d = 0;
	
	//if(pzf == ENOMEM)
	pzf = fopen(string, "wb");
	
	a = 'P';
	b = 'Z';
	c = 'F';
	d = 0;	// version
	fwrite(&a, 1, 1, pzf);
	fwrite(&b, 1, 1, pzf);
	fwrite(&c, 1, 1, pzf);
	fwrite(&d, 1, 1, pzf);
	
	fwrite(&z->LevelName1, 1, 20, pzf);
	fwrite(&z->LevelName2, 1, 20, pzf);
	
	
	
	a = 0;
	
	fwrite(&z->Act_FileCount, 1, 1, pzf);
	fwrite(&z->OSC_FileCount, 1, 1, pzf);
	fwrite(&z->BATT_FileCount, 1, 1, pzf);
	fwrite(&z->BDAT_FileCount, 1, 1, pzf);
	fwrite(&z->BLOCK_FileCount, 1, 1, pzf);
	fwrite(&z->BMAP_FileCount, 1, 1, pzf);
	fwrite(&z->BSOL_FileCount, 1, 1, pzf);
	fwrite(&z->OBJ_FileCount, 1, 1, pzf);
	fwrite(&z->PAL_FileCount, 1, 1, pzf);
	fwrite(&z->TMAP_FileCount, 1, 1, pzf);
	fwrite(&z->WMAP_FileCount, 1, 1, pzf);
	fwrite(&z->CCYC_FileCount, 1, 1, pzf);
	fwrite(&z->FILTERDISTORTION_FileCount, 1, 1, pzf);
	fwrite(&z->FILTERCOMPOSITE_FileCount, 1, 1, pzf);
	
	x[0] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[1] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[2] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[3] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[4] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[5] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[6] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[7] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[8] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[9] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[10] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[11] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[12] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	x[13] = ftell(pzf);			// Save current position
	fwrite(&a, 4, 1, pzf);
	
	/////////////////////
	// WRITE ACT FILES //
	/////////////////////
	a = ftell(pzf);				// save the table address
	fseek(pzf, x[0], SEEK_SET);	// go back to table pointer
	fwrite(&a, 4, 1, pzf);		// write address value to pointer
	fseek(pzf, a, SEEK_SET);	// go back to the table
	
	a = 0;
	// Setup the act file table
	for(b=0; b < z->Act_FileCount; b++){
		fwrite(&z->Act[b].IncludedStages, 1, 1, pzf);
		y[b] = ftell(pzf);
		fwrite(&a, 4, 1, pzf);
	}
	
	// Write the act files
	for(b=0; b < z->Act_FileCount; b++){
		a = ftell(pzf);				// save the act file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the act table
		fwrite(&a, 4, 1, pzf);		// write address value to act file
		fseek(pzf, a, SEEK_SET);	// go back to the act file
		
		for(c=0; c<4; c++){
			switch(c){
				case 0:
					a = (z->Act[b].IncludedStages & 1);
					break;
					
				case 1:
					a = ((z->Act[b].IncludedStages >> 1) & 1);
					break;
					
				case 2:
					a = ((z->Act[b].IncludedStages >> 2) & 1);
					break;
					
				default:
					a = ((z->Act[b].IncludedStages >> 3) & 1);
			}
			
			if(a == 1){
				fwrite(&(z->Act[b].Stage[c].Name), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].ActNumber), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].MusicRegular), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].MusicAlternate), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].OpeningScript), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].ClosingScript), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].ActiveScript), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].WaterEnable), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].WrapPoint), 2, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].AboveWaterFilterL), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BelowWaterFilterL), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].AboveWaterFilterSpeed), 4, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BelowWaterFilterSpeed), 4, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].ClearBackground), 1, 1, pzf);
				// PLACE HOLDER FOR 0x10E
				fwrite(&(z->Act[b].Stage[c].Palette), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].ColorCycle), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].WaterMap), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BlockMap), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BlockArt), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BlockData), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BlockAttributes), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].BlockSolidity), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].TileMap), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].ObjectLayout), 1, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].WaterHeight), 2, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].LevelXL), 2, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].LevelXR), 2, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].LevelYT), 2, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].LevelYB), 2, 1, pzf);
				fwrite(&(z->Act[b].Stage[c].StartX[0]), 2, 16, pzf);
				fwrite(&(z->Act[b].Stage[c].StartY[0]), 2, 16, pzf);
			}
		}
	}
	
	/////////////////////
	// WRITE OSC FILES //
	/////////////////////
	a = ftell(pzf);
	fseek(pzf, x[1], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->OSC_FileCount; b++){
		fwrite(&z->OSC_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->OSC_FileCount; b++){
		a = ftell(pzf);				// save the OSC file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the OSC table
		fwrite(&a, 4, 1, pzf);		// write address to OSC file
		fseek(pzf, a, SEEK_SET);	// go back to the OSC file
		
		a = z->OSC_AddressTable[b];
		
		// Write file
		for(c=0; c < z->OSC_SizeTable[b]; c++)
			fwrite(&z->OSC[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE BATT FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[2], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->BATT_FileCount; b++){
		fwrite(&z->BATT_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->BATT_FileCount; b++){
		a = ftell(pzf);				// save the BATT file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the BATT table
		fwrite(&a, 4, 1, pzf);		// write address to BATT file
		fseek(pzf, a, SEEK_SET);	// go back to the BATT file
		
		a = z->BATT_AddressTable[b];
		
		// Write file
		for(c=0; c < z->BATT_SizeTable[b]; c++)
			fwrite(&z->BATT[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE BDAT FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[3], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->BDAT_FileCount; b++){
		fwrite(&z->BDAT_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->BDAT_FileCount; b++){
		a = ftell(pzf);				// save the BDAT file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the BDAT table
		fwrite(&a, 4, 1, pzf);		// write address to BDAT file
		fseek(pzf, a, SEEK_SET);	// go back to the BDAT file
		
		a = z->BDAT_AddressTable[b];
		
		// Write file
		for(c=0; c < z->BDAT_SizeTable[b]; c++)
			fwrite(&z->BDAT[a+c], 1, 1, pzf);
	}
	
	///////////////////////
	// WRITE BLOCK FILES //
	///////////////////////
	a = ftell(pzf);
	fseek(pzf, x[4], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->BLOCK_FileCount; b++){
		fwrite(&z->BLOCK_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->BLOCK_FileCount; b++){
		a = ftell(pzf);				// save the BLOCK file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the BLOCK table
		fwrite(&a, 4, 1, pzf);		// write address to BLOCK file
		fseek(pzf, a, SEEK_SET);	// go back to the BLOCK file
		
		a = z->BLOCK_AddressTable[b];
		
		// Write file
		for(c=0; c < z->BLOCK_SizeTable[b]; c++)
			fwrite(&z->BLOCK[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE BMAP FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[5], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->BMAP_FileCount; b++){
		fwrite(&z->BMAP_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->BMAP_FileCount; b++){
		a = ftell(pzf);				// save the BMAP file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the BMAP table
		fwrite(&a, 4, 1, pzf);		// write address to BMAP file
		fseek(pzf, a, SEEK_SET);	// go back to the BMAP file
		
		a = z->BMAP_AddressTable[b];
		
		// Write file
		for(c=0; c < z->BMAP_SizeTable[b]; c++)
			fwrite(&z->BMAP[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE BSOL FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[6], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->BSOL_FileCount; b++){
		fwrite(&z->BSOL_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->BSOL_FileCount; b++){
		a = ftell(pzf);				// save the BSOL file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the BSOL table
		fwrite(&a, 4, 1, pzf);		// write address to BSOL file
		fseek(pzf, a, SEEK_SET);	// go back to the BSOL file
		
		a = z->BSOL_AddressTable[b];
		
		// Write file
		for(c=0; c < z->BSOL_SizeTable[b]; c++)
			fwrite(&z->BSOL[a+c], 1, 1, pzf);
	}
	
	/////////////////////
	// WRITE OBJ FILES //
	/////////////////////
	a = ftell(pzf);
	fseek(pzf, x[7], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->OBJ_FileCount; b++){
		fwrite(&z->OBJ_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->OBJ_FileCount; b++){
		a = ftell(pzf);				// save the OBJ file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the OBJ table
		fwrite(&a, 4, 1, pzf);		// write address to OBJ file
		fseek(pzf, a, SEEK_SET);	// go back to the OBJ file
		
		a = z->OBJ_AddressTable[b];
		
		// Write file
		for(c=0; c < z->OBJ_SizeTable[b]; c++)
			fwrite(&z->OBJ[a+c], 1, 1, pzf);
	}
	
	/////////////////////
	// WRITE PAL FILES //
	/////////////////////
	a = ftell(pzf);
	fseek(pzf, x[8], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->PAL_FileCount; b++){
		fwrite(&z->PAL_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->PAL_FileCount; b++){
		a = ftell(pzf);				// save the PAL file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the PAL table
		fwrite(&a, 4, 1, pzf);		// write address to PAL file
		fseek(pzf, a, SEEK_SET);	// go back to the PAL file
		
		a = z->PAL_AddressTable[b];
		
		// Write file
		for(c=0; c < z->PAL_SizeTable[b]; c++)
			fwrite(&z->PAL[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE TMAP FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[9], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->TMAP_FileCount; b++){
		fwrite(&z->TMAP_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->TMAP_FileCount; b++){
		a = ftell(pzf);				// save the TMAP file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the TMAP table
		fwrite(&a, 4, 1, pzf);		// write address to TMAP file
		fseek(pzf, a, SEEK_SET);	// go back to the TMAP file
		
		a = z->TMAP_AddressTable[b];
		
		// Write file
		for(c=0; c < z->TMAP_SizeTable[b]; c++)
			fwrite(&z->TMAP[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE WMAP FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[10], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->WMAP_FileCount; b++){
		fwrite(&z->WMAP_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->WMAP_FileCount; b++){
		a = ftell(pzf);				// save the WMAP file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the WMAP table
		fwrite(&a, 4, 1, pzf);		// write address to WMAP file
		fseek(pzf, a, SEEK_SET);	// go back to the WMAP file
		
		a = z->WMAP_AddressTable[b];
		
		// Write file
		for(c=0; c < z->WMAP_SizeTable[b]; c++)
			fwrite(&z->WMAP[a+c], 1, 1, pzf);
	}
	
	//////////////////////
	// WRITE CCYC FILES //
	//////////////////////
	a = ftell(pzf);
	fseek(pzf, x[11], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->CCYC_FileCount; b++){
		fwrite(&z->CCYC_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->CCYC_FileCount; b++){
		a = ftell(pzf);				// save the CCYC file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the CCYC table
		fwrite(&a, 4, 1, pzf);		// write address to CCYC file
		fseek(pzf, a, SEEK_SET);	// go back to the CCYC file
		
		a = z->CCYC_AddressTable[b];
		
		// Write file
		for(c=0; c < z->CCYC_SizeTable[b]; c++)
			fwrite(&z->CCYC[a+c], 1, 1, pzf);
	}
	
	//////////////////////////////////
	// WRITE FILTERDISTORTION FILES //
	//////////////////////////////////
	a = ftell(pzf);
	fseek(pzf, x[12], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->FILTERDISTORTION_FileCount; b++){
		fwrite(&z->FILTERDISTORTION_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->FILTERDISTORTION_FileCount; b++){
		a = ftell(pzf);				// save the FILTERDISTORTION file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the FILTERDISTORTION table
		fwrite(&a, 4, 1, pzf);		// write address to FILTERDISTORTION file
		fseek(pzf, a, SEEK_SET);	// go back to the FILTERDISTORTION file
		
		a = z->FILTERDISTORTION_AddressTable[b];
		
		// Write file
		for(c=0; c < z->FILTERDISTORTION_SizeTable[b]; c++)
			fwrite(&z->FILTERDISTORTION[a+c], 1, 1, pzf);
	}
	
	/////////////////////////////////
	// WRITE FILTERCOMPOSITE FILES //
	/////////////////////////////////
	a = ftell(pzf);
	fseek(pzf, x[13], SEEK_SET);
	fwrite(&a, 4, 1, pzf);
	fseek(pzf, a, SEEK_SET);
	
	a = 0;
	for(b=0; b < z->FILTERCOMPOSITE_FileCount; b++){
		fwrite(&z->FILTERCOMPOSITE_SizeTable[b], 3, 1, pzf);	// write 24-bit size
		y[b] = ftell(pzf);							// save address position
		fwrite(&a, 4, 1, pzf);						// address holder
	}
	
	for(b=0; b < z->FILTERCOMPOSITE_FileCount; b++){
		a = ftell(pzf);				// save the FILTERCOMPOSITE file address
		fseek(pzf, y[b], SEEK_SET);	// go back to the FILTERCOMPOSITE table
		fwrite(&a, 4, 1, pzf);		// write address to FILTERCOMPOSITE file
		fseek(pzf, a, SEEK_SET);	// go back to the FILTERCOMPOSITE file
		
		a = z->FILTERCOMPOSITE_AddressTable[b];
		
		// Write file
		for(c=0; c < z->FILTERCOMPOSITE_SizeTable[b]; c++)
			fwrite(&z->FILTERCOMPOSITE[a+c], 1, 1, pzf);
	}
	
	fclose(pzf);
	return 0;
}
