/*
 *						'Mags.rex' 		for FM-TOWNS
 *
 *				- MAKIchan Graphic loader is not 鮪だ！ -
 *
 *					Version 1.03	Update 1991/05/12
 *
 *							programmed by MALOR
 */

/*
 *			1991/05/07	v1.00	正常にセーブされたぞ
 *					10	v1.02	スタックにヒープを取るようにして、
 *								実行ファイル512Ｋの地獄を脱した(^_^;)
 *					12	v1.03	部分セーブのバグ修正
 *  今後の課題
 * 		アセンブラ化で高速化
 */

#define DEBUG

#include <egb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pixel.h"

#define VERSION	"1.03"
#define UPDATE	"1991/05/12 01:52"

#define tolower(x) ((x)<'Z')&&((x)>'A')?((x)-'A'+'a'):(x)

#define FNAME16 0x0006118c
#define FNAME25 0x000610fc
#define FNAME32 0x000614dc

#define MemorySize 512*1024		/* Buffer is 512Kbyte */

#ifndef NULL
#define NULL	0
#endif

#define FALSE	0
#define TRUE	1
#define EOC		0x1a		/* End Of Comment */
#define CR		0x0d
#define LF		0x0a
#define BufSize	256

#define PLANE20	0x001c
#define PLANE21	0x0104
#define PLANE10	0x010c

#define PALNO	0xfd90
#define PALB	0xfd92
#define PALR	0xfd94
#define PALG	0xfd96

#define LINE200	0x01			/* 200ラインフラグ */
#define COL8	0x02			/* 8色フラグ */
#define DIGITAL	0x04			/* デジタルフラグ */
#define COL256	0x80			/* 256色フラグ */

#define TOWNS	0x00			/* TOWNS機種コード(今のところなし) */

typedef struct {
	char	header;			/* ヘッダの先頭 */
	char	machine;		/* 機種コード */
	char	rflg;			/* 機種依存フラグ */
	char	screen;			/* スクリーンモード */
	short	lx;				/* 表示開始位置Ｘ */
	short	ly;				/* 表示開始位置Ｙ */
	short	rx;				/* 表示終了位置Ｘ */
	short	ry;				/* 表示終了位置Ｙ */
	int		offa;			/* フラグＡのオフセット */
	int		offb;			/* フラグＢのオフセット */
	int		sizb;			/* フラグＢのサイズ */
	int		offp;			/* ピクセルのオフセット */
	int		sizp;			/* ピクセルのサイズ */
	} MAGHEADER;

/* Prototype declaration */

int		mag_make_head(FILE *fp);
int		mag_encode(int mode,int lx,int ly,int rx,int ry);
int		memory_allocate(int size);
int		checkpix(int x,int y,int flag,int src_pix);
int		checkpix2(int x,int y,int flag,int src_pix);

/* Global Vari. */

char		mag_id[]="MAKI02  ";
char		machine[]="TOWN ";
char		usr[]=">謎<              ";
char		comment[]=" TOWNSまぐせーばー Ver1.03(REX版)";

int			dx[]={0,-1,-2,-4, 0,-1, 0,-1,-2, 0,-1,-2, 0,-1,-2,  0};
int			dy[]={0, 0, 0, 0,-1,-1,-2,-2,-2,-4,-4,-4,-8,-8,-8,-16};

