#include	<stdio.h>
#include	<allegro.h>

#include	"tools.h"
#include	"strings.h"
#include	"common.h"
#include	"text.h"
#include	"sprites.h"
#include	"draw.h"
#include	"obj01.h"

void ShowBlockInfo(ZONE *z){
	unsigned short val_tile_offset;
	int val_bmap_offset;
	
	char r, g, b;
	short val_block_offset;
	
	short val_tile;			// 14 bits	>> 0	& 0x3FFF
	unsigned int val_bmap;	// 32 bits	----	----
	short val_block;		// 14 bits	>> 0	& 0x3FFF
	char val_mirror;		// 1 bit	>> 14	& 0x1
	char val_flip;			// 1 bit	>> 15	& 0x1
	char val_platform1;		// 1 bit	>> 22	& 0x1
	char val_barrier1;		// 1 bit	>> 23	& 0x1
	char val_platform2;		// 1 bit	>> 22	& 0x1
	char val_barrier2;		// 1 bit	>> 23	& 0x1
	char val_plane;			// 1 bit	>> 20	& 0x1
	char val_translucency;	// 4 bits	>> 16	& 0xF
	//char VAL_RESERVED;	// 1 bit	>> 21	& 0x1
	
	//short NumberOfTiles;
	short FullTileSize = (32 << tilesize);
	short TileBlockRow = (2 << tilesize);
	short TileMemoryBits = (4 + (tilesize << 1));	// How many bits to shift
	
	short OffsetX;
	short OffsetY;
	
	char tileblock_changed = 0;
	
	
	
	// TEMPORARY SOLUTION TO BAR PEOPLE FROM USING CRASH-PRONE EDITORS
	if(edit_mode > 1)
		edit_mode = 0;
	
	
	
	if(!edit_mode) return;
	
	
	
	//if(mouse_x < 0 || mouse_y > screen_resolution_x) return;
	//if(mouse_y < 0 || mouse_y > screen_resolution_y) return;
	
	OffsetX = p->Camera_X_pos + (((mouse_pos >> 16) - (screen_offset_x << screen_double_x)) >> screen_double_x);
	OffsetY = p->Camera_Y_pos + (((mouse_pos & 0xFFFF) - (screen_offset_y << screen_double_y)) >> screen_double_y);
	
	// correction for 320x224 with bars at top and bottom of screen
	if((mouse_pos >> 16) < (screen_offset_x << screen_double_x))
		OffsetX = p->Camera_X_pos + (screen_offset_x >> screen_double_x);
	else if((mouse_pos >> 16) >= ((screen_resolution_x + screen_offset_x) << screen_double_x))
		OffsetX = p->Camera_X_pos + ((screen_resolution_x + screen_offset_x) << screen_double_x) - 1;
	
	// correction for 320x224 with bars at top and bottom of screen
	if((mouse_pos & 0xFFFF) < (screen_offset_y << screen_double_y))
		OffsetY = p->Camera_Y_pos + (screen_offset_y >> screen_double_y);
	else if((mouse_pos & 0xFFFF) >= ((screen_resolution_y + screen_offset_y) << screen_double_y))
		OffsetY = p->Camera_Y_pos + ((screen_resolution_y + screen_offset_y) << screen_double_y) - 1;
	
	val_tile_offset = (OffsetX / FullTileSize)
	 +((OffsetY & z->Act[act].Stage[stage].WrapPoint-1) / FullTileSize * tiles_x_long);
	val_tile = *(short *)(&z->TMAP[tmap_ptr+((val_tile_offset) << 1)]);
	
	if(val_tile > 0){
		val_bmap_offset = bmap_ptr
		 +(val_tile << TileMemoryBits)
		 +(((OffsetX >> 4) & (TileBlockRow-1)) << 2)
		 +(((((OffsetY & z->Act[act].Stage[stage].WrapPoint-1) >> 4) & (TileBlockRow-1)) << 2) * TileBlockRow);
		val_bmap = *(int *)(&z->BMAP[val_bmap_offset]);
		
		
		
		val_block = val_bmap & 0x3FFF;
		val_mirror = (val_bmap >> 14) & 1;
		val_flip = (val_bmap >> 15) & 1;
		val_platform1 = (val_bmap >> 16) & 1;
		val_barrier1 = (val_bmap >> 17) & 1;
		val_platform2 = (val_bmap >> 18) & 1;
		val_barrier2 = (val_bmap >> 19) & 1;
		val_plane = (val_bmap >> 20) & 1;
		val_translucency = (val_bmap >> 26) & 0x3F;
		
		
		
		OffsetX = ((mouse_pos >> 16) - (screen_offset_x << screen_double_x)) >> screen_double_x;
		OffsetY = ((mouse_pos & 0xFFFF) - (screen_offset_y << screen_double_y)) >> screen_double_y;
		
		// correction for 320x224 with bars at top and bottom of screen
		if((mouse_pos >> 16) < (screen_offset_x << screen_double_x))
			OffsetX = (screen_offset_x >> screen_double_x);
		else if((mouse_pos >> 16) >= ((screen_resolution_x + screen_offset_x) << screen_double_x))
			OffsetX = ((screen_resolution_x + screen_offset_x) << screen_double_x) - 1;
		
		// correction for 320x224 with bars at top and bottom of screen
		if((mouse_pos & 0xFFFF) < (screen_offset_y << screen_double_y))
			OffsetY = (screen_offset_y >> screen_double_y);
		else if((mouse_pos & 0xFFFF) >= ((screen_resolution_y + screen_offset_y) << screen_double_y))
			OffsetY = ((screen_resolution_y + screen_offset_y) << screen_double_y) - 1;
		
		
		
		if(edit_mode < EDIT_MODE_SOLIDITY){
			DrawSprite(&(*z), LayerL[frame-1], 0x102, 1, NORMAL, 24, ((OffsetX+16) + (p->Camera_X_pos & 0xF) & 0xFFF0) - (p->Camera_X_pos & 0xF), (OffsetY + (p->Camera_Y_pos & 0xF) & 0xFFF0) - (p->Camera_Y_pos & 0xF));
			DrawSprite(&(*z), LayerL[frame-1], 0x102, 0, NORMAL, 40, (OffsetX+16) + 0xC, OffsetY + 0xC);
			DrawText(OffsetX + 0x10, OffsetY + 0x10, (edit_selector == 0), "TILE");
			DrawText(OffsetX + 0x10, OffsetY + 0x18, (edit_selector == 1), "BLOCK");
			DrawText(OffsetX + 0x10, OffsetY + 0x20, (edit_selector == 2), "MIRROR");
			DrawText(OffsetX + 0x10, OffsetY + 0x28, (edit_selector == 3), "FLIP");
			DrawText(OffsetX + 0x10, OffsetY + 0x30, (edit_selector == 4), "PLAT");
			DrawText(OffsetX + 0x10, OffsetY + 0x38, (edit_selector == 5), "BARR");
			DrawText(OffsetX + 0x10, OffsetY + 0x40, (edit_selector == 6), "PLANE");
			DrawText(OffsetX + 0x10, OffsetY + 0x48, (edit_selector == 7), "TRANS");
			DrawCounter16(LayerH[frame-1], val_tile, OffsetX + 0x48, OffsetY + 0x10);
			DrawCounter16(LayerH[frame-1], val_block, OffsetX + 0x48, OffsetY + 0x18);
			DrawCounter16(LayerH[frame-1], val_mirror, OffsetX + 0x48, OffsetY + 0x20);
			DrawCounter16(LayerH[frame-1], val_flip, OffsetX + 0x48, OffsetY + 0x28);
			DrawCounter16(LayerH[frame-1], (val_platform2 << 8) + val_platform1, OffsetX + 0x48, OffsetY + 0x30);
			DrawCounter16(LayerH[frame-1], (val_barrier2 << 8) + val_barrier1, OffsetX + 0x48, OffsetY + 0x38);
			DrawCounter16(LayerH[frame-1], val_plane, OffsetX + 0x48, OffsetY + 0x40);
			DrawCounter16(LayerH[frame-1], val_translucency, OffsetX + 0x48, OffsetY + 0x48);
		}
		else{
			//n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
			val_block_offset = z->BLOCK_AddressTable[z->Act[act].Stage[stage].BlockArt]+2;
			for(i=0; i < 32; i++){
				for(n=0; n < 32; n++){
					if(i+OffsetY + 0xC + 36 < screen_buffer_y
					 && i+OffsetY + 0xC + 36 >= 0
					 && n+(OffsetX+16) + 0xC < screen_buffer_x
					 && n+(OffsetX+16) + 0xC >= 0){
						r = z->BLOCK[val_block_offset+(val_block<<10) + 1 + ((i>>1)<<6) + ((n>>1)<<2)];
						g = z->BLOCK[val_block_offset+(val_block<<10) + 2 + ((i>>1)<<6) + ((n>>1)<<2)];
						b = z->BLOCK[val_block_offset+(val_block<<10) + 3 + ((i>>1)<<6) + ((n>>1)<<2)];
						if(r < 64 && g < 64 && b < 64){
							LayerH[frame-1]->line
							[i+OffsetY + 0xC + 36]
							[n+(OffsetX+16) + 0x10]
							= 1;//////ColorTable[r][g][b];
						}
					}
				}
			}
			for(i=0; i < 32; i++){
				for(n=0; n < 32; n++){
					if(i+OffsetY + 0xC + 36 < screen_buffer_y
					 && i+OffsetY + 0xC + 36 >= 0
					 && n+(OffsetX+16) + 0xC + 32 < screen_buffer_x
					 && n+(OffsetX+16) + 0xC + 32 >= 0
					 && (i>>1)+((OffsetY + (p->Camera_Y_pos & 0xF) & 0xFFF0) - (p->Camera_Y_pos & 0xF)) < screen_buffer_y
					 && (i>>1)+((OffsetY + (p->Camera_Y_pos & 0xF) & 0xFFF0) - (p->Camera_Y_pos & 0xF)) >= 0
					 && (n>>1)+((OffsetX+16) + (p->Camera_X_pos & 0xF) & 0xFFF0) - (p->Camera_X_pos & 0xF) < screen_buffer_x
					 && (n>>1)+((OffsetX+16) + (p->Camera_X_pos & 0xF) & 0xFFF0) - (p->Camera_X_pos & 0xF) >= 0){
						LayerH[frame-1]->line
						[i+OffsetY + 0xC + 36]
						[n+(OffsetX+16) + 0x10 + 32]
						=
						LayerL[frame-1]->line
						[(i>>1)+((OffsetY + (p->Camera_Y_pos & 0xF) & 0xFFF0) - (p->Camera_Y_pos & 0xF))]
						[(n>>1)+((OffsetX+16) + (p->Camera_X_pos & 0xF) & 0xFFF0) - (p->Camera_X_pos & 0xF)];
					}
				}
			}
			if(selection_a < 16){
				if(OffsetY + 0xC + 36 + 34 < screen_buffer_y
				 && OffsetY + 0xC + 36 + 33 >= 0
				 && (selection_a << 1) + (OffsetX+16) + 0xC + 33 < screen_buffer_x
				 && (selection_a << 1) + (OffsetX+16) + 0xC + 32 >= 0){
					LayerH[frame-1]->line
					[OffsetY + 0xC + 36 + 34]
					[(selection_a << 1) + (OffsetX+16) + 0x10 + 32]
					= 1;
					LayerH[frame-1]->line
					[OffsetY + 0xC + 36 + 35]
					[(selection_a << 1) + (OffsetX+16) + 0x10 + 32]
					= 1;
					LayerH[frame-1]->line
					[OffsetY + 0xC + 36 + 34]
					[(selection_a << 1) + (OffsetX+16) + 0x10 + 33]
					= 1;
					LayerH[frame-1]->line
					[OffsetY + 0xC + 36 + 35]
					[(selection_a << 1) + (OffsetX+16) + 0x10 + 33]
					= 1;
				}
			}
			else{
				if(OffsetY + 0xC + 36 + 34 < screen_buffer_y
				 && OffsetY + 0xC + 36 + 33 >= 0
				 && (selection_a << 1) + (OffsetX+16) + 0xC + 33 < screen_buffer_x
				 && (selection_a << 1) + (OffsetX+16) + 0xC + 32 >= 0){
					LayerH[frame-1]->line
					[((31-selection_a) <<1) + OffsetY + 0xC + 36]
					[(OffsetX+16) + 0x10 + 32 + 34]
					= 1;
					LayerH[frame-1]->line
					[((31-selection_a) <<1) + OffsetY + 0xC + 37]
					[(OffsetX+16) + 0x10 + 32 + 34]
					= 1;
					LayerH[frame-1]->line
					[((31-selection_a) <<1) + OffsetY + 0xC + 36]
					[(OffsetX+16) + 0x10 + 32 + 35]
					= 1;
					LayerH[frame-1]->line
					[((31-selection_a) <<1) + OffsetY + 0xC + 37]
					[(OffsetX+16) + 0x10 + 32 + 35]
					= 1;
				}
			}
			DrawSprite(&(*z), LayerL[frame-1], 0x102, 1, NORMAL, 24, (((OffsetX+16) + (p->Camera_X_pos & 0xF) & 0xFFF0) - (p->Camera_X_pos & 0xF)) >> screen_double_x, ((OffsetY + (p->Camera_Y_pos & 0xF) & 0xFFF0) - (p->Camera_Y_pos & 0xF)) >> screen_double_y);
			DrawSprite(&(*z), LayerL[frame-1], 0x102, 0, NORMAL, 40, ((OffsetX+16) + 0xC) >> screen_double_x, (OffsetY + 0xC) >> screen_double_y);
			if(edit_selector == 0)	DrawText(OffsetX + 0x10, OffsetY + 0x10, 1, "SLOPE1");
			else					DrawText(OffsetX + 0x10, OffsetY + 0x10, 0, "SLOPE1");
			if(edit_selector == 1)	DrawText(OffsetX + 0x10, OffsetY + 0x18, 1, "SLOPE2");
			else					DrawText(OffsetX + 0x10, OffsetY + 0x18, 0, "SLOPE2");
			if(edit_selector == 2)	DrawText(OffsetX + 0x10, OffsetY + 0x20, 1, "SOLID1");
			else					DrawText(OffsetX + 0x10, OffsetY + 0x20, 0, "SOLID1");
			if(edit_selector == 3)	DrawText(OffsetX + 0x10, OffsetY + 0x28, 1, "SOLID2");
			else					DrawText(OffsetX + 0x10, OffsetY + 0x28, 0, "SOLID2");
			n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
			DrawCounter16(LayerH[frame-1], z->BATT[n + val_block], OffsetX + 0x48, OffsetY + 0x10);
			DrawCounter16(LayerH[frame-1], z->BATT[n + val_block + 0x400], OffsetX + 0x48, OffsetY + 0x18);
		}
	}
	
	
	
	if(waitCounter == 0){
		switch(edit_mode){
			case EDIT_MODE_TILE_LAYOUT:
				edit_selector = 0;
				
				if(mouse_z != mouse_z_previous){
					val_tile += (mouse_z - mouse_z_previous);
					val_tile &= 0xFF;
					tileblock_changed = 1;
					mouse_z_previous = mouse_z;
				}
				
				if(key[KEY_C] && (key[KEY_LCONTROL] || key[KEY_RCONTROL])){
					edit_clipboard = val_tile;
					waitCounter = 12;
				}
				else if(key[KEY_V] && (key[KEY_LCONTROL] || key[KEY_RCONTROL])){
					val_tile = edit_clipboard;
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_DEL]){
					val_tile = 0;
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_EQUALS] || key[KEY_PLUS_PAD]){
					val_tile++;
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_MINUS] || key[KEY_MINUS_PAD]){
					val_tile--;
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_ASTERISK]){
					val_tile += 0x10;
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_SLASH] || key[KEY_SLASH_PAD]){
					val_tile -= 0x10;
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_TAB]){
					clear(LayerH[frame-1]);
					InputText((screen_resolution_x >> 1)-156, (screen_resolution_y >> 1)-8, 0, STR_MSG_OPEN_FILE);
					tilefile = load_bitmap(TextBuffer, NULL);
					if(tilefile && (tilefile->w < 128 || tilefile->h < 128))
						allegro_message("Bitmap image is too small! Must be at least 128x128.");
					else if(tilefile){
						while(!key[KEY_ENTER] && !key[KEY_ESC]){
							while(ticUpdated == 0);	// wait until 'ticUpdated' is 1
							ticUpdated = 0;
							clear(LayerH[frame-1]);
							blit(tilefile, LayerH[frame-1], coordinate_x, coordinate_y, 0, 0, tilefile->w, tilefile->h);
							
							OffsetX = mouse_pos >> 16;
							OffsetY = mouse_pos & 0xFFFF;
							if(OffsetX < 64)	OffsetX = 64;
							if(OffsetY < 64)	OffsetY = 64;
							if(screen_resolution_x - OffsetX < 64)
								OffsetX = screen_resolution_x - 64;
							if(screen_resolution_y - OffsetY < 64)
								OffsetY = screen_resolution_y - 64;
							if(tilefile->w < screen_resolution_x && OffsetX > tilefile->w - 64)
								OffsetX = tilefile->w - 64;
							if(tilefile->h < screen_resolution_y && OffsetY > tilefile->h - 64)
								OffsetY = tilefile->h - 64;
							
							for(n=0; n < 128; n++){
								LayerH[frame-1]->line[OffsetY-64][(OffsetX-64+n)<<1] = ~LayerH[frame-1]->line[OffsetY-64][(OffsetX-64+n)<<1];
								LayerH[frame-1]->line[OffsetY-64][((OffsetX-64+n)<<1)+1] = ~LayerH[frame-1]->line[OffsetY-64][((OffsetX-64+n)<<1)+1];
								LayerH[frame-1]->line[OffsetY+63][(OffsetX-64+n)<<1] = ~LayerH[frame-1]->line[OffsetY+63][(OffsetX-64+n)<<1];
								LayerH[frame-1]->line[OffsetY+63][((OffsetX-64+n)<<1)+1] = ~LayerH[frame-1]->line[OffsetY+63][((OffsetX-64+n)<<1)+1];
							}
							for(n=0; n < 128; n++){
								LayerH[frame-1]->line[OffsetY-64+n][(OffsetX-64)<<1] = ~LayerH[frame-1]->line[OffsetY-64+n][(OffsetX-64)<<1];
								LayerH[frame-1]->line[OffsetY-64+n][((OffsetX-64)<<1)+1] = ~LayerH[frame-1]->line[OffsetY-64+n][((OffsetX-64)<<1)+1];
								LayerH[frame-1]->line[OffsetY-64+n][(OffsetX+63)<<1] = ~LayerH[frame-1]->line[OffsetY-64+n][(OffsetX+63)<<1];
								LayerH[frame-1]->line[OffsetY-64+n][((OffsetX+63)<<1)+1] = ~LayerH[frame-1]->line[OffsetY-64+n][((OffsetX+63)<<1)+1];
							}
							
							DrawCounter16(LayerH[frame-1], OffsetX-64 + coordinate_x, OffsetX-52, OffsetY-12);
							DrawCounter16(LayerH[frame-1], OffsetY-64 + coordinate_y, OffsetX-12, OffsetY-12);
							blit(LayerH[frame-1], screen, 0, 0, 0, 0, screen_buffer_x, screen_buffer_y);
							
							if(key[KEY_UP] && coordinate_y > 0)
								coordinate_y -= 8;
							else if(key[KEY_DOWN] && tilefile->h - coordinate_y > screen_resolution_y)
								coordinate_y += 8;
							
							if(key[KEY_LEFT] && coordinate_x > 0)
								coordinate_x -= 8;
							else if(key[KEY_RIGHT] && tilefile->w - coordinate_x > screen_resolution_x)
								coordinate_x += 8;
							
							if(tilefile->h - coordinate_y <= screen_resolution_y)
								coordinate_y = tilefile->h - screen_resolution_y;
							if(coordinate_y < 0)
								coordinate_y = 0;
							if(tilefile->w - coordinate_x <= screen_resolution_x)
								coordinate_x = tilefile->w - screen_resolution_x;
							if(coordinate_x < 0)
								coordinate_x = 0;
						}
						clear(LayerH[frame-1]);
						
						if(key[KEY_ENTER]){
							// store blocks into work memory
							destroy_bitmap(tilefile);
							tilefile = 0;
							set_color_depth(24);
							tilefile = load_bitmap(TextBuffer, NULL);
							
							// FIX ME!!!
							
							for(n=0; n < 64; n++){ // 64 blocks
								for(i=0; i < 256; i++){ // 256 pixels each
									imported_blocks[n][i] = ((tilefile->line
									 [((n&56)<<1)+coordinate_y+OffsetY-64+(i>>4)]
									 [(((n&7)<<4)+coordinate_x+OffsetX-64+(i&15))*3]
									 >> 3) << 11);
									
									imported_blocks[n][i] |= ((tilefile->line
									 [((n&56)<<1)+coordinate_y+OffsetY-64+(i>>4)]
									 [((((n&7)<<4)+coordinate_x+OffsetX-64+(i&15))*3)+1]
									 >> 2) << 5);
									
									imported_blocks[n][i] |= (tilefile->line
									 [((n&56)<<1)+coordinate_y+OffsetY-64+(i>>4)]
									 [((((n&7)<<4)+coordinate_x+OffsetX-64+(i&15))*3)+2]
									 >> 3);
								}
							}
							
							destroy_bitmap(tilefile);
							tilefile = 0;
							set_color_depth(16);
							
							
							
							key[KEY_ENTER] = 0;
							rest(200);
							b = -1;
							while(b < 0){
								clear(LayerH[frame-1]);
								InputText((screen_resolution_x >> 1)-156, (screen_resolution_y >> 1)-8, 0, STR_MSG_REUSE_BLOCKS);
								if(strcmp(TextBuffer, "Y") != 0 && strcmp(TextBuffer, "y") != 0){
									if(strcmp(TextBuffer, "N") != 0 && strcmp(TextBuffer, "n") != 0)
										allegro_message("Invalid response! Please type 'Y' or 'N'");
									else
										b = 0;
								}
								else
									b = 1;
							}
							
							
							
							// clear block_matches[]
							for(i=0; i < 64; i++)
								block_matches[i] = 0;
							
							for(a=0; a < 64; a++){
								match_count = 0;
								// search for a pre-existing block
								for(n=0; n < 0x400; n++){	// block
									for(i=0; i < 0x100; i++){	// index
										if(*(unsigned short *)&z->BLOCK[block_ptr + (n << 9) + (i<<1)] == imported_blocks[a][i])
											match_count++;
										else{
											i = 0x100;
											match_count=0;
										}
									}
									if(match_count == 0x100){
										block_matches[a] = n + 0x4000;	// avoid using zero
										n = 0x400;
									}
								}
								
								// if after checking all blocks we still don't have a match
								if(block_matches[a] == 0 || (b == 0 && block_matches[a] != 0x4000)){
									// search for empty block
									match_count=0;
									for(n=1; n < 0x400; n++){	// block
										for(i=0; i < 0x100; i++){	// index
											if(*(unsigned short *)&z->BLOCK[block_ptr + (n << 9) + (i<<1)] == MASK_COLOR_16)
												match_count++;
											else{
												i = 0x100;
												match_count=0;
											}
										}
										// if empty block found
										if(match_count == 0x100){
											block_matches[a] = n + 0x4000;
											// make sure block isn't already in use
											/*for(i=0; i < 16384; i++){	// check 256 tiles, 64 blocks each
												if(((z->BMAP[bmap_ptr+(i<<2)+1]&0x3F)<<8) + z->BMAP[bmap_ptr+(i<<2)] == block_matches[a] - 0x4000){
													// the block is being used by a tile
													i = 16384;
													block_matches[a] = 0x4000;
												}
											}*/
											// if block isn't being used
											if(i < 16384){
												n = 0x400;
												// copy block into BLOCK memory
												for(i=0; i < 0x100; i++)
													*(unsigned short *)&z->BLOCK[block_ptr + ((block_matches[a]-0x4000) << 9) + (i<<1)] = imported_blocks[a][i];
											}
										}
									}
								}
							}
							
							for(n=0; n < 64; n++){
								z->BMAP[bmap_ptr + (val_tile << 8) + (n<<2)] = ((block_matches[n]-0x4000)&0xFF);
								z->BMAP[bmap_ptr + (val_tile << 8) + (n<<2)+1] = ((block_matches[n]-0x4000)>>8);
								z->BMAP[bmap_ptr + (val_tile << 8) + (n<<2)+2] = 0;
								z->BMAP[bmap_ptr + (val_tile << 8) + (n<<2)+3] = 0;
							}
						}
						tileblock_changed = 1;
						
						key[KEY_ENTER] = 0;
						key[KEY_ESC] = 0;
					}
					else
						allegro_message("Could not open \"%s\"!", TextBuffer);
					if(tilefile){
						destroy_bitmap(tilefile);
						tilefile = 0;
					}
				}
				
				if(val_tile < 0)
					val_tile = 256 + val_tile;
				else if(val_tile > 255)
					val_tile = val_tile - 256;
				
				z->TMAP[tmap_ptr+(val_tile_offset << 1)] = (val_tile & 0xFF);
				z->TMAP[tmap_ptr+(val_tile_offset << 1)+1] = (val_tile >> 8);
				
				if(tileblock_changed)
					UpdateBlockLayout(z);
				break;
				
			case EDIT_MODE_BLOCK_MAPPINGS:
				if(!edit_selector)
					edit_selector = 1;
				
				if(mouse_z != mouse_z_previous){
					val_block += (mouse_z - mouse_z_previous);
					val_block &= 0x3FF;
					mouse_z_previous = mouse_z;
				}
				
				if(key[KEY_CLOSEBRACE]){
					edit_selector++;
					edit_selector %= 8;
					if(!edit_selector)
						edit_selector = 1;
					waitCounter = 12;
				}
				else if(key[KEY_OPENBRACE]){
					edit_selector--;
					edit_selector %= 8;
					if(!edit_selector)
						edit_selector = 7;
					waitCounter = 12;
				}
				
				if(key[KEY_C] && (key[KEY_LCONTROL] || key[KEY_RCONTROL])){
					edit_clipboard = val_bmap;
					waitCounter = 12;
				}
				else if(key[KEY_V] && (key[KEY_LCONTROL] || key[KEY_RCONTROL])){
					val_block = edit_clipboard & 0x3FFF;
					val_mirror = (edit_clipboard >> 14) & 1;
					val_flip = (edit_clipboard >> 15) & 1;
					val_platform1 = (edit_clipboard >> 16) & 1;
					val_barrier1 = (edit_clipboard >> 17) & 1;
					val_platform2 = (edit_clipboard >> 18) & 1;
					val_barrier2 = (edit_clipboard >> 19) & 1;
					val_plane = (edit_clipboard >> 20) & 1;
					val_translucency = (edit_clipboard >> 26) & 0x3F;
					waitCounter = 12;
				}
				else if(key[KEY_DEL]){
					val_block = 0;
					waitCounter = 12;
				}
				else if(key[KEY_EQUALS] || key[KEY_PLUS_PAD]){
					switch(edit_selector){
						case 1:
							val_block++;		break;
						case 2:
							val_mirror^=1;		break;
						case 3:
							val_flip^=1;		break;
						case 4:
							val_platform1^=1;	break;
						case 5:
							val_barrier1^=1;	break;
						case 6:
							val_plane^=1;		break;
						case 7:
							val_translucency++;
					}
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_MINUS] || key[KEY_MINUS_PAD]){
					switch(edit_selector){
						case 1:
							val_block--;		break;
						case 2:
							val_mirror^=1;		break;
						case 3:
							val_flip^=1;		break;
						case 4:
							val_platform1^=1;	break;
						case 5:
							val_barrier1^=1;	break;
						case 6:
							val_plane^=1;		break;
						case 7:
							val_translucency--;
					}
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_ASTERISK]){
					switch(edit_selector){
						case 1:
							val_block += 0x10;			break;
						case 2:
							val_mirror^=1;				break;
						case 3:
							val_flip^=1;				break;
						case 4:
							val_platform2^=1;			break;
						case 5:
							val_barrier2^=1;			break;
						case 6:
							val_plane^=1;				break;
						case 7:
							val_translucency += 0x10;
					}
					tileblock_changed = 1;
					waitCounter = 12;
				}
				else if(key[KEY_SLASH] || key[KEY_SLASH_PAD]){
					switch(edit_selector){
						case 1:
							val_block -= 0x10;			break;
						case 2:
							val_mirror^=1;				break;
						case 3:
							val_flip^=1;				break;
						case 4:
							val_platform2^=1;			break;
						case 5:
							val_barrier2^=1;			break;
						case 6:
							val_plane^=1;				break;
						case 7:
							val_translucency -= 0x10;
					}
					tileblock_changed = 1;
					waitCounter = 12;
				}
				
				if(val_block < 0)
					val_block = 0x400 + val_block;
				else if(val_block > 0x3FF)
					val_block = val_block - 0x400;
				
				val_translucency &= 0x3F;
					
				val_bmap = val_block + (val_mirror << 14) + (val_flip << 15)
						+ (val_platform1 << 16) + (val_barrier1 << 17)
						+ (val_platform2 << 18) + (val_barrier2 << 19)
						+ (val_plane << 20) + (val_translucency << 26);
				
				z->BMAP[val_bmap_offset+3] = val_bmap >> 24;
				z->BMAP[val_bmap_offset+2] = val_bmap >> 16;
				z->BMAP[val_bmap_offset+1] = val_bmap >> 8;
				z->BMAP[val_bmap_offset] = val_bmap;
				
				if(tileblock_changed)
					UpdateBlockLayout(z);
				break;
				
			case EDIT_MODE_SOLIDITY:
				edit_selector &= 3;
				
				if(key[KEY_CLOSEBRACE]){
					edit_selector++;
					edit_selector &= 3;
					waitCounter = 12;
				}
				else if(key[KEY_OPENBRACE]){
					edit_selector--;
					edit_selector &= 3;
					waitCounter = 12;
				}
				
				if(key[KEY_END]){
					selection_a = (selection_a - 1) & 0x1F;
					waitCounter = 8;
				}
				else if(key[KEY_HOME]){
					selection_a = (selection_a + 1) & 0x1F;
					waitCounter = 8;
				}
				else if(key[KEY_EQUALS] || key[KEY_PLUS_PAD]){
					switch(edit_selector){
						case 0:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block]++;
							break;
						case 1:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block + 0x400]++;
							break;
						default:
							if(selection_a < 16){
								n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
								if(edit_selector == 2){
									z->BSOL[n + selection_a + (val_block << 5)]++;
									z->BSOL[n + selection_a + (val_block << 5)] %= 17;
								}
								if(edit_selector == 3){
									z->BSOL[n + selection_a + (val_block << 5) + 0x8000]++;
									z->BSOL[n + selection_a + (val_block << 5) + 0x8000] %= 17;
								}
							}
							else{
								n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
								if(edit_selector == 2){
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16]++;
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16] %= 17;
								}
								if(edit_selector == 3){
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16 + 0x8000]++;
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16 + 0x8000] %= 17;
								}
							}
					}
					waitCounter = 12;
				}
				else if(key[KEY_MINUS] || key[KEY_MINUS_PAD]){
					switch(edit_selector){
						case 0:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block]--;
							break;
						case 1:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block + 0x400]--;
							break;
						default:
							if(selection_a < 16){
								n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
								if(edit_selector == 2){
									z->BSOL[n + selection_a + (val_block << 5)]--;
									z->BSOL[n + selection_a + (val_block << 5)] %= 17;
								}
								if(edit_selector == 3){
									z->BSOL[n + selection_a + (val_block << 5) + 0x8000]--;
									z->BSOL[n + selection_a + (val_block << 5) + 0x8000] %= 17;
								}
							}
							else{
								n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
								if(edit_selector == 2){
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16]--;
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16] %= 17;
								}
								if(edit_selector == 3){
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16 + 0x8000]--;
									z->BSOL[n + (31-selection_a) + (val_block << 5)+16 + 0x8000] %= 17;
								}
							}
					}
					waitCounter = 12;
				}
				else if(key[KEY_ASTERISK]){
					switch(edit_selector){
						case 0:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block] += 0x10;
							break;
						case 1:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block + 0x400] += 0x10;
					}
					waitCounter = 12;
				}
				else if(key[KEY_SLASH] || key[KEY_SLASH_PAD]){
					switch(edit_selector){
						case 0:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block] -= 0x10;
							break;
						case 1:
							n = z->BATT_AddressTable[z->Act[act].Stage[stage].BlockAttributes];
							z->BATT[n + val_block + 0x400] -= 0x10;
					}
					waitCounter = 12;
				}
				else if(key[KEY_INSERT]){
					n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
					if(edit_selector == 2){
						for(i=0; i < 32; i++)
							z->BSOL[n + selection_a + (val_block << 5) + i] = 0x10;
					}
					else if(edit_selector == 3){
						for(i=0; i < 32; i++)
							z->BSOL[n + selection_a + (val_block << 5) + i + 0x8000] = 0x10;
					}
					waitCounter = 12;
				}
				else if(key[KEY_DEL]){
					n = z->BSOL_AddressTable[z->Act[act].Stage[stage].BlockSolidity];
					if(edit_selector == 2){
						for(i=0; i < 32; i++)
							z->BSOL[n + selection_a + (val_block << 5) + i] = 0;
					}
					else if(edit_selector == 3){
						for(i=0; i < 32; i++)
							z->BSOL[n + selection_a + (val_block << 5) + i + 0x8000] = 0;
					}
					waitCounter = 12;
				}
				//break;
		}
				
		if(key[KEY_D] && (key[KEY_LCONTROL] || key[KEY_RCONTROL])){
			SaveZone(z, "dump.pzf");
			allegro_message(STR_MSG_PZF_DUMPED);
		}
		if(key[KEY_BACKSLASH]){
			p->layer = ((p->layer + 1) & 1) + 0x10;
			waitCounter = 12;
		}
	}
}