char		swap[]={
				0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,
				0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,
				0x01,0x11,0x21,0x31,0x41,0x51,0x61,0x71,
				0x81,0x91,0xa1,0xb1,0xc1,0xd1,0xe1,0xf1,
				0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72,
				0x82,0x92,0xa2,0xb2,0xc2,0xd2,0xe2,0xf2,
				0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x73,
				0x83,0x93,0xa3,0xb3,0xc3,0xd3,0xe3,0xf3,
				0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x74,
				0x84,0x94,0xa4,0xb4,0xc4,0xd4,0xe4,0xf4,
				0x05,0x15,0x25,0x35,0x45,0x55,0x65,0x75,
				0x85,0x95,0xa5,0xb5,0xc5,0xd5,0xe5,0xf5,
				0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x76,
				0x86,0x96,0xa6,0xb6,0xc6,0xd6,0xe6,0xf6,
				0x07,0x17,0x27,0x37,0x47,0x57,0x67,0x77,
				0x87,0x97,0xa7,0xb7,0xc7,0xd7,0xe7,0xf7,
				0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78,
				0x88,0x98,0xa8,0xb8,0xc8,0xd8,0xe8,0xf8,
				0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x79,
				0x89,0x99,0xa9,0xb9,0xc9,0xd9,0xe9,0xf9,
				0x0a,0x1a,0x2a,0x3a,0x4a,0x5a,0x6a,0x7a,
				0x8a,0x9a,0xaa,0xba,0xca,0xda,0xea,0xfa,
				0x0b,0x1b,0x2b,0x3b,0x4b,0x5b,0x6b,0x7b,
				0x8b,0x9b,0xab,0xbb,0xcb,0xdb,0xeb,0xfb,
				0x0c,0x1c,0x2c,0x3c,0x4c,0x5c,0x6c,0x7c,
				0x8c,0x9c,0xac,0xbc,0xcc,0xdc,0xec,0xfc,
				0x0d,0x1d,0x2d,0x3d,0x4d,0x5d,0x6d,0x7d,
				0x8d,0x9d,0xad,0xbd,0xcd,0xdd,0xed,0xfd,
				0x0e,0x1e,0x2e,0x3e,0x4e,0x5e,0x6e,0x7e,
				0x8e,0x9e,0xae,0xbe,0xce,0xde,0xee,0xfe,
				0x0f,0x1f,0x2f,0x3f,0x4f,0x5f,0x6f,0x7f,
				0x8f,0x9f,0xaf,0xbf,0xcf,0xdf,0xef,0xff};

extern char	mem[];						/* Heap Buffer */
char		*egb;						/* EGBworkへのポインタ(Global版) */

MAGHEADER	maghead;					/* MAGのヘッダ */
int			siza;						/* MAGのflag aのサイズ */
int			headtop;					/* MAGのヘッダのオフセット */
char		pal[768];					/* 現在のパレット情報 */
char		*flga,*flgb,*flg,*pix;		/* flag&pixelへのポインタ */
char		*flga_base,*flgb_base,*flg_base,*pix_base;
										/* flag&pixel格納先頭アドレス */
int			xpixel;						/* 横方向のピクセル数の半分 */
int			right_pix,left_pix;			/* 左右のピクセル番号 */

/* Main program */

void	save(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey)
{
	char *s,*d,*p,fname[BufSize];
	FILE *fp;
	int dx,dy,i;

	dx=0; dy=0;
	egb = egbwork;

	if (mode==16) return;

	if (mag_encode(((mode==4)?0:COL256),sx,sy,ex,ey)==FALSE)
		return;

	if (mode == 4) 
		p = (char *)FNAME16;
	else if (mode == 8)
		p = (char *)FNAME25;
	else
		return;

	for(d=fname,s=p,i=0;i<8;i++)
		*d++ = ((*s!='\0')&&(*s!='.'))?(*s++):' ';

	for(s=".mag";*s!='\0';*d++ = *s++);
	*d = '\0';

#ifdef DEBUG
	printf("file open\n");
#endif

	if ((fp=fopen(fname,"wb"))==NULL)
		return;

#ifdef DEBUG
	printf("buffer flush !\n");
#endif

	mag_make_head(fp);

	fclose(fp);

}

int		mag_make_head(FILE *fp)
{
	char *p;
	int i,r,g,b;

	/* Header Set */
	maghead.header = 0;
	maghead.machine = TOWNS;
	maghead.rflg = 0;

	/* MAG識別子 & 機種コード & ユーザー & コメント 書き出し */
	fwrite(mag_id,1,8,fp);
	fwrite(machine,1,5,fp);
	fwrite(usr,1,18,fp);
	fwrite(comment,1,33,fp);
	fputc(EOC,fp);

	/* ヘッダー書き出し */
	fwrite((char *)&maghead,1,sizeof(MAGHEADER),fp);

	/* カラーパレットセット */
	if(maghead.screen&COL256)
		for(p=pal,i=0;i<256;i++) {
			outpb(PALNO,i);
			*p++ = inpb(PALG);
			*p++ = inpb(PALR);
			*p++ = inpb(PALB);
			}
	else
		for(p=pal,i=0;i<16;i++) {
			outpb(PALNO,i);
			g = inpb(PALG);
			r = inpb(PALR);
			b = inpb(PALB);
			*p++ = (g)?(g|0xf):0;
			*p++ = (r)?(r|0xf):0;
			*p++ = (b)?(b|0xf):0;
			}

	fwrite(pal,1,(maghead.screen&COL256)?768:48,fp);

	fwrite(flga_base,1,siza,fp);
	if (siza%2==1) fwrite("\0",1,1,fp);
	fwrite(flgb_base,1,maghead.sizb,fp);
	if ((maghead.sizb%2)==1) fwrite("\0",1,1,fp);
	fwrite(pix_base,1,maghead.sizp,fp);

	return TRUE;

}