void LoadZonePrompt(){
	InputText((screen_resolution_x >> 1)-156, (screen_resolution_y >> 1)-24, 0, STR_MSG_OPEN_FILE);
	
	for(i=0; i < 256; i++){
		if(TextBuffer[i] >= 'A' && TextBuffer[i] <= 'Z')
			TextBuffer[i] += 0x20;
		else if(TextBuffer[i] == '\0')
			i = 255;
	}
	for(i=0; i <= 256; i++){
		if(i == 256){
			strcpy(zone_file_list[i], TextBuffer);
			unlisted_zone = 1;
		}
		if(strcmp(zone_file_list[i], TextBuffer) == 0){
			zone = (i & 0xFF);
			i = 256;
			
			InputText((screen_resolution_x >> 1)-156, (screen_resolution_y >> 1), 0, "ENTER ACT VALUE 1 TO 8:");
			act = TextBuffer[0] - '1';
			if(act >= z.Act_FileCount)
				act = 0;
			InputText((screen_resolution_x >> 1)-156, (screen_resolution_y >> 1)+24, 0, "ENTER STAGE VALUE A TO D:");
			if(TextBuffer[0] >= 'a')
				TextBuffer[0] -= 0x20;
			stage = TextBuffer[0] - 'A';
			if(((z.Act[act].IncludedStages >> stage) & 1) == 0)
				stage = 0;
			
			Level_Inactive_flag = 1;
		}
	}
}