int		mag_encode(int mode,int lx,int ly,int rx,int ry)
{
	int i,x,y,eah,eal;
	char	check_bit,flag,bflg;

	/* Header Set */
	maghead.rx = rx;
	maghead.ry = ry;
	maghead.lx = lx;
	maghead.ly = ly;
	maghead.screen = (mode&COL256)?COL256:0;

	left_pix  = (mode&COL256)?(lx/4)*2:(lx/8)*2;
	right_pix = (mode&COL256)?(rx/4)*2:(rx/8)*2;
	xpixel = right_pix/2 - left_pix/2 + 1;
	siza = (xpixel*(ry-ly+1)+7) / 8;

	if ((flga_base=flga=(char *)memory_allocate(siza))==NULL)
		return FALSE;
	
	if ((flg_base=flg=(char *)memory_allocate(siza*8))==NULL)
		return FALSE;

	if ((pix_base=pix=(char *)memory_allocate(1))==NULL)
		return FALSE;
							/* ピクセルバッファ先頭アドレス取得 */

	Lineofs = (unsigned int)1024*((maghead.screen&COL256)?2:1);
	Mofs[0]  = -(int)(( 0+ 0*Lineofs)/2);
	Mofs[1]  = -(int)(( 4+ 0*Lineofs)/2);
	Mofs[2]  = -(int)(( 8+ 0*Lineofs)/2);
	Mofs[3]  = -(int)((16+ 0*Lineofs)/2);
	Mofs[4]  = -(int)(( 0+ 1*Lineofs)/2);
	Mofs[5]  = -(int)(( 4+ 1*Lineofs)/2);
	Mofs[6]  = -(int)(( 0+ 2*Lineofs)/2);
	Mofs[7]  = -(int)(( 4+ 2*Lineofs)/2);
	Mofs[8]  = -(int)(( 8+ 2*Lineofs)/2);
	Mofs[9]  = -(int)(( 0+ 4*Lineofs)/2);
	Mofs[10] = -(int)(( 4+ 4*Lineofs)/2);
	Mofs[11] = -(int)(( 8+ 4*Lineofs)/2);
	Mofs[12] = -(int)(( 0+ 8*Lineofs)/2);
	Mofs[13] = -(int)(( 4+ 8*Lineofs)/2);
	Mofs[14] = -(int)(( 8+ 8*Lineofs)/2);
	Mofs[15] = -(int)(( 0+16*Lineofs)/2);
	Lineofs /= 2;								/* 前方参照オフセット */

/* Pixel Encode */

#ifdef DEBUG
	printf("pixel encode\n");
#endif

	if (!(mode&COL256)) {						/* 16色モード */
			y=0;
			for(x=0;x<xpixel;x++) {
				/* Left Pixel Encode */
				eal=getpix(PLANE20,x*4+left_pix*2+(y+ly)*Lineofs);
				eah=getpix(PLANE20,x*4+left_pix*2+2+(y+ly)*Lineofs);
				if (checkpix(x*2+left_pix,y+ly, 1,eal)!=FALSE)
					flag= 1;
				else if (checkpix(x*2+left_pix,y+ly, 4,eal)!=FALSE)
					flag= 4;
				else if (checkpix(x*2+left_pix,y+ly, 5,eal)!=FALSE)
					flag= 5;
				else if (checkpix(x*2+left_pix,y+ly, 6,eal)!=FALSE)
					flag= 6;
				else if (checkpix(x*2+left_pix,y+ly, 7,eal)!=FALSE)
					flag= 7;
				else if (checkpix(x*2+left_pix,y+ly, 9,eal)!=FALSE)
					flag= 9;
				else if (checkpix(x*2+left_pix,y+ly,10,eal)!=FALSE)
					flag=10;
				else if (checkpix(x*2+left_pix,y+ly, 2,eal)!=FALSE)
					flag= 2;
				else if (checkpix(x*2+left_pix,y+ly, 8,eal)!=FALSE)
					flag= 8;
				else if (checkpix(x*2+left_pix,y+ly,11,eal)!=FALSE)
					flag=11;
				else if (checkpix(x*2+left_pix,y+ly,12,eal)!=FALSE)
					flag=12;
				else if (checkpix(x*2+left_pix,y+ly,13,eal)!=FALSE)
					flag=13;
				else if (checkpix(x*2+left_pix,y+ly,14,eal)!=FALSE)
					flag=14;
				else if (checkpix(x*2+left_pix,y+ly, 3,eal)!=FALSE)
					flag= 3;
				else if (checkpix(x*2+left_pix,y+ly,15,eal)!=FALSE)
					flag=15;
				else {
					flag= 0;
					*pix++ = swap[eal&0xff];
					*pix++ = swap[eal>>8];
				}
				flag = flag << 4;
				/* Right Pixel Encode */
				if (checkpix(x*2+left_pix+1,y+ly, 1,eah)!=FALSE)
					flag|= 1;
				else if (checkpix(x*2+left_pix+1,y+ly, 4,eah)!=FALSE)
					flag|= 4;
				else if (checkpix(x*2+left_pix+1,y+ly, 5,eah)!=FALSE)
					flag|= 5;
				else if (checkpix(x*2+left_pix+1,y+ly, 6,eah)!=FALSE)
					flag|= 6;
				else if (checkpix(x*2+left_pix+1,y+ly, 7,eah)!=FALSE)
					flag|= 7;
				else if (checkpix(x*2+left_pix+1,y+ly, 9,eah)!=FALSE)
					flag|= 9;
				else if (checkpix(x*2+left_pix+1,y+ly,10,eah)!=FALSE)
					flag|=10;
				else if (checkpix(x*2+left_pix+1,y+ly, 2,eah)!=FALSE)
					flag|= 2;
				else if (checkpix(x*2+left_pix+1,y+ly, 8,eah)!=FALSE)
					flag|= 8;
				else if (checkpix(x*2+left_pix+1,y+ly,11,eah)!=FALSE)
					flag|=11;
				else if (checkpix(x*2+left_pix+1,y+ly,12,eah)!=FALSE)
					flag|=12;
				else if (checkpix(x*2+left_pix+1,y+ly,13,eah)!=FALSE)
					flag|=13;
				else if (checkpix(x*2+left_pix+1,y+ly,14,eah)!=FALSE)
					flag|=14;
				else if (checkpix(x*2+left_pix+1,y+ly, 3,eah)!=FALSE)
					flag|= 3;
				else if (checkpix(x*2+left_pix+1,y+ly,15,eah)!=FALSE)
					flag|=15;
				else {
					flag|= 0;
					*pix++ = swap[eah&0xff];
					*pix++ = swap[eah>>8];
				}
				*flg++ = flag;
			}

		for(y=1;y<ry-ly+1;y++) {
			for(x=0;x<xpixel;x++) {
				eal=getpix(PLANE20,x*4+left_pix*2+(y+ly)*Lineofs);
				eah=getpix(PLANE20,x*4+left_pix*2+2+(y+ly)*Lineofs);
				bflg = ((char)*(flg-xpixel));
				/* Left Pixel Encode */
				if (((bflg>>4)!=0)&&(checkpix(x*2+left_pix,y+ly,bflg>>4,eal)!=FALSE))
					flag= bflg>>4;
				else if (checkpix(x*2+left_pix,y+ly, 1,eal)!=FALSE)
					flag= 1;
				else if (checkpix(x*2+left_pix,y+ly, 4,eal)!=FALSE)
					flag= 4;
				else if (checkpix(x*2+left_pix,y+ly, 5,eal)!=FALSE)
					flag= 5;
				else if (checkpix(x*2+left_pix,y+ly, 6,eal)!=FALSE)
					flag= 6;
				else if (checkpix(x*2+left_pix,y+ly, 7,eal)!=FALSE)
					flag= 7;
				else if (checkpix(x*2+left_pix,y+ly, 9,eal)!=FALSE)
					flag= 9;
				else if (checkpix(x*2+left_pix,y+ly,10,eal)!=FALSE)
					flag=10;
				else if (checkpix(x*2+left_pix,y+ly, 2,eal)!=FALSE)
					flag= 2;
				else if (checkpix(x*2+left_pix,y+ly, 8,eal)!=FALSE)
					flag= 8;
				else if (checkpix(x*2+left_pix,y+ly,11,eal)!=FALSE)
					flag=11;
				else if (checkpix(x*2+left_pix,y+ly,12,eal)!=FALSE)
					flag=12;
				else if (checkpix(x*2+left_pix,y+ly,13,eal)!=FALSE)
					flag=13;
				else if (checkpix(x*2+left_pix,y+ly,14,eal)!=FALSE)
					flag=14;
				else if (checkpix(x*2+left_pix,y+ly, 3,eal)!=FALSE)
					flag= 3;
				else if (checkpix(x*2+left_pix,y+ly,15,eal)!=FALSE)
					flag=15;
				else {
					flag= 0;
					*pix++ = swap[eal&0xff];
					*pix++ = swap[eal>>8];
				}
				flag = flag << 4;
				/* Right Pixel Encode */
				if (((bflg&0xf)!=0)&&(checkpix(x*2+left_pix+1,y+ly,bflg&0xf,eah)!=FALSE))
					flag|=bflg&0xf;
				else if (checkpix(x*2+left_pix+1,y+ly, 1,eah)!=FALSE)
					flag|= 1;
				else if (checkpix(x*2+left_pix+1,y+ly, 4,eah)!=FALSE)
					flag|= 4;
				else if (checkpix(x*2+left_pix+1,y+ly, 5,eah)!=FALSE)
					flag|= 5;
				else if (checkpix(x*2+left_pix+1,y+ly, 6,eah)!=FALSE)
					flag|= 6;
				else if (checkpix(x*2+left_pix+1,y+ly, 7,eah)!=FALSE)
					flag|= 7;
				else if (checkpix(x*2+left_pix+1,y+ly, 9,eah)!=FALSE)
					flag|= 9;
				else if (checkpix(x*2+left_pix+1,y+ly,10,eah)!=FALSE)
					flag|=10;
				else if (checkpix(x*2+left_pix+1,y+ly, 2,eah)!=FALSE)
					flag|= 2;
				else if (checkpix(x*2+left_pix+1,y+ly, 8,eah)!=FALSE)
					flag|= 8;
				else if (checkpix(x*2+left_pix+1,y+ly,11,eah)!=FALSE)
					flag|=11;
				else if (checkpix(x*2+left_pix+1,y+ly,12,eah)!=FALSE)
					flag|=12;
				else if (checkpix(x*2+left_pix+1,y+ly,13,eah)!=FALSE)
					flag|=13;
				else if (checkpix(x*2+left_pix+1,y+ly,14,eah)!=FALSE)
					flag|=14;
				else if (checkpix(x*2+left_pix+1,y+ly, 3,eah)!=FALSE)
					flag|= 3;
				else if (checkpix(x*2+left_pix+1,y+ly,15,eah)!=FALSE)
					flag|=15;
				else {
					flag|=0;
					*pix++ = swap[eah&0xff];
					*pix++ = swap[eah>>8];
				}
				*flg++ = (char)flag;
			}
		}
	} else {										/* 256色モード */
			y=0;
			for(x=0;x<xpixel;x++) {
				/* Left Pixel Encode */
				eal=getpix(PLANE10,x*4+left_pix*2+(y+ly)*Lineofs);
				eah=getpix(PLANE10,x*4+left_pix*2+2+(y+ly)*Lineofs);
				if (checkpix2(x*2+left_pix,y+ly, 1,eal)!=FALSE)
					flag= 1;
				else if (checkpix2(x*2+left_pix,y+ly, 4,eal)!=FALSE)
					flag= 4;
				else if (checkpix2(x*2+left_pix,y+ly, 5,eal)!=FALSE)
					flag= 5;
				else if (checkpix2(x*2+left_pix,y+ly, 6,eal)!=FALSE)
					flag= 6;
				else if (checkpix2(x*2+left_pix,y+ly, 7,eal)!=FALSE)
					flag= 7;
				else if (checkpix2(x*2+left_pix,y+ly, 9,eal)!=FALSE)
					flag= 9;
				else if (checkpix2(x*2+left_pix,y+ly,10,eal)!=FALSE)
					flag=10;
				else if (checkpix2(x*2+left_pix,y+ly, 2,eal)!=FALSE)
					flag= 2;
				else if (checkpix2(x*2+left_pix,y+ly, 8,eal)!=FALSE)
					flag= 8;
				else if (checkpix2(x*2+left_pix,y+ly,11,eal)!=FALSE)
					flag=11;
				else if (checkpix2(x*2+left_pix,y+ly,12,eal)!=FALSE)
					flag=12;
				else if (checkpix2(x*2+left_pix,y+ly,13,eal)!=FALSE)
					flag=13;
				else if (checkpix2(x*2+left_pix,y+ly,14,eal)!=FALSE)
					flag=14;
				else if (checkpix2(x*2+left_pix,y+ly, 3,eal)!=FALSE)
					flag= 3;
				else if (checkpix2(x*2+left_pix,y+ly,15,eal)!=FALSE)
					flag=15;
				else {
					flag= 0;
					*pix++ = eal&0xff;
					*pix++ = eal>>8;
				}
				flag = flag << 4;
				/* Right Pixel Encode */
				if (checkpix2(x*2+left_pix+1,y+ly, 1,eah)!=FALSE)
					flag|= 1;
				else if (checkpix2(x*2+left_pix+1,y+ly, 4,eah)!=FALSE)
					flag|= 4;
				else if (checkpix2(x*2+left_pix+1,y+ly, 5,eah)!=FALSE)
					flag|= 5;
				else if (checkpix2(x*2+left_pix+1,y+ly, 6,eah)!=FALSE)
					flag|= 6;
				else if (checkpix2(x*2+left_pix+1,y+ly, 7,eah)!=FALSE)
					flag|= 7;
				else if (checkpix2(x*2+left_pix+1,y+ly, 9,eah)!=FALSE)
					flag|= 9;
				else if (checkpix2(x*2+left_pix+1,y+ly,10,eah)!=FALSE)
					flag|=10;
				else if (checkpix2(x*2+left_pix+1,y+ly, 2,eah)!=FALSE)
					flag|= 2;
				else if (checkpix2(x*2+left_pix+1,y+ly, 8,eah)!=FALSE)
					flag|= 8;
				else if (checkpix2(x*2+left_pix+1,y+ly,11,eah)!=FALSE)
					flag|=11;
				else if (checkpix2(x*2+left_pix+1,y+ly,12,eah)!=FALSE)
					flag|=12;
				else if (checkpix2(x*2+left_pix+1,y+ly,13,eah)!=FALSE)
					flag|=13;
				else if (checkpix2(x*2+left_pix+1,y+ly,14,eah)!=FALSE)
					flag|=14;
				else if (checkpix2(x*2+left_pix+1,y+ly, 3,eah)!=FALSE)
					flag|= 3;
				else if (checkpix2(x*2+left_pix+1,y+ly,15,eah)!=FALSE)
					flag|=15;
				else {
					flag|= 0;
					*pix++ = eah&0xff;
					*pix++ = eah>>8;
				}
				*flg++ = flag;
			}

		for(y=1;y<ry-ly+1;y++) {
			for(x=0;x<xpixel;x++) {
				eal=getpix(PLANE10,x*4+left_pix*2+(y+ly)*Lineofs);
				eah=getpix(PLANE10,x*4+left_pix*2+2+(y+ly)*Lineofs);
				bflg = ((char)*(flg-xpixel));
				/* Left Pixel Encode */
				if (((bflg>>4)!=0)&&(checkpix2(x*2+left_pix,y+ly,bflg>>4,eal)!=FALSE))
					flag= bflg>>4;
				else if (checkpix2(x*2+left_pix,y+ly, 1,eal)!=FALSE)
					flag= 1;
				else if (checkpix2(x*2+left_pix,y+ly, 4,eal)!=FALSE)
					flag= 4;
				else if (checkpix2(x*2+left_pix,y+ly, 5,eal)!=FALSE)
					flag= 5;
				else if (checkpix2(x*2+left_pix,y+ly, 6,eal)!=FALSE)
					flag= 6;
				else if (checkpix2(x*2+left_pix,y+ly, 7,eal)!=FALSE)
					flag= 7;
				else if (checkpix2(x*2+left_pix,y+ly, 9,eal)!=FALSE)
					flag= 9;
				else if (checkpix2(x*2+left_pix,y+ly,10,eal)!=FALSE)
					flag=10;
				else if (checkpix2(x*2+left_pix,y+ly, 2,eal)!=FALSE)
					flag= 2;
				else if (checkpix2(x*2+left_pix,y+ly, 8,eal)!=FALSE)
					flag= 8;
				else if (checkpix2(x*2+left_pix,y+ly,11,eal)!=FALSE)
					flag=11;
				else if (checkpix2(x*2+left_pix,y+ly,12,eal)!=FALSE)
					flag=12;
				else if (checkpix2(x*2+left_pix,y+ly,13,eal)!=FALSE)
					flag=13;
				else if (checkpix2(x*2+left_pix,y+ly,14,eal)!=FALSE)
					flag=14;
				else if (checkpix2(x*2+left_pix,y+ly, 3,eal)!=FALSE)
					flag= 3;
				else if (checkpix2(x*2+left_pix,y+ly,15,eal)!=FALSE)
					flag=15;
				else {
					flag= 0;
					*pix++ = eal&0xff;
					*pix++ = eal>>8;
				}
				flag = flag << 4;
				/* Right Pixel Encode */
				if (((bflg&0xf)!=0)&&(checkpix2(x*2+left_pix+1,y+ly,bflg&0xf,eah)!=FALSE))
					flag|=bflg&0xf;
				else if (checkpix2(x*2+left_pix+1,y+ly, 1,eah)!=FALSE)
					flag|= 1;
				else if (checkpix2(x*2+left_pix+1,y+ly, 4,eah)!=FALSE)
					flag|= 4;
				else if (checkpix2(x*2+left_pix+1,y+ly, 5,eah)!=FALSE)
					flag|= 5;
				else if (checkpix2(x*2+left_pix+1,y+ly, 6,eah)!=FALSE)
					flag|= 6;
				else if (checkpix2(x*2+left_pix+1,y+ly, 7,eah)!=FALSE)
					flag|= 7;
				else if (checkpix2(x*2+left_pix+1,y+ly, 9,eah)!=FALSE)
					flag|= 9;
				else if (checkpix2(x*2+left_pix+1,y+ly,10,eah)!=FALSE)
					flag|=10;
				else if (checkpix2(x*2+left_pix+1,y+ly, 2,eah)!=FALSE)
					flag|= 2;
				else if (checkpix2(x*2+left_pix+1,y+ly, 8,eah)!=FALSE)
					flag|= 8;
				else if (checkpix2(x*2+left_pix+1,y+ly,11,eah)!=FALSE)
					flag|=11;
				else if (checkpix2(x*2+left_pix+1,y+ly,12,eah)!=FALSE)
					flag|=12;
				else if (checkpix2(x*2+left_pix+1,y+ly,13,eah)!=FALSE)
					flag|=13;
				else if (checkpix2(x*2+left_pix+1,y+ly,14,eah)!=FALSE)
					flag|=14;
				else if (checkpix2(x*2+left_pix+1,y+ly, 3,eah)!=FALSE)
					flag|= 3;
				else if (checkpix2(x*2+left_pix+1,y+ly,15,eah)!=FALSE)
					flag|=15;
				else {
					flag|=0;
					*pix++ = eah&0xff;
					*pix++ = eah>>8;
				}
				*flg++ = (char)flag;
			}
		}
	}

	memory_allocate((int)(pix-pix_base)-1);		/* 帳尻あわせ */
	flg--;

	if((flgb_base=flgb=(char *)memory_allocate(1))==NULL)
		return FALSE;

#ifdef DEBUG
	printf(" pix_base = 0x%x :  pix_bottom = 0x%x\n",pix_base,pix-1);
	printf("flgb_base = 0x%x : \n",flgb_base);
#endif

	/* 1 Line Xor */

#ifdef DEBUG
	printf("flag 1 line xor\n");
#endif

	for (i=xpixel;i<xpixel*(ry-ly+1);i++,flg--)
		*flg ^= *(flg-xpixel);

	/* Flag Encode */

#ifdef DEBUG
	printf("flag encode main\n");
#endif

	check_bit = 0x80;
	flg = flg_base;
	flga = flga_base;
	flgb = flgb_base;
	*flga = 0;
	for (i=0;i<xpixel*(ry-ly+1);i++) {
		if ((flag=*flg++)!=0) {
			*flga |= check_bit;
			*flgb++ = flag;
		}
		check_bit = check_bit >> 1;
		if (check_bit==0) {
			check_bit = 0x80;
			flga++;
			*flga = 0;
		}
	}

#ifdef DEBUG
	printf("flag encode finish !\n");
#endif

	/* Header Set */

	maghead.sizp = (int)(pix-pix_base);
	maghead.sizb = (int)(flgb-flgb_base);
	maghead.offa = (sizeof(MAGHEADER)) + ((mode&COL256)?768:48);
	maghead.offb = maghead.offa + siza + siza%2;
	maghead.offp = maghead.offb + maghead.sizb + maghead.sizb%2;

#ifdef DEBUG
	printf( "+------+OFFSET-+--SIZE-+\n"
			"|flag a| %5d | %5d |\n"
			"|flag b| %5d | %5d |\n"
			"|pixel | %5d | %5d |\n"
			"+------+-------+-------+\n"
			,maghead.offa,siza,maghead.offb
			,maghead.sizb,maghead.offp,maghead.sizp);
#endif

	return TRUE;

}

int		memory_allocate(int size)
{
	static char *bottom = mem;
	static int total_size = 0;

	if (total_size+size>=MemorySize)
		return 0;
	else {
		bottom += size;
		total_size += size;
		return (int)bottom-size;
	}
}

int		checkpix(int x,int y,int flag,int src_pix)
{
	int ofs,dest_pix;


	if (x+dx[flag]<left_pix) {
		return FALSE;
	}
	if (y+dy[flag]<maghead.ly) {
		return FALSE;
	}

	ofs = (dy[flag]+y)*Lineofs + (dx[flag]+x)*2;
	dest_pix = getpix(PLANE20,ofs);

	return (src_pix==dest_pix);

}

int		checkpix2(int x,int y,int flag,int src_pix)
{
	int ofs,dest_pix;


	if (x+dx[flag]<left_pix) {
		return FALSE;
	}
	if (y+dy[flag]<maghead.ly) {
		return FALSE;
	}

	ofs = (dy[flag]+y)*Lineofs + (dx[flag]+x)*2;
	dest_pix = getpix(PLANE10,ofs);

	return (src_pix==dest_pix);

}
