#include <io.h>
#include <dos.h>
#include <bios.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <ctype.h>
#include <i86.h>
#include <time.h>
#include <process.h>
#include "view32.h"
#include "font.h"
#include "mouse.h"



extern "C" char mousepoint[5][64];

void inkey(char &key1,char &key2);

class icon
{
   char s[64];
   public:
   icon(){};
   ~icon(){};
   void show(char *s1){showicon(s1,s);};
   void show2(char *s1){showiconm(s1,s);};
   void show(int x,int y);
   void show2(int x,int y);
   char *the_ptr(){return s;};
   char the_ptrs(int i){return s[i];};
   char check();
};

class icon45
{
   char s[256];
   public:
   icon45(){};
   ~icon45(){};
   void show(char *s1){showicon45(s1,s);};
   void showl(char *s1){showicon45l(s1,s);};
   void showr(char *s1){showicon45r(s1,s);};
   void showt(char *s1){showicon45t(s1,s);};
   void showd(char *s1){showicon45d(s1,s);};
   char *the_ptr(){return s;};
   char the_ptrs(int i){return s[i];};
};


class image
{
   protected:
   short int width,high;
   short unsigned size;
   char *ptr;
   
   public:
   image();
   image(char *filename,char code=0){set(filename,code);};
   image(int w1,int h1);
   image(int x,int y,int w,int h);
   ~image();
   void set(char *filename,char code=0);
   void set(int x,int y,int w,int h);
   void save(char *filename);
   void clear();
   void show(int x,int y);
   void showm(int x,int y);
   void cutshow(int x,int y,int x2,int y2,int w,int h)
   {
      show_pict_mask(x,y,width,h,ptr,x2,y2,w);
   };
   
   int the_width(){return width;};
   int the_high(){return high;};
   char *the_ptr(){return ptr;};
};

class menu
{
   protected:
   int x,y,xitem,yitem;
   int xlen,ylen,itemlen;
   char *title;
   public:
   menu(){title=NULL;};
   virtual ~menu(){};
   void set(int x1,int y1,int xitem1,int yitem1,
            int xlen1,int ylen1,int itemlen1);
   void settitle(char *ptr){title=ptr;};
   int select(int can_esc=1,int can_show=1,int need_show=1);
};


struct temp_block
{
   int width,high;
   short *tb;
   public:
   temp_block(){width=high=0;tb=NULL;};
   ~temp_block(){clear();};
   void set(int w,int h);
   void clear();
   void copy(temp_block &b2);
   void show(int x,int y);
};

class map
{
   int width,high;
   int size;
   int show_x,show_y;
   short *floor,*over,*scroll;
   
   
   public:
   char is_scroll;
   
   map();
   map(int w,int h);
   ~map();
   void home(){show_x=show_y=0;};
   void clear();
   void clear_floor();
   void show();
   void show2(int x1,int y1,int x2,int y2);
   void making();
   void cut_block(int px,int py);
   int cut_block_mouse(int px,int py);
   int clear_block_mouse(int px,int py);
   void save(char *filename);
   void save_scroll(char *filename);
   void load(char *filename);
   void load_scroll(char *filename);
   int function();
   void draw1(int px,int py);
   void draw2(int px,int py);
   void undo();
   void tran(int w2,int h2,int sx,int sy);
   void showman(int sp,int sel);
   int catman();
   int selman();
   int seldoor();
   int setrange(int px,int py);
   int make_door(int px,int py);
   int set_neg(int px,int py);
   void optimize();
   int the_width(){return width;};
   int the_high(){return high;};
   void change_point();
};

struct man
{
   char body[8][576];
   
   void show(int x,int y,int d=0)
   {
      show_image_mask(x,y,24,24,body[d]);
   };
   
};

struct manxy
{
   short x,y;
   short unsigned z;
   short id,dir,go;
   short talk_id;
   short startx,starty,width,high;
   char canmove;
   
   void set(int x2,int y2,int id2,int dir2,int talk_id2,
   int x3,int y3,int w2,int h2);
   void set(int x2,int y2){x=x2;y=y2;};
   void set(int id2){id=id2;};
   void showdata();
   void print();
   void save(int fno);
   void load(int fno);
};

struct entry_point
{
   short int x1,y1,x2,y2,new_x,new_y;
   char next_file[20];
   short int script_no;
   
   void set(int x1_2,int y1_2,int x2_2,int y2_2,
   int new_x_2,int new_y_2,char *next_file_2,int script_no_2);
   
   void set(int x1_2,int y1_2,int x2_2,int y2_2);
   int check(int x,int y);
   void showdata();
   
   void save(int fno);
   void load(int fno);
};

/////////////////////////////////////////////////////////////////////////

temp_block main_block,undo_block;
int undo_x,undo_y,undo_sx,undo_sy,undo_editmode;
map *mainmap,*tempmap;
signed char mapid=1,catid=1,editmode=1;
//char vscreen[64000];
icon *picon;
//icon45 ficon[256];
icon spoint;
icon door_point[4];
int  picon_count;
char spshow_on=0;
int isneg=1;
int manshow_sel;
short *opti_temp;
char optimize_on=0;
short int manshow_count=0,manmove_count=0;
manxy use_manxy[21];

man *useman;
int man_count,man_id;

entry_point use_entry[41];
short int entry_count=0;
int entry_sel;

char pub_filename[20]="";
char pub_manfile[20]="";
char pub_entryfile[20]="";


void check_mouse(int &button,int &x,int &y);
void change_block();
void waitkey();
void black_box(int x,int y,int w,int h,int t1);
char lineedit(char *line);
char load_file(char *filename2,char *wide);
void save_man(char *filename);
void load_man(char *filename);
char load_man2(char *filename2);

////////////////////////////////////////////////////////////////////

void manxy::showdata()
{
   char s[160];
   
   hide_mouse();
   
   black_box(0,0,320,200,1);
   
   sprintf(s,"序號 :  %3d",manshow_sel);
   cutfont(0,  0,s,0x31,2);
   sprintf(s,"Ｘ   :  %3d",x);
   cutfont(0, 20,s,0x31,2);
   sprintf(s,"Ｙ   :  %3d",y);
   cutfont(0, 40,s,0x31,2);
   sprintf(s,"身份 :  %3d",id);
   cutfont(0, 60,s,0x31,2);
   sprintf(s,"方向 :  %3d",dir);
   cutfont(0, 80,s,0x31,2);
   sprintf(s,"對話 :  %3d  距離  : %3d",talk_id,z);
   cutfont(0,100,s,0x31,2);
   sprintf(s,"範圍 :  %3d %3d %3d %3d",
   startx,starty,width,high);
   cutfont(0,120,s,0x31,2);
   if(canmove)
      cutfont(0,140,"可以移動",0x31,2);
   else
      cutfont(0,140,"不可移動",0x31,2);
   sprintf(s,"COUNT %3d",manshow_count);
   cutfont(0,160,s,0x31,2);
   
   waitkey();
   show_mouse();
}

void manxy::print()
{
   printf("%3d %3d %3d %3d \n",startx,starty,id,talk_id);
}

void manxy::set(int x2,int y2,int id2,int dir2,int talk_id2,
int x3,int y3,int w2,int h2)
{
   x=x2;
   y=y2;
   //z=manxy_width * y + x;
   id=id2;
   dir=dir2;
   talk_id=talk_id2;
   go=0;
   startx=x3;
   starty=y3;
   width=w2;
   high=h2;                   
   canmove=0;
}

void manxy::save(int fno)
{
   write(fno,this,sizeof(manxy)-1);
}

void manxy::load(int fno)
{
   read(fno,this,sizeof(manxy)-1);
   if(startx!=width || starty!=high)
      canmove=1;
   else
      canmove=0;
}

void entry_point::set(int x1_2,int y1_2,int x2_2,int y2_2,
int new_x_2,int new_y_2,char *next_file_2,int script_no_2)
{
   x1=x1_2;
   y1=y1_2;
   x2=x2_2;
   y2=y2_2;
   new_x=new_x_2;
   new_y=new_y_2;
   strcpy(next_file,next_file_2);
   script_no=script_no_2;
}

void entry_point::set(int x1_2,int y1_2,int x2_2,int y2_2)
{
   x1=x1_2;
   y1=y1_2;
   x2=x2_2;
   y2=y2_2;
}   
   
int entry_point::check(int x,int y)
{
   return (x >= x1 && x<= x2 && y >= y1 && y <= y2);
}

void entry_point::showdata()
{
   char s[160];
   
   hide_mouse();
   
   black_box(0,0,320,200,1);
   
   sprintf(s,"序號 :  %3d",entry_sel);
   cutfont(0,  0,s,0x31,2);
   sprintf(s,"範圍 :  %3d %3d %3d %3d",x1,y1,x2,y2);
   cutfont(0, 20,s,0x31,2);
   sprintf(s,"新Ｘ :  %3d",new_x);
   cutfont(0, 40,s,0x31,2);
   sprintf(s,"新Ｙ :  %3d",new_y);
   cutfont(0, 60,s,0x31,2);
   //if(next_file[0])
      sprintf(s,"下一地圖 :  %s",next_file);
   /*else
      strcpy(s,"下一地圖 :  沒有");*/
   cutfont(0, 80,s,0x31,2);
   sprintf(s,"劇本 :  %3d",script_no);
   cutfont(0,100,s,0x31,2);
   
   waitkey();
   show_mouse();
}

void entry_point::load(int fno)
{
   read(fno,this,sizeof(entry_point));
}

void entry_point::save(int fno)
{
   write(fno,this,sizeof(entry_point));
}

void icon::show(int x,int y)
{
   showicon(screen + y * 320 + x ,s);
}

void icon::show2(int x,int y)
{  
   showiconm(screen + y * 320 + x ,s);
}

char icon::check()
{
   int i;
   
   for(i=0;i<64;i++)
   {
      if(s[i]==0)
         return 0;
   }
   return 1;
}

image::image()
{
   ptr=NULL;
   size=width=high=0;
}

image::image(int w1,int h1)
{
   high = h1;
   width = w1;
   size = w1 * h1;
   ptr = new char [size];
}

image::image(int x,int y,int w,int h)
{
   int i;
   char *s=screen + y * 320 + x,*p1;
   
   high = h;
   width = w;
   size = w * h;
   p1=ptr = new char [size];
   
   for(i=0;i<h;i++)
   {
      memcpy(p1,s,w);
      p1+=w;
      s+=320;
   }
}

image::~image()
{
   if(ptr)
      delete ptr;
}

void image::clear()
{
   if(ptr)
      delete ptr;

   ptr=NULL;
}

void image::set(char *filename,char code)
{
   int fno;

   fno=open(filename,O_RDONLY | O_BINARY);
   if(code)
   {
      size=filelength(fno)-4;
      ptr=new char [size];
      read(fno,&width,2);
      read(fno,&high,2);
      read(fno,ptr,size);
   }
   else
   {
      read(fno,&width,2);
      read(fno,&high,2);
      size=width * high;
      ptr=new char [size];
      read(fno,ptr,size);
   }
   close(fno);
}

void image::set(int x,int y,int w,int h)
{
   int i;
   char *s=screen + y * 320 + x,*p1 = ptr;
   
   high = h;
   width = w;
   size = w * h;
   
   for(i=0;i<h;i++)
   {
      memcpy(p1,s,w);
      p1+=w;
      s+=320;
   }
}

void image::save(char *filename)
{
   int fno;

   _fmode=O_BINARY;
   fno=creat(filename,S_IREAD | S_IWRITE);
   write(fno,&width,4);
   write(fno,ptr,size);
   close(fno);
}

void image::show(int x,int y)
{
   show_image(x,y,width,high,ptr);
}

void image::showm(int x,int y)
{
   show_image_mask(x,y,width,high,ptr);
}



void temp_block::set(int w,int h)
{
   width=w;
   high=h;
   
   tb = new short [width * high];
}

void temp_block::clear()
{
   high=width=0;
   if(tb)
      delete tb;
}

void temp_block::copy(temp_block &b2)
{
   clear();
   width=b2.width;
   high=b2.high;
   tb = new short [width * high];
   memfcpy(tb,b2.tb,width * high);
}

void temp_block::show(int x,int y)
{
   int i,j;
   short *s=tb;
   
   for(i=0;i<high;i++)
   {
      for(j=0;j<width;j++)
      {
         picon[abs(*s++)].show(x,y);
         x+=8;
      }
      y += 8;
      x -= 8 * width;
   }
}


void drawbutton
(int x,int y,int xlen,int ylen,char *s,char c1,char c2,char c3)
{
   char *screen2=screen+y*320+x;
   int i;
   
   memset(screen2,c2,xlen-1);
   screen2[xlen-1]=c3;
   screen2+=320;
   for(i=0;i<ylen-2;i++)
   {
      screen2[0]=c2;
      memset(screen2+1,c1,xlen-2);
      screen2[xlen-1]=c3;
      screen2+=320;
   }
   memset(screen2,c3,xlen);
   cutfont(x+8,y+3,s,0x31,2);
}

void menu::set(int x1,int y1,int xitem1,int yitem1,
            int xlen1,int ylen1,int itemlen1)
{
   x=x1;
   y=y1;
   xitem=xitem1;
   yitem=yitem1;
   xlen=xlen1;
   ylen=ylen1;
   itemlen=itemlen1;
}


                       
int menu::select(int can_esc,int can_show,int need_show)
{
   int i,j,k,sel=0,x2=x,y2=y,llen=xitem*yitem;
   int x3,y3,sel3;
   char key1,key2;
   hide_mouse();
   image scrbuf(x,y,xitem * xlen,yitem * ylen);
   
   if(can_show)
   {
      drawbutton(x,y,xlen,ylen,title,0x4a,0x56,0x50);
   
      for(k=0,i=0;i<yitem;i++)
         for(j=0;j<xitem;j++,k++)
            if(i || j)
               drawbutton
               (x+j*xlen,y+i*ylen,xlen,ylen
               ,title+k*itemlen,0x50,0x4a,0x56);
   }
   
   show_mouse();
   
   //key2=key1=0;
   for(;;)
   {
      key1=key2=0;
      inkey(key1,key2);
      //key1=inportb(0x60);
      x3=x2;
      y3=y2;
      sel3=sel;
      switch(key1)
      {
         case 80:
            y2+=ylen;
            sel+=xitem;
            if(sel>=llen)
            {
               sel-=llen;
               y2=y;
            }
         break;
         case 72:
            y2-=ylen;
            sel-=xitem;
            if(sel<0)
            {
               sel+=llen;
               y2=y+ylen*(yitem-1);
            }
         break;
         case 77:
            x2+=xlen;
            sel++;
            if(x2==x+xitem*xlen)
            {
               sel-=xitem;
               x2=x;
            }
         break;
         case 75:
            x2-=xlen;
            sel--;
            if(x2<x)
            {
               sel+=xitem;
               x2=x+(xitem-1)*xlen;
            }
         break;
         case 28: case 57:
            while(inp(0x60)<128)
            {}
            goto l1;
         case 1:
            if(can_esc)
            {
               sel=-1;
               goto l1;
            }
         break;
         default:
         {
            //key2=key1;
            if(mouse_event)
            {
               mouse_event=0;
               if(left_button)
               {
                  right_button=left_button=0;
                  int lx,ly;
                  
                  lx=(mouse_cx / 2 - x) / xlen;
                  ly=(mouse_dx - y) / ylen;
                  if(lx < xitem && ly < yitem && lx >= 0 && ly >= 0)
                  {
                     sel=ly * xitem + lx;
                     goto l1;
                  }
               }
               else
                  continue;
            }
            else
               continue;
         }
      }
      if(sel!=sel3)
      {
         hide_mouse();
         drawbutton(x3,y3,xlen,ylen,title+sel3*itemlen,0x50,0x4a,0x56);
         drawbutton(x2,y2,xlen,ylen,title+sel*itemlen,0x4a,0x56,0x50);
         show_mouse();
         delay(15);
      }
      /*if(key1!=key2)
      {
         key2=key1;
         delay_2(140);
      }
      else
         delay_2(40);*/
   }
   l1:

   //loadscreen(x,y,x+xitem*xlen,y+yitem*ylen,scrbuf);
   if(need_show)
   {
      hide_mouse();
      scrbuf.show(x,y);
      show_mouse();
   }
      
   //clear_key_buffer();
        
   return sel;
}


map::map()
{
   width=256;
   high=128;
   size=width * high;
   show_x=show_y=0;
   is_scroll=0;
   floor=new short [size];
   over=new short [size];
   scroll = new short [size];
   
   mem4set(floor,0,size / 2);
   mem4set(over,0,size / 2);
   mem4set(scroll,0,size / 2);
}

map::map(int w,int h)
{
   is_scroll=0;
   width=w;
   high=h;
   show_x=show_y=0;
   size=width * high;
   floor=new short [size];
   over=new short [size];
   scroll=new short [size];
   
   mem4set(floor,0,size / 2);
   mem4set(over,0,size / 2);
   mem4set(scroll,0,size / 2);
}

map::~map()
{
   if(floor)
   {
      delete floor;
      delete over;
      delete scroll;
   }
}

void map::clear()
{
   width=size=high=0;
   if(floor)
   {
      delete floor;
      delete over;
      delete scroll;
   }
}

void map::clear_floor()
{
   int i,j;
   
   home();
   mem4set(floor,0,size / 2);
   mem4set(over,0,size / 2);
   mem4set(scroll,0,size / 2);
}

void map::show()
{
   int i,j;
   char *sc_buf=new char [64000];
   
   screen=sc_buf;
   
   if(is_scroll)
   {
      if(spshow_on==3)
      {
         showmap2(show_x,show_y,width,floor);
         if(editmode<0)
            showover2(show_x,show_y,width,over);
      }
      else
      {
         showmap(show_x,show_y,width,floor);
         if(editmode<0)
            showover(show_x,show_y,width,over);
      }
   }
   else
   {
      if(spshow_on==3)
      {
         showmap2(show_x,show_y,width,floor);
         if(editmode<0)
            showover2(show_x,show_y,width,over);
      }
      else
      {
         showmap(show_x,show_y,width,floor);
         if(editmode<0)
            showover(show_x,show_y,width,over);
      }
   }
   
   if(spshow_on==1)
   {
      for(i=0;i<manshow_count;i++)
      {
         if(use_manxy[i].x >= show_x && use_manxy[i].x < show_x + 38 &&
         use_manxy[i].y >= show_y && use_manxy[i].y < show_y + 23)
         {
            useman[use_manxy[i].id].show(
            (use_manxy[i].x - show_x) * 8
            ,(use_manxy[i].y - show_y) * 8
            ,use_manxy[i].dir);
         }
      }
   }
   else
   if(spshow_on==2)
   {
      for(i=0;i<entry_count;i++)
      {
         if(use_entry[i].x1 >= show_x && use_entry[i].x1 < show_x + 40 &&
         use_entry[i].y1 >= show_y && use_entry[i].y1 < show_y + 25)
         {
            door_point[0].show(
            (use_entry[i].x1 - show_x) * 8
            ,(use_entry[i].y1 - show_y) * 8);
         }
         
         if(use_entry[i].x2 >= show_x && use_entry[i].x2 < show_x + 40 &&
         use_entry[i].y2 >= show_y && use_entry[i].y2 < show_y + 25)
         {
            door_point[2].show(
            (use_entry[i].x2 - show_x) * 8
            ,(use_entry[i].y2 - show_y) * 8);
         }
         
         if(use_entry[i].x1 >= show_x && use_entry[i].x1 < show_x + 40 &&
         use_entry[i].y2 >= show_y && use_entry[i].y2 < show_y + 25)
         {
            door_point[3].show(
            (use_entry[i].x1 - show_x) * 8
            ,(use_entry[i].y2 - show_y) * 8);
         }
         
         if(use_entry[i].x2 >= show_x && use_entry[i].x2 < show_x + 40 &&
         use_entry[i].y1 >= show_y && use_entry[i].y1 < show_y + 25)
         {
            door_point[1].show(
            (use_entry[i].x2 - show_x) * 8
            ,(use_entry[i].y1 - show_y) * 8);
         }
      }
   }
      
   screen=(char *)0xA0000;
   mem4cpy(screen,sc_buf,16000);
   
   delete sc_buf;   
}

void map::show2(int x1,int y1,int x2,int y2)
{
   int i,j;
   char *sc_buf=new char [64000];
   int dx,dy,dw,dh;
   
   screen=sc_buf;
   showmap(show_x,show_y,width,floor);
   if(editmode<0)
      showover(show_x,show_y,width,over);
      
   if(x1<show_x)
      dx=0;
   else
      dx=(x1-show_x) * 8;
      
   if(y1<show_y)
      dy=0;
   else
      dy=(y1-show_y) * 8;   
      
   dw=(x2 - x1 + 1 ) * 8;
   if(dw + dx > 320)
      dw=320 - dx;
   
   dh=(y2 - y1 + 1 ) * 8;
   if(dh + dy > 200)
      dh=200 - dy;
      
   black_box(dx,dy,dw,dh,1);
      
   screen=(char *)0xA0000;
   mem4cpy(screen,sc_buf,16000);
   
   delete sc_buf;   
}


void map::tran(int w2,int h2,int sx,int sy)
{
   int i,i2,j,j2,k;
   short *s1,*s2,*s3;
   int size2;
   
   size2=h2 * w2;
   if(size2 > 65536)
      return;
   
   s3=s1=new short [size2];
   memfset(s1,0,size2);
   s2=floor + sy * width;
   
   for(i=sy,i2=0;i<high && i2<h2;i++,i2++)
   {
      for(j=sx,j2=0;j<width && j2<w2;j++,j2++)
      {
         s3[j2]=s2[j];
      }
      s2+=width;
      s3+=w2;
   }
   delete floor;
   floor=s1;
   
   s3=s1=new short [size2];
   memfset(s1,0,size2);
   s2=over + sy * width;
   
   for(i=sy,i2=0;i<high && i2<h2;i++,i2++)
   {
      for(j=sx,j2=0;j<width && j2<w2;j++,j2++)
      {
         s3[j2]=s2[j];
      }
      s2+=width;
      s3+=w2;
   }
   delete over;
   over=s1;
   
   s3=s1=new short [size2];
   memfset(s1,0,size2);
   s2=scroll + sy * width;
   
   for(i=sy,i2=0;i<high && i2<h2;i++,i2++)
   {
      for(j=sx,j2=0;j<width && j2<w2;j++,j2++)
      {
         s3[j2]=s2[j];
      }
      s2+=width;
      s3+=w2;
   }
   delete scroll;
   scroll=s1;
   
   high=h2;
   width=w2;
   size=size2;
   
   show_x=show_y=0;
}

void map::undo()
{
   int i,j,w2,w3,px,py;
   short *s1=undo_block.tb;
   short *s2;
   
   px=undo_x;
   py=undo_y;
   
   if(undo_editmode<0)            
      s2=over  + py * width + px;
   else
      s2=floor + py * width + px;
   for(i=0;i<undo_block.high && py+i<high;i++)
   {
      for(w2=width,w3=undo_block.width,j=0;j<undo_block.width && 
      px+j<width;j++,w2--,w3--)
      {
         *s2=*s1;
         s1++;
         s2++;
      }
      s1+=w3;
      s2+=w2;
   }   
}

void map::draw1(int px,int py)
{
   int i,j,w2,w3;
   short *s1=main_block.tb;
   short *s2;
   short *s3;
   
   undo_block.clear();
   undo_x=show_x + px;
   undo_y=show_y + py;
   undo_block.set(main_block.width,main_block.high);
   s3=undo_block.tb;
   undo_editmode=editmode;
   
   if(editmode<0)            
      s2=over  + (show_y + py) * width + (show_x + px);
   else
      s2=floor + (show_y + py) * width + (show_x + px);
   for(i=0;i<main_block.high && py+show_y+i<high;i++)
   {
      for(w2=width,w3=main_block.width,j=0;j<main_block.width && 
      px+show_x+j<width;j++,w2--,w3--)
      {
         *s3=*s2;
         if(*s1)
         {
            *s2=*s1;
         }
         s1++;
         s2++;
         s3++;
      }
      s3+=w3;
      s1+=w3;
      s2+=w2;
   }   
}

void map::draw2(int px,int py)
{
   int i,j,k,w2,w3;
   short *s1=main_block.tb;
   short *s2,*s4;
   char s3[64];
   
   undo_block.clear();
   undo_x=show_x + px;
   undo_y=show_y + py;
   undo_block.set(main_block.width,main_block.high);
   s4=undo_block.tb;
   undo_editmode=editmode;
               
   if(editmode<0)            
      s2=over  + (show_y + py) * width + (show_x + px);
   else
      s2=floor + (show_y + py) * width + (show_x + px);
   for(i=0;i<main_block.high && py+show_y+i<high;i++)
   {
      for(w2=width,w3=main_block.width,j=0;j<main_block.width 
      && px+show_x+j<width;j++,w2--,w3--)
      {
         *s4=*s2;
         if(*s1)
         {
            if(*s2)
            {
               memcpy(s3,&picon[*s2],64);
               for(k=0;k<64;k++)
                  if(picon[*s1].the_ptrs(k))
                     s3[k]=picon[*s1].the_ptrs(k);
               for(k=0;k<picon_count;k++)
                  if(!memcmp(&picon[k],s3,64))
                     goto label1;
            
               memfcpy(&picon[picon_count],s3,32);
               k=picon_count++;
         
               label1:
               *s2=k;
            }
            else
               *s2=*s1;
         }
         s1++;
         s2++;
         s4++;
      }
      s1+=w3;
      s2+=w2;
      s4+=w3;
   }
}

void map::making()
{
   char key1,key2;
   int px,py,button,Sx,Sy;
   char pp,ff,f;
   clock_t Oldt=0;
   clock_t Newt;
   int Oldx,Oldy,sel_func=0,i,j;
   
   px=py=0;
   show();
   spoint.show2(0,0);
   if(mapid==2)
   {
      printfont(0,0,"賭中無相",0x31,2);
   }
   else
   {
      char s[20];
      
      sprintf(s,"%3d %3d",show_x+px,show_y+py);
      cutfont(0,0,s,0x31,2);
   }

   pp=px=py=0;
   for(;;)
   {
      inkey(key1,key2);
      if(key1 || key2)
      {
         f=1;
         switch(key1)
         {
            case 1:
               memfset(screen,0,32000);
               goto quit1;
            case 71:
               show_x=0;
               px=0;
            break;
            case 79:
               show_x=119;
               px=0;
            break;
            case 132:
               show_y=0;
               py=0;
            break;
            case 118:
               show_y=119;
               py=0;
            break;
            case 73:
               if(show_y-9>0)
                  show_y-=9;
               else
                  show_y=0;
            break;
            case 81:
               if(show_y+9<width - 25)
                  show_y+=9;
               else
                  show_y=width - 25;
            break;
            case 115:
               if(show_x-9>0)
                  show_x-=9;
               else
                  show_x=0;
            break;
            case 116:
               if(show_x+20<119)
                  show_x+=20;
               else
                  show_x=119;
            break;
            case 72:
               if(py>0)
                  py--;
               else
                  if(show_y>0)
                     show_y--;
            break;
            case 80:
               if(py<24)
                  py++;
               else
                  if(show_y<high - 25)
                     show_y++;
            break;
            case 75:
               if(px>0)
                  px--;
               else
                  if(show_x>0)
                     show_x--;
            break;
            case 77:
               if(px<39)
                  px++;
               else
                  if(show_x<width - 40)
                     show_x++;
            break;
            case 78:
               pp++;
               if(picon_count==pp)
                  pp=0;
            break;
            case 74:
               if(pp==0)
                  pp=picon_count-1;
               else
                  pp--;
            break;
            case 57:
                  *(floor + (show_y + py) * width + (show_x + px))=pp;
            break;
            case 59:
               draw1(px,py);
            break;
            case 60:
               cut_block(px,py);
            break;
            case 61:
               draw2(px,py);
            break;
            default:
              f=0;
         }
         
      }
      else
      if(mouse_event)
      {
         mouse_event=0;
         if(right_button)
         {
            while(!(mouse_code & 16))
            {
               if(mouse_dx<=5)
               {
                  if(show_y)
                     show_y--;
                  f=1;
               }
               else
               if(mouse_dx>=195)
               {
                  if(show_y<high - 25)
                     show_y++;
                  f=1;
               }
               else
               if(mouse_cx<=5)
               {
                  if(show_x)
                     show_x--;
                     f=1;
               }
               else
               if(mouse_cx>=630)
               {
                  if(show_x<width - 40)
                     show_x++;
                  f=1;
               }
               else
               {
                  int b=function();
                  
                  if(b==4)
                  {
                     //if(spshow_on!=3)
                        editmode=-editmode;
                  }
                  else
                  if(b==5)
                  {
                     catid=-catid;
                  }
                  else
                  if(b==6)
                  {
                     mapid=3;
                     
                     hide_mouse();
                     memfset(screen,0,32000);
                     show_mouse();
                     goto quit1;
                  }
                  else
                  if(b==15)
                  {
                     hide_mouse();
                     memfset(screen,0,32000);
                     show_mouse();
                     goto quit1;
                  }
                  else
                  if(b!=-1)
                     sel_func=b;
                  goto label3;
               }
               if(f)
               {
                  //test show
                  //showmap(show_x,show_y,width,floor);
                  show();
                  /*if(mapid==2)
                     printfont(0,0,"賭中無相",0x31,2);*/
                  f=0;
               }
            }
            label3:
            f=1;
            right_button=0;
            hide_mouse();
            show();
            show_mouse();
         }
         else
         if(left_button)
         {
            check_mouse(button,Sx,Sy);
            while(button & 1)
            {
               if(Sx-std_x>16 || Sy-std_y>8)
               {
                  int r;
                  
                  px=std_x / 16;
                  py=std_y / 8;
                  if(sel_func==10)
                  {
                     make_door(px,py);
                  }
                  else
                  if(sel_func==12)
                  {
                     set_neg(px,py);
                  }
                  else
                  {
                     if(catid<0)
                        clear_block_mouse(px,py);
                     else
                     {
                        cut_block_mouse(px,py);
                        sel_func=0;
                     }
                  }
                  
                  f=1;
                  goto label2;
               }
               check_mouse(button,Sx,Sy);
            }
            
            /*if(!Oldt)
            {
               Oldt=clock();
               Oldx = std_x;
               Oldy = std_y;
            }
            else*/
            {
               //if(Newt-Oldt<=30 && std_x==Oldx && std_y==Oldy)
               if(std_x/16 == px && std_y/8 == py)
               {
                  Oldt=0;
                  switch(sel_func)
                  {
                     case 0:
                        draw1(px,py);
                        f=1;
                     break;
                     case 1:
                        draw2(px,py);
                        f=1;
                     break;
                     ////////////////////////////
                     //  make man
                     case 8:
                        for(i=0;i<manshow_count;i++)
                        {
                           if(
                           show_x+px >= use_manxy[i].x &&
                           show_y+py >= use_manxy[i].y &&
                           show_x+px <= use_manxy[i].x + 2 &&
                           show_y+py <= use_manxy[i].y + 2
                           )
                           {
                              
                              manshow_sel=i;
                              selman();
                              f=1;
                              goto label2;
                           }
                        }
                           
                        if(manshow_sel!=-1)
                           use_manxy[manshow_sel].set(show_x+px,show_y+py);
                        f=1;
                     break;
                     case 10:
                        for(i=0;i<entry_count;i++)
                        {
                           if(
                           show_x+px >= use_entry[i].x1 &&
                           show_y+py >= use_entry[i].y1 &&
                           show_x+px <= use_entry[i].x2 &&
                           show_y+py <= use_entry[i].y2 
                           )
                           {
                              
                              entry_sel=i;
                              seldoor();
                              f=1;
                              goto label2;
                           }
                        }
                           
                        f=1;
                     break;
                  }
                  
                  goto label2;
               }
               /*else
               {
                  Oldt=clock();
                  Oldx = mouse_cx;
                  Oldy = mouse_dx;
               }*/
            }
            
            px=mouse_cx / 16;
            py=mouse_dx / 8;
            f=1;
            
            label2:
            
            left_button=0;
         }
         else
            f=0;
      }
      if(f)
      {
         hide_mouse();
         show();
         picon[pp].show(px * 8,py * 8);
         spoint.show2(px * 8,py * 8);
         if(mapid==2)
         {
            printfont(0,0,"賭中無相",0x31,2);
         }
         else
         {
            char s[20];
      
            sprintf(s,"%3d %3d",show_x+px,show_y+py);
            cutfont(0,0,s,0x31,2);
         }
         show_mouse();
         f=0;
      }
   }
   
   quit1:
   return;
}

void box(int x,int y,int w,int h)
{
   int x1 = x * 8;
   int y1 = y * 8;
   int x2 = x1 + w * 8 - 1;
   int y2 = y1 + h * 8 - 1;
   
   line256(x1,y1,x2,y1,1,0);
   line256(x2,y1,x2,y2,1,0);
   line256(x1,y1,x1,y2,1,0);
   line256(x1,y2,x2,y2,1,0);
}

void map::showman(int sp,int sel)
{
   int i,j,x,y;
   char *s1;
   
   hide_mouse();
   show();
   i=j=0;
   x=5;
   y=25;
   for(;;)
   {
      if(i==sel)
      {
         s1=screen + y * 320 + x;
         for(j=0;j<24;j++)
         {
            memset(s1,16,24);
            s1+=320;
         }
      }
      useman[sp+i].show(x,y);
      x+=30;
      i++;
      if(i+sp==man_count)
      {
         drawbutton(0,178,50,20,"上捲",0x4a,0x56,0x50);
         drawbutton(268,178,50,20,"下捲",0x4a,0x56,0x50);
         show_mouse();
         break;
      }
      else
      if(x>300)
      {
         y+=25;
         if(y>160)
         {
            drawbutton(0,178,50,20,"上捲",0x4a,0x56,0x50);
            drawbutton(268,178,50,20,"下捲",0x4a,0x56,0x50);
            show_mouse();
            break;
         } 
         x=5;
      }
   }
   
   
   //waitkey();
}

int map::catman()
{
   char key1,key2,f=1;
   int sp,sel,x,y,l,sel_count;
   int r=0;
   
   sp=sel=0;
   mouse_event=left_button=right_button=0;
   if(sp + 60 < man_count )
      sel_count=60;
   else
      sel_count=man_count - sp;
   for(;;)
   {
      if(f==1)
      {
         f=0;
         showman(sp,sel);
      }
      key1=key2=0;
      inkey(key1,key2);
      if(key1==1)
      {
         r=-1;
         break;
      }
      else
      if(mouse_event)
      {
         if(left_button)
         {
            x=mouse_cx / 2;
            y=mouse_dx;
            if(x>=5 && x<305 && y>=25 && y<=175)
            {
               l=(y-25) / 25 * 10 + (x-5) / 30;
               if(l<sel_count)
               {
                  if(l==sel)
                  {
                     r=sp + sel;
                     break;
                  }
                  else
                  {
                     sel=l;
                     f=1;
                  }
               }
            }
            else
            if(x<50 && y>=180 && sp+60 < man_count)
            {
               sp+=10;
               sel=0;
               if(sp + 60 < man_count )
                  sel_count=60;
               else
                  sel_count=man_count - sp;
               f=1;
            }
            else
            if(x>=268 && y>=180 && sp>0)
            {
               sp-=10;
               sel=0;
               if(sp + 60 < man_count )
                  sel_count=60;
               else
                  sel_count=man_count - sp;
               f=1;
            }
         }
         else
         if(right_button)
         {
            r=-1;
            break;
         }
         mouse_event=left_button=right_button=0;
      }
   }
   mouse_event=left_button=right_button=0;
   
   return r;
}

void change_xy(int &x1,int &y1,int &x2,int &y2)
{
   int t;
   
   if(x1 > x2)
   {
      t  = x2;
      x2 = x1;
      x1 = t;
   }
   if(y1 > y2)
   {
      t  = y2;
      y2 = y1;
      y1 = t;
   }
}

int map::setrange(int px,int py)
{
   char key1,key2;
   int button,Sx,Sy,r;
   char pp,ff,f;
   clock_t Oldt=0;
   clock_t Newt;
   int Oldx,Oldy,sel_func=0,i,j;
   int x1,y1,x2,y2;
   
   for(;;)
   {
      if(mouse_event)
      {
         mouse_event=0;
         if(right_button)
         {
            while(!(mouse_code & 16))
            {
               if(mouse_dx==0)
               {
                  if(show_y)
                     show_y--;
                  f=1;
               }
               else
               if(mouse_dx==199)
               {
                  if(show_y<high - 25)
                     show_y++;
                  f=1;
               }
               else
               if(mouse_cx==0)
               {
                  if(show_x)
                     show_x--;
                     f=1;
               }
               else
               if(mouse_cx>=637)
               {
                  if(show_x<width - 40)
                     show_x++;
                  f=1;
               }
               if(f)
               {
                  //test show
                  //showmap(show_x,show_y,width,floor);
                  show();
                  /*if(mapid==2)
                     printfont(0,0,"賭中無相",0x31,2);*/
                  f=0;
               }
            }
            label3:
            f=1;
            right_button=0;
            hide_mouse();
            show();
            show_mouse();
         }
         else
         if(left_button)
         {
            int ex,ey,w,h,button,w2,h2;
            
            int f=0;
            
            px=mouse_cx / 16;
            py=mouse_dx / 8;
            
            x1=x2=show_x + px;
            y1=y2=show_y + py;
            mouse_event=right_button=left_button=0;
            //hide_mouse();
            for(;;)
            {
               check_mouse(button,ex,ey);
               px=ex / 16;
               py=ey / 8;
               if(button & 1)
               {
                  if(ey==0)
                  {
                     if(show_y)
                        show_y--;
                     f=1;
                  }
                  else
                  if(ey==199)
                  {
                     if(show_y<high - 25)
                        show_y++;
                     f=1;
                  }
                  else
                  if(ex==0)
                  {
                     if(show_x)
                        show_x--;
                     f=1;
                  }
                  else
                  if(ex>=637)
                  {
                     if(show_x<width - 40)
                        show_x++;
                     f=1;
                  }
                  //if(f)
                  {
                     if(show_x+px>=x1)
                        x2=show_x+px;
                     if(show_y+py>=y1)   
                        y2=show_y+py;
                     show2(x1,y1,x2,y2);
                     f=0;
                  }
               }
               else
               {
                  use_manxy[manshow_sel].startx=x1;
                  use_manxy[manshow_sel].starty=y1;
                  use_manxy[manshow_sel].width=x2;
                  use_manxy[manshow_sel].high=y2;
                  //show_mouse();
                  goto quit1;
                  break;
               }
            }
            //break;
            goto quit1;
         }
      mouse_event=right_button=left_button=0;
      }
   }
   
   quit1:
   
   if(x1!=x2 || y1!=y2)
      use_manxy[manshow_sel].canmove=1;
   else
      use_manxy[manshow_sel].canmove=0;
   
   return r;
}

int map::selman()
{
   menu main_menu;
   char main_title[12][5]={
   "換人","資料","範圍","對話","斬人","距離","DIR","LOAD","SAVE","離開"
   };
   char key1,key2;
   char nums[80];
   int sel,r=-1,i;
   
   mouse_event=right_button=left_button=0;
   main_menu.set(0,0,2,5,50,20,5);
   main_menu.settitle((char *)main_title);
   sel=main_menu.select();
   switch(sel)
   {  
      case 0:
         man_id=catman();
         if(man_id!=-1)
         {
            use_manxy[manshow_sel].set(man_id);
         }
      break;
      case 1:
      {
         show();
         use_manxy[manshow_sel].showdata();
      }
      break;
      case 2:
         setrange(use_manxy[manshow_sel].x
         ,use_manxy[manshow_sel].y);
         r=2;
      break;
      case 3:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         itoa(use_manxy[manshow_sel].talk_id,nums,10);
         drawbutton(8,23,180,20,"對話",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            use_manxy[manshow_sel].talk_id=atoi(nums);
         }
         show_mouse();
      break;
      case 4:
         if(manshow_count>1)
         {
            memmove(use_manxy+manshow_sel,
            use_manxy+manshow_sel+1,
            (manshow_count-1-manshow_sel) * sizeof(manxy));
            manshow_count--;
            manshow_sel=0;
         }
         else
         if(manshow_count==1)
         {
            manshow_count--;
            manshow_sel=0;
         }
         else
            manshow_sel=-1;
      break;
      case 5:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         itoa(use_manxy[manshow_sel].z,nums,10);
         drawbutton(8,23,180,20,"距離",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            use_manxy[manshow_sel].z=atoi(nums);
         }
         show_mouse();
      break;
      case 6:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         itoa(use_manxy[manshow_sel].dir,nums,10);
         drawbutton(8,23,180,20,"DIR",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            use_manxy[manshow_sel].dir=atoi(nums);
         }
         show_mouse();
      break;
      case 7:
         if(load_man2(pub_manfile))
         {
            int l=strlen(pub_manfile)-4;
               
            cutfont(15,15,pub_manfile,0x02,0x31);
            load_man(pub_manfile);
               
            pub_manfile[l]=0;
         }
      break;
      case 8:
         if(lineedit(pub_manfile))
         {
            hide_mouse();
              
            save_man(pub_manfile);
            cutfont(8,83,"檔案儲存中",0x31,2);
               
            show_mouse();
               
         }
      break;
   }
   
   return r;
}

void save_entry(char *filename)
{
   int fno,i;
   char filename2[30];
   
   strcpy(filename2,filename);
   strcat(filename2,".ENT");
   fno=creat(filename2,S_IREAD | S_IWRITE);
   write(fno,&entry_count,2);
   for(i=0;i<entry_count;i++)
      use_entry[i].save(fno);
   close(fno);
}

void load_entry(char *filename)
{
   int fno,i,l;
   
   fno=open(filename,O_RDONLY | O_BINARY);
   read(fno,&entry_count,2);
   for(i=0;i<entry_count;i++)
      use_entry[i].load(fno);
   close(fno);
}

int map::seldoor()
{
   menu main_menu;
   char main_title[16][5]={
   "資料","劇本","地圖","找圖",
   "NEWX","NEWY","取出","存入","閂門","離開"
   };
   char key1,key2;
   char nums[80];
   int sel,r=-1,i;
   
   mouse_event=right_button=left_button=0;
   main_menu.set(0,0,2,5,50,20,5);
   main_menu.settitle((char *)main_title);
   sel=main_menu.select();
   switch(sel)
   {  
      case 0:
      {
         show();
         use_entry[entry_sel].showdata();
      }
      break;
      
      case 1:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         itoa(use_entry[entry_sel].script_no,nums,10);
         drawbutton(8,23,180,20,"劇本",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            use_entry[entry_sel].script_no=atoi(nums);
         }
         show_mouse();
      break;
      case 2:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         strcpy(nums,use_entry[entry_sel].next_file);
         drawbutton(8,23,180,20,"地圖",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            strcpy(use_entry[entry_sel].next_file,nums);
         }
         show_mouse();
      break;
      case 3:
         if(load_file(use_entry[entry_sel].next_file,"*.map"))
         {
            int l=strlen(use_entry[entry_sel].next_file);
            
            use_entry[entry_sel].next_file[l-4]=0;
         }
         
      break;
      case 4:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         itoa(use_entry[entry_sel].new_x,nums,10);
         drawbutton(8,23,180,20,"NEWX",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            use_entry[entry_sel].new_x=atoi(nums);
         }
         show_mouse();
      break;
      case 5:
         hide_mouse();
         show();
         black_box(0,0,320,200,1);
         itoa(use_entry[entry_sel].new_y,nums,10);
         drawbutton(8,23,180,20,"NEWY",0x56,0x4A,0x50);
         if(lineedit(nums))
         {
            use_entry[entry_sel].new_y=atoi(nums);
         }
         show_mouse();
      break;
      case 6:
         if(load_file(pub_entryfile,"*.ent"))
         {
            int l=strlen(pub_entryfile)-4;
               
            cutfont(15,15,pub_entryfile,0x02,0x31);
            load_entry(pub_entryfile);
               
            pub_entryfile[l]=0;
         }
      break;
      case 7:
         if(lineedit(pub_entryfile))
         {
            hide_mouse();
              
            save_entry(pub_entryfile);
            cutfont(8,83,"檔案儲存中",0x31,2);
               
            show_mouse();
              
         }
      break;
      case 8:
         if(entry_count>1)
         {
            memmove(use_entry+entry_sel,
            use_entry+entry_sel+1,
            (entry_count-1-entry_sel) * sizeof(entry_point));
            entry_count--;
            entry_sel=0;
         }
         else
         if(entry_count==1)
         {
            entry_count--;
            entry_sel=0;
         }
         else
            entry_sel=-1;
      break;
   }
   
   return r;
}



int map::function()
{
   menu func_menu;
   char func_title[18][5]={
   "覆蓋\","重疊","方塊","座標",
   "上下","清除","換頁","重來",
   "放人","殺人","開門","看門",
   "負力","＋－","離開","結束"
   };
   char key1,key2;
   int sel,r;
   
   if(catid<0)
      strcpy(func_title[5],"抓圖");
   
   mouse_event=right_button=left_button=0;   
   func_menu.set(0,0,2,8,50,20,5);
   func_menu.settitle((char *)func_title);
   sel=func_menu.select();
   switch(sel)
   {  
      case 0:
         spshow_on=0;
         r=0;
      break;
      case 1:
         spshow_on=0;
         r=1;
      break;
      case 2:
         spshow_on=0;
         change_block();
         r=-1;
      break;
      case 3:
        change_point();
        r=-1;
      break;
      case 7:
         undo();
         r=-1;
      break;
      case 8:
         man_id=catman();
         if(man_id!=-1)
         {
            spshow_on=1;
            manshow_sel=manshow_count++;
            use_manxy[manshow_sel].set(man_id);
            r=8;
         }
      break;
      case 9:
         spshow_on=1;
         r=8;
      break;
      case 10:
         entry_sel=entry_count++;
         spshow_on=2;
         r=10;
      break;
      case 11:
         if(entry_count>0)
         {
            
            r=10;
            spshow_on=2;
         }
         else
            r=-1;
      break;
      case 12:
         spshow_on=3;
         //editmode=-1;
         isneg=-1;
         r=12;
      break;
      case 13:
         spshow_on=3;
         //editmode=-1;
         isneg=-isneg;
         r=12;
      break;
      case -1: case 14:
         r=-1;
      break;
      default:
         r=sel;
      break;
   }
   return r;
}

void map::cut_block(int px,int py)
{
   int i,j,x,y,w,h,lx,ly,f=1;
   short *p3,*p4;
   char key1,key2;
   
   w=h=1;
   x=show_x + px;
   y=show_y + py;
   for(;;)
   {
      inkey(key1,key2);
      switch(key1)
      {
         case 1:
            goto quit1;
         case 57:
         {
            main_block.clear();
            main_block.set(w,h);
            p3=main_block.tb;
            if(editmode<0)
               p4=over + width * y + x;
            else
               p4=floor + width * y + x;
            
            for(i=0;i<h;i++)
            {
               for(j=0;j<w;j++)
                  *p3++=*p4++;
               p4+=width  - w;
            }
            goto quit1;
         }
         case 72:
            if(h > 1)
            {
               h--;
               f=1;
            }
         break;
         case 80:
            if(h < 25 - py)
            {
               h++;
               f=1;
            }
         break;
         case 75:
            if(w > 1)
            {
               w--;
               f=1;
            }
         break;
         case 77:
            if(w < 40 - px)
            {
               w++;
               f=1;
            }
         break;
         default:
            f=0;
      }   
      if(f)
      {
         /*if(editmode<0)
            showover(show_x,show_y,width,over);
         else
            showmap(show_x,show_y,width,floor);   */
         show();
         box(px,py,w,h);
      }
   }
   quit1:
   return;
}

void check_mouse(int &button,int &x,int &y)
{
   union REGS inregs, outregs;
   
   inregs.w.ax = 0x3;
   int386( 0x33, &inregs, &outregs );
   
   button=outregs.w.bx;
   x=outregs.w.cx;
   y=outregs.w.dx;
}

void map::save(char *filename)
{
   int fno,i;
   
   _fmode=O_BINARY;
   fno=creat(filename,S_IREAD | S_IWRITE);
   write(fno,&width,8);
   write(fno,floor,size * 2);
   write(fno,over,size * 2);
   for(i=0;i<size;i++)
   {
      if(scroll[i])
      {
         write(fno,scroll,size * 2);
         break;
      }
   }
   close(fno);
}
   
void map::save_scroll(char *filename)
{
   int fno,i;
   char s[80];
   
   strcpy(s,filename);
   for(i=0;i<size;i++)
   {
      if(scroll[i])
      {
         strcpy(s+strlen(s)-3,"sro");
         fno=creat(s,S_IREAD | S_IWRITE);
         write(fno,scroll,size * 2);
         close(fno);
         break;
      }
   }
}

void map::load(char *filename)
{
   int fno;
   char s[80];

   strcpy(s,filename);
   fno=open(filename,O_RDONLY | O_BINARY);
   read(fno,&width,4);
   read(fno,&high,4);
   size=width * high;
   floor=new short [size];
   over=new short [size];
   scroll=new short [size];
   read(fno,floor,size * 2);
   read(fno,over,size * 2);
   if(!eof(fno))
   {
      read(fno,scroll,size * 2);
      //is_scroll=1;
   }
   else
   {
      mem4set(scroll,0,size / 2);
      //is_scroll=0;
   }
   close(fno);
   show_x=show_y=0;
   is_scroll=0;
}

void map::load_scroll(char *filename)
{
   int fno;
   char s[80]; 
   
   fno=open(s,O_RDONLY | O_BINARY);
   if(fno!=-1)
   {
      read(fno,scroll,size * 2);
      close(fno);
   }
   else
      mem4set(scroll,0,size / 2);
}

void map::change_point()
{
   short *temp1;
         
   if(is_scroll)
   {
      is_scroll=0;
      
      temp1=scroll;
      scroll=floor;
      floor=over;
      over=temp1;
   }
   else
   {
      is_scroll=1;
      
      temp1=floor;
      floor=scroll;
      scroll=over;
      over=temp1;
            
   }
   //go_scroll;
}

int map::cut_block_mouse(int px,int py)
{
   int i,j,x,y,w,h,ex,ey,r,button,w2,h2;
   short *p3,*p4;
   char key1,key2;
   
   w=h=1;
   w2=h2=0;
   x=show_x + px;
   y=show_y + py;
   hide_mouse();
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         ex/=16;
         ey/=8;
         w=(ex>=px ? ex-px+1 : 1);
         h=(ey>=py ? ey-py+1 : 1);
         if(w2 != w || h2 != h)
         {
            /*if(editmode<0)
               showover(show_x,show_y,width,over);
            else
               showmap(show_x,show_y,width,floor);*/
            show();
            box(px,py,w,h);
            h2=h;
            w2=w;
         }
      }
      else
         break;
   }
   
   show_mouse();
   
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         main_block.clear();
         main_block.set(w,h);
         p3=main_block.tb;
         if(editmode<0)
            p4=over  + width * y + x;
         else
            p4=floor + width * y + x;
            
         for(i=0;i<h;i++)
         {
            for(j=0;j<w;j++)
               *p3++=*p4++;
            p4+=width  - w;
         }
         r=1;
         break;
      }
      else
      if(button & 2)
      {
         r=2;
         break;
      }
   }
   
   while(!(button & 3))
      check_mouse(button,ex,ey);
   mouse_event=0;
      
   return r;
}

int map::clear_block_mouse(int px,int py)
{
   int i,j,x,y,w,h,ex,ey,r,button,w2,h2;
   short *p3,*p4;
   char key1,key2;
   short *s4;
   
   w=h=1;
   w2=h2=0;
   x=show_x + px;
   y=show_y + py;
   hide_mouse();
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         ex/=16;
         ey/=8;
         w=(ex>=px ? ex-px+1 : 1);
         h=(ey>=py ? ey-py+1 : 1);
         if(w2 != w || h2 != h)
         {
            show();
            box(px,py,w,h);
            h2=h;
            w2=w;
         }
      }
      else
         break;
   }
   
   show_mouse();
   
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         undo_block.clear();
         undo_x=show_x + px;
         undo_y=show_y + py;
         undo_block.set(w,h);
         s4=undo_block.tb;
         undo_editmode=editmode;
         
         if(editmode<0)            
            p4=over  + width * y + x;
         else
            p4=floor + width * y + x;
            
            
            
         for(i=0;i<h;i++)
         {
            for(j=0;j<w;j++)
            {
               *s4++=*p4;
               *p4++=0;
            }
            p4+=width  - w;
         }
         r=1;
         break;
      }
      else
      if(button & 2)
      {
         r=2;
         break;
      }
   }
   
   while(!(button & 3))
      check_mouse(button,ex,ey);
   mouse_event=0;
      
   return r;
}

int map::make_door(int px,int py)
{
   int i,j,x,y,w,h,ex,ey,r,button,w2,h2;
   short *p3,*p4;
   char key1,key2;
   
   w=h=1;
   w2=h2=0;
   x=show_x + px;
   y=show_y + py;
   hide_mouse();
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         ex/=16;
         ey/=8;
         w=(ex>=px ? ex-px+1 : 1);
         h=(ey>=py ? ey-py+1 : 1);
         if(w2 != w || h2 != h)
         {
            /*if(editmode<0)
               showover(show_x,show_y,width,over);
            else
               showmap(show_x,show_y,width,floor);*/
            show();
            box(px,py,w,h);
            h2=h;
            w2=w;
         }
      }
      else
         break;
   }
   
   show_mouse();
   
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         use_entry[entry_sel].set(x,y,x+w-1,y+h-1);
         r=10;
         break;
      }
      else
      if(button & 2)
      {
         r=10;
         break;
      }
   }
   
   while(!(button & 3))
      check_mouse(button,ex,ey);
   mouse_event=0;
      
   return r;
}

int map::set_neg(int px,int py)
{
   int i,j,x,y,w,h,ex,ey,r,button,w2,h2;
   short *p3,*p4;
   char key1,key2;
   short *s4;
   short p5;
   
   w=h=1;
   w2=h2=0;
   x=show_x + px;
   y=show_y + py;
   hide_mouse();
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         ex/=16;
         ey/=8;
         w=(ex>=px ? ex-px+1 : 1);
         h=(ey>=py ? ey-py+1 : 1);
         if(w2 != w || h2 != h)
         {
            show();
            box(px,py,w,h);
            h2=h;
            w2=w;
         }
      }
      else
         break;
   }
   
   show_mouse();
   
   for(;;)
   {
      check_mouse(button,ex,ey);
      if(button & 1)
      {
         main_block.clear();
         main_block.set(w,h);
         p3=main_block.tb;
         if(editmode<0)
            p4=over  + width * y + x;
         else
            p4=floor + width * y + x;
         
         if(isneg==-1)
         {
            for(i=0;i<h;i++)
            {
               for(j=0;j<w;j++)
               {
                  p5=*p4;
                  if(p5>0)
                    *p4=-p5;
                  p4++;
               }
               p4+=width  - w;
            }
         }
         else
         {
            for(i=0;i<h;i++)
            {
               for(j=0;j<w;j++)
               {
                  p5=*p4;
                  if(p5<0)
                    *p4=-p5;
                  p4++;
               }
               p4+=width  - w;
            }
         }
         r=12;
         break;
      }
      else
      if(button & 2)
      {
         r=12;
         break;
      }
   }
   
   while(!(button & 3))
      check_mouse(button,ex,ey);
   mouse_event=0;
      
   return r;
}


void map::optimize()
{
   int i,j,count2=picon_count-1;
   
   memfset(opti_temp,1,4096);
   
   for(j=0;j<size;j++)
   {
      opti_temp[abs(floor[j])]=0;
   }
   for(j=0;j<size;j++)
   {
      opti_temp[abs(over[j])]=0;
   }
   
   for(i=1;i<picon_count;i++)
   {
      if(opti_temp[i])
         mem4set(picon+i,0,16);
   }
   
   for(i=picon_count-1;i>0;i--)
   {
      if(!opti_temp[i])
         break;
      else
         picon_count--;
   }
   
   optimize_on=1;
   
   /*for(i=1;i<picon_count && i<count2;i++)
   {
      if(temp[i])
      {
         while(temp[count2])
         {
            count2--;
         }
         count2
      }
   }*/
   
   /*while(i<picon_count)
   {
      for(j=0;j<size;j++)
      {
         if(floor[j]==i)
            goto label1;
      }
      for(j=0;j<size;j++)
      {
         if(over[j]==i)
            goto label1;
      }
      
      mem4set(picon+i,0,16);
      
      label1:
      i++;
   }*/
}



////////////////////////////////////////////////////////







///////////////////////////////////////////////////////////

void inkey(char &key1,char &key2)
{
   short int key;
   
   if(kbhit())
   {
      key=inkeyasm();
      key2=key; // && 0x00FF;
      key1=key >> 8;
   }
   else
      key1=key2=0;
}

void waitkey()
{
   char key1,key2;     
   int button,Sx,Sy;
   
   while(!_bios_keybrd(1))
   {
      if(mouse_event) 
      {
         mouse_event=0;
         if(right_button)
         {
            right_button=0;
            return ;
         }
      }
   }
   inkey(key1,key2);
}



void setup()
{
   int fno,size,i;
   char *ptr1,*cpoint;
   char filename[20];
   
   _fmode=O_BINARY;
   
   screen=(char *)0xA0000;
   picon = new icon [2048];
   
   /*fno=open("icon.blk",O_RDONLY | O_BINARY);
   size=filelength(fno);
   read(fno,picon,size);
   close(fno);*/
   mem4set(picon,0,16);
   mpicon=(char *)picon;
   picon_count=1;
   
   /*fno=open("base.i45",O_RDONLY | O_BINARY);
   size=filelength(fno);
   read(fno,ficon,size);
   close(fno);*/
   
   fno=open("point",O_RDONLY | O_BINARY);
   size=filelength(fno);
   cpoint=new char [size];
   read(fno,cpoint,size);
   close(fno);
   memcpy(&spoint,cpoint + 4,64);
   
   strcpy(filename,"point001");
   for(i=0;i<4;i++)
   {
      fno=open(filename,O_RDONLY | O_BINARY);
      read(fno,cpoint,68);
      close(fno);
      memcpy(&door_point[i],cpoint + 4,64);
      filename[7]++;
   }
   
   setmode13();
   fontsetup();
   
   SetPal256(cpoint+(size - 768));
   
   delete cpoint;
   
   
   ///////////////////////////////////////////
   /*
   fno=open("hill001.img",O_RDONLY | O_BINARY);
   size=filelength(fno);
   cpoint=new char [size];
   read(fno,cpoint,size);
   close(fno);
   
   SetPal256(cpoint+(size - 768));
   
   delete cpoint;
   */
   ////////////////////////////////////////
   
}


///////////////////////////////////////////////////////////



void block(int x,int y,int w,int h,char c)
{
   int i,j;
   char *s=screen + y * 320 + x;
   
   for(i=0;i<h;i++)
   {
      for(j=0;j<w;j++)
         s[j]=c;
      s+=320;
   }
}

typedef temp_block *blockptr;
blockptr *use_block;
int block_count=0;

void take_icon(image &a)
{
   char s[64],*p0=a.the_ptr(),*p1=p0,*p2;
   short *p3;
   short i,j,k,l,m,w,h,mod;
   int x=0,y=0;
   char key1,key2;
   
   hide_mouse();
   w=a.the_width() / 8;
   mod=a.the_width() % 8;
   h=a.the_high() / 8;
   
   memfset(screen,0,32000);
   main_block.clear();
   main_block.set(w,h);
   p3=main_block.tb;

   for(i=0;i<h;i++)
   {
      for(j=0;j<w;j++)
      {
         p2=p1;
         m=0;
         for(k=0;k<8;k++)
         {
            for(l=0;l<8;l++)
               s[m++]=p2[l];
            p2+=a.the_width();
             
         }
         
         for(k=0;k<picon_count;k++)
         {
            if(!memcmp(&picon[k],s,64))
            {
               *p3=k;
               goto label1;
            }
         }
         
         if(optimize_on)
         {
            for(k=1;k<picon_count;k++)
            {
               if(opti_temp[k])
               {
                  memfcpy(&picon[k],s,32);
                  picon[k].show(x,y);
                  *p3=k;
                  opti_temp[k]=0;
                  goto label1;
               }
            }
         }
         
         {
            memfcpy(&picon[picon_count],s,32);
            picon[picon_count].show(x,y);
            *p3=picon_count;
            picon_count++;
         }
         
         label1:
         
         p3++;
         x+=9;
         p1+=8;
      }
      y+=9;
      x=0;
      p1+=a.the_width() * 7 + mod;
   }
   
   if(block_count<32)
   {
      for(i=0;i<block_count;i++)
      {
         if(use_block[i]->width == main_block.width &&
         use_block[i]->high == main_block.high)
         {
            if(!memcmp(use_block[i]->tb,main_block.tb,h * w * 2))
               goto quit1;
         }
      }
   
   
      use_block[block_count]=new temp_block;
      use_block[block_count]->copy(main_block);
      block_count++;
   }
   
   quit1:
   
   show_mouse();
   waitkey();
}

void change_block()
{
   menu main_menu;
   char main_title[6][5]={"前頁","次頁","取圖","轉換","加圖","離開"};
   char key1,key2;
   int sel,block_sel=0;
   
   mouse_event=right_button=left_button=0;
   main_menu.set(0,0,6,1,50,20,5);
   main_menu.settitle((char *)main_title);
   
   hide_mouse();
   memfset(screen,0,5120);
   show_mouse();
   
   for(;;)
   {
      hide_mouse();
      memfset(screen+5120,0,32000-5120);
      if(block_count)
         use_block[block_sel]->show(0,22);
      show_mouse();
      sel=main_menu.select();
      switch(sel)
      {
         case 0:
            if(block_sel>0)
               block_sel--;
            else
               block_sel=block_count-1;
         break;
         case 1:
            if(block_sel<block_count-1)
               block_sel++;
            else
               block_sel=0;
         break;
         case 2:
            main_block.copy(*use_block[block_sel]);
            return;
         break;
         case 3:
            use_block[block_sel]->copy(main_block);
            return;
         break;
         case 4:
            if(block_count<32)
            {
               use_block[block_count]=new temp_block;
               block_sel=block_count++;
               use_block[block_sel]->copy(main_block);
            }
            return;
         break;
         case 5: case -1:
            memfset(screen,0,32000);
            return;
         //break;
      }
   }
}

void view_icon(image &a)
{
   char s[64],*p0=a.the_ptr(),*p1=p0,*p2;
   icon *spoint;
   int i,j,k,l,m,w,h,mod;
   int x=0,y=0;
   char key1,key2;
   
   hide_mouse();
   spoint=(icon *)s;
   w=a.the_width() / 8;
   mod=a.the_width() % 8;
   h=a.the_high() / 8;
   mem4set(screen,0,16000);

   for(i=0;i<h;i++)
   {
      for(j=0;j<w;j++)
      {
         p2=p1;
         m=0;
         for(k=0;k<8;k++)
         {
            for(l=0;l<8;l++)
               s[m++]=p2[l];
            p2+=a.the_width();
         }
         
         spoint->show2(x,y);
         x+=9;
         
         p1+=8;
      }
      y+=9;
      x=0;
      if(y>190)
      {
         waitkey();
         mem4set(screen,0,16000);
         y=0;
      }
      p1+=a.the_width() * 7 + mod;
   }
   show_mouse();
   waitkey();
}

void show_use_icon()
{
   int i,x,y;
   
   hide_mouse();
   memfset(screen,0,32000);
   x=y=0;
   for(i=0;i<picon_count;i++)
   {
      picon[i].show(x,y);
      x+=8;
      if(x==320)
      {
         x=0;
         y+=8;
      }
      if(y>=180)
      {
         waitkey();
         mem4set(screen,0,16000);
         y=0;
      }
   }
   show_mouse();
   waitkey();
}


void show_cat_image(char *s)
{
   menu main_menu;
   char main_title[5][5]={"分解","存入","仆街","暫存","離開"};
   char key1,key2;
   int sel;
   image aaa(s);
   
   mouse_event=right_button=left_button=0;
   main_menu.set(0,0,5,1,50,20,5);
   main_menu.settitle((char *)main_title);
   
   for(;;)
   {
      hide_mouse();
      memfset(screen,0,32000);
      aaa.show(0,20);
      show_mouse();
      sel=main_menu.select();
      switch(sel)
      {
         case 0:
            view_icon(aaa);
         break;
         case 1:
            take_icon(aaa);
         break;
         case 2:
            show_use_icon();
         break;
         case 3:
            //if(block_count)
               change_block();
         break;
         case 4: case -1:
            memfset(screen,0,32000);
            return;
         //break;
      }
   }
}

typedef char filelist[512][15];
typedef char filestring[15];

void print_filelist(filestring *filename,int count,int sg,int g,int l)
{
   int i;
   
   block(0,0,100,199,0);
   for(i=0;i<10 && i<count;i++)
   {
      printfont(0,i * 16 + 10,filename[sg+i],5);
   }   
   block(0,l * 16 + 9,100,15,0x50);
   printfont(0,l * 16 + 10,filename[g],5);
}



void sort_dir(filestring *filename,int count)
{
   int i,j;
   char temp_string[20];
   
   for(i=count - 1;i>=0;i--)
      for(j=0;j<i;j++)
         if(strcmp(filename[j],filename[j+1])>0)
         {
            strcpy(temp_string,filename[j]);
            strcpy(filename[j],filename[j+1]);
            strcpy(filename[j+1],temp_string);
         }
}


void read_image()
{
   struct find_t fileblk;
   //filelist *filename=new filelist;
   filestring *filename=new filestring[1024];
   char key1,key2;
   int done,i=0,g=0,count,l=0,f=1,sg=0;
   char review=1;
   image preview;
   
   
   done=_dos_findfirst("*.img",0,&fileblk);
   strcpy(filename[i++],fileblk.name);
   while(i<1024 && !done)
   {
      done=_dos_findnext(&fileblk);
      strcpy(filename[i++],fileblk.name);
   }
   
   printfont(120,10,"上",5);
   printfont(120,154,"下",5);
   printfont(220,180,"離開",5);
   
   count=i-1;
   
   sort_dir(filename,count);
   
   for(;;)
   {
      
      if(f)
      {
         hide_mouse();
         print_filelist(filename,count,sg,g,l);
         f=0;
         show_mouse();
      }
      
      inkey(key1,key2);
      switch(key1)
      {
         case 1:
            goto quit1;
         case 28:
            show_cat_image(filename[g]);
            printfont(120,10,"上",5);
            printfont(120,154,"下",5);
            printfont(220,180,"離開",5);
            review=f=1;
         break;
         case 72:
            if(g>0)
            {
               g--;
               if(l>0)
                  l--;
               else
                  sg--;
               review=f=1;
            }
         break;
         case 73:
            if(sg>=10)
            {
               g-=10+l;
               l=0;
               sg-=10;
               review=f=1;
            }
            else
            {
               g=0;
               sg=0;
               l=0;
               review=f=1;
            }
         break;
         case 80:
            if(g<count-1)
            {
               g++;
               if(l<9)
                  l++;
               else
                  sg++;
               review=f=1;
            }
         break;
         case 81:
            if(sg+10<count-11)
            {
               g+=10;
               sg+=10;
               
               review=f=1;
            }
            else
            {
               g=sg=count-11;
               l=0;
               
               review=f=1;
            }
         break;
         default:
         if(left_button)
         {
            mouse_event=0;
            if((mouse_code & 2) && !(mouse_code & 1))
            {
               int lx,ly;
               
               //left_button=0;
               lx=(mouse_cx / 2);
               ly=(mouse_dx - 10) / 16;
               if(lx>=120 && lx<=136)
               {
                  if(mouse_dx>=10 && mouse_dx<=26)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg>0)
                        {
                           sg--;
                           g--;
                           review=f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
                  else
                  if(mouse_dx>=154 && mouse_dx<=170)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg+10<count)
                        {
                           sg++;
                           g++;
                           review=f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
               }
               else
               if(lx>=220 && lx<=252 && mouse_dx>=180 && mouse_dx<=196)
               {
                  goto quit1;
               }
               else
               {
                  if(ly>=count)
                     ly=count-1;
                  if(ly <= 9 && ly>=0 && lx<100)
                  {
                     if(mouse_event)
                        while(mouse_code & 4);
                     g=sg+ly;
                     l=ly;
                     show_cat_image(filename[g]);
                     printfont(120,10,"上",5);
                     printfont(120,154,"下",5);
                     printfont(220,180,"離開",5);
                     review=f=1;
                  }
               }
            }
         }
         else
         if(review)
         {
            int i;
            preview.set(filename[g]);
            for(i=0;i<200;i++)
               mem4set(screen + 160 + i * 320,0,40);
            if(preview.the_width()<=160)
               preview.show(160,0);
            else
               preview.cutshow(160,0,0,0,160,preview.the_high());
            print_filelist(filename,count,sg,g,l);
            preview.clear();
            review=0;
         }
      }
   }
   
   quit1:
   
   hide_mouse();
   memfset(screen,0,32000);
   show_mouse();
   delete filename;
   return;
   
}   

char lineedit(char *line)
{
   char key1,key2,r;
   int i,sel,len;
   
   hide_mouse();
   sel=len=strlen(line);
   strcat(line,"_");
   drawbutton(8,43,180,20,line,0x56,0x4A,0x50);
   for(;;)
   {
      inkey(key1,key2);
      if(key2==8 && sel>0)
      {
         line[sel]=0;
         sel--;
         line[sel]='_';
         drawbutton(8,43,180,20,line,0x56,0x4A,0x50);
      }
      else
      if(key2==13)
      {
         r=1;
         goto quit1;
      }
      else
      if(key2==27)
      {  
         r=0;
         goto quit1;
      }
      else
      if(key2>='0' &&  sel<8)
      {
         
         line[sel]=key2;
         sel++;
         line[sel]='_';
         line[sel+1]=0;
         
         drawbutton(8,43,180,20,line,0x56,0x4A,0x50);
      }
      
   }
   quit1:
   
   line[sel]=0;
   show_mouse();
   return r;
}

char read_iconfile(char *filename2)
{
   struct find_t fileblk;
   //filelist *filename=new filelist;
   filestring *filename=new filestring[1024];
   char key1,key2;
   int done,i=0,g=0,count,l=0,f=1,sg=0,r=1;
   
   
   done=_dos_findfirst("*.ico",0,&fileblk);
   strcpy(filename[i++],fileblk.name);
   while(i<1024 && !done)
   {
      done=_dos_findnext(&fileblk);
      strcpy(filename[i++],fileblk.name);
   }
   
   printfont(120,10,"上",5);
   printfont(120,154,"下",5);
   printfont(220,180,"離開",5);
   
   count=i-1;
   
   sort_dir(filename,count);
   
   for(;;)
   {
      
      if(f)
      {
         hide_mouse();
         print_filelist(filename,count,sg,g,l);
         f=0;
         show_mouse();
      }
      
      inkey(key1,key2);
      switch(key1)
      {
         case 1:
            r=0;
            goto quit1;
         case 28:
            strcpy(filename2,filename[g]);
            goto quit1;
         break;
         case 72:
            if(g>0)
            {
               g--;
               if(l>0)
                  l--;
               else
                  sg--;
               f=1;
            }
         break;
         case 73:
            if(sg>=10)
            {
               g-=10+l;
               l=0;
               sg-=10;
               f=1;
            }
            else
            {
               g=0;
               sg=0;
               l=0;
               f=1;
            }
         break;
         case 80:
            if(g<count-1)
            {
               g++;
               if(l<9)
                  l++;
               else
                  sg++;
               f=1;
            }
         break;
         case 81:
            if(sg+10<count-11)
            {
               g+=10;
               sg+=10;
               
               f=1;
            }
            else
            {
               g=sg=count-11;
               l=0;
               
               f=1;
            }
         break;
         default:
         if(mouse_event)
         {
            mouse_event=0;
            if((mouse_code & 2) && !(mouse_code & 1))
            {
               int lx,ly;
               
               left_button=0;
               lx=(mouse_cx / 2);
               ly=(mouse_dx - 10) / 16;
               if(lx>=120 && lx<=136)
               {
                  if(mouse_dx>=10 && mouse_dx<=26)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg>0)
                        {
                           sg--;
                           g--;
                           f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
                  else
                  if(mouse_dx>=154 && mouse_dx<=170)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg+10<count)
                        {
                           sg++;
                           g++;
                           f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
               }
               else
               if(lx>=220 && lx<=252 && mouse_dx>=180 && mouse_dx<=196)
               {
                  r=0;
                  goto quit1;
               }
               else
               {
                  if(ly>=count)
                     ly=count-1;
                  if(ly <= 9 && ly>=0 && lx<100)
                  {
                     if(mouse_event)
                        while(mouse_code & 4);
                     g=sg+ly;
                     l=ly;
                     
                     strcpy(filename2,filename[g]);
                     goto quit1;
                  }
               }
            }
         }
      }
   }
   
   quit1:
   
   hide_mouse();
   memfset(screen,0,32000);
   show_mouse();
   delete filename;
   
   return r;
   
}   



void save_picon(char *filename)
{
   int fno,i;
   
   fno=creat(filename,S_IREAD | S_IWRITE);
   //write(fno,&picon_count,4);
   write(fno,picon,picon_count * 64);
   close(fno);
}

void load_picon(char *filename)
{
   int fno,i;
   
   fno=open(filename,O_RDONLY | O_BINARY);
   picon_count=filelength(fno);
   read(fno,picon,picon_count);
   picon_count/=64;
   close(fno);
}

void save_man(char *filename)
{
   int fno,i;
   char filename2[30];
   
   strcpy(filename2,filename);
   strcat(filename2,".man");
   fno=creat(filename2,S_IREAD | S_IWRITE);
   write(fno,&manshow_count,2);
   manmove_count=0;
   for(i=0;i<manshow_count;i++)
      if(use_manxy[i].canmove)
         manmove_count++;
         
   write(fno,&manmove_count,2);
   for(i=0;i<manshow_count;i++)
      if(use_manxy[i].canmove)
         use_manxy[i].save(fno);
   for(i=0;i<manshow_count;i++)
      if(!use_manxy[i].canmove)
         use_manxy[i].save(fno);      
   close(fno);
}

void load_man(char *filename)
{
   int fno,i,l;
   //char filename2[30];
   
   //strcpy(filename2,filename);
   //strcat(filename2,".man");
   fno=open(filename,O_RDONLY | O_BINARY);
   read(fno,&manshow_count,2);
   read(fno,&manmove_count,2);
   for(i=0;i<manshow_count;i++)
      use_manxy[i].load(fno);
   close(fno);
}

char load_man2(char *filename2)
{
   struct find_t fileblk;
   //filelist *filename=new filelist;
   filestring *filename=new filestring[1024];
   char key1,key2;
   int done,i=0,g=0,count,l=0,f=1,sg=0,r=1;
   
   
   done=_dos_findfirst("*.man",0,&fileblk);
   strcpy(filename[i++],fileblk.name);
   while(i<1024 && !done)
   {
      done=_dos_findnext(&fileblk);
      strcpy(filename[i++],fileblk.name);
   }
   
   printfont(120,10,"上",5);
   printfont(120,154,"下",5);
   printfont(220,180,"離開",5);
   
   count=i-1;
   
   sort_dir(filename,count);
   
   for(;;)
   {
      
      if(f)
      {
         hide_mouse();
         print_filelist(filename,count,sg,g,l);
         f=0;
         show_mouse();
      }
      
      inkey(key1,key2);
      switch(key1)
      {
         case 1:
            r=0;
            goto quit1;
         case 28:
            strcpy(filename2,filename[g]);
            goto quit1;
         break;
         case 72:
            if(g>0)
            {
               g--;
               if(l>0)
                  l--;
               else
                  sg--;
               f=1;
            }
         break;
         case 73:
            if(sg>=10)
            {
               g-=10+l;
               l=0;
               sg-=10;
               f=1;
            }
            else
            {
               g=0;
               sg=0;
               l=0;
               f=1;
            }
         break;
         case 80:
            if(g<count-1)
            {
               g++;
               if(l<9)
                  l++;
               else
                  sg++;
               f=1;
            }
         break;
         case 81:
            if(sg+10<count-11)
            {
               g+=10;
               sg+=10;
               
               f=1;
            }
            else
            {
               g=sg=count-11;
               l=0;
               
               f=1;
            }
         break;
         default:
         if(mouse_event)
         {
            mouse_event=0;
            if((mouse_code & 2) && !(mouse_code & 1))
            {
               int lx,ly;
               
               left_button=0;
               lx=(mouse_cx / 2);
               ly=(mouse_dx - 10) / 16;
               if(lx>=120 && lx<=136)
               {
                  if(mouse_dx>=10 && mouse_dx<=26)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg>0)
                        {
                           sg--;
                           g--;
                           f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
                  else
                  if(mouse_dx>=154 && mouse_dx<=170)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg+10<count)
                        {
                           sg++;
                           g++;
                           f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
               }
               else
               if(lx>=220 && lx<=252 && mouse_dx>=180 && mouse_dx<=196)
               {
                  r=0;
                  goto quit1;
               }
               else
               {
                  if(ly>=count)
                     ly=count-1;
                  if(ly <= 9 && ly>=0 && lx<100)
                  {
                     if(mouse_event)
                        while(mouse_code & 4);
                     g=sg+ly;
                     l=ly;
                     
                     strcpy(filename2,filename[g]);
                     goto quit1;
                  }
               }
            }
         }
      }
   }
   
   quit1:
   
   hide_mouse();
   memfset(screen,0,32000);
   show_mouse();
   delete filename;
   
   return r;
   
}   

char load_file(char *filename2,char *wide)
{
   struct find_t fileblk;
   //filelist *filename=new filelist;
   filestring *filename=new filestring[1024];
   char key1,key2;
   int done,i=0,g=0,count,l=0,f=1,sg=0,r=1;
   
   
   done=_dos_findfirst(wide,0,&fileblk);
   strcpy(filename[i++],fileblk.name);
   while(i<1024 && !done)
   {
      done=_dos_findnext(&fileblk);
      strcpy(filename[i++],fileblk.name);
   }
   
   printfont(120,10,"上",5);
   printfont(120,154,"下",5);
   printfont(220,180,"離開",5);
   
   count=i-1;
   
   sort_dir(filename,count);
   
   for(;;)
   {
      
      if(f)
      {
         hide_mouse();
         print_filelist(filename,count,sg,g,l);
         f=0;
         show_mouse();
      }
      
      inkey(key1,key2);
      switch(key1)
      {
         case 1:
            r=0;
            goto quit1;
         case 28:
            strcpy(filename2,filename[g]);
            goto quit1;
         break;
         case 72:
            if(g>0)
            {
               g--;
               if(l>0)
                  l--;
               else
                  sg--;
               f=1;
            }
         break;
         case 73:
            if(sg>=10)
            {
               g-=10+l;
               l=0;
               sg-=10;
               f=1;
            }
            else
            {
               g=0;
               sg=0;
               l=0;
               f=1;
            }
         break;
         case 80:
            if(g<count-1)
            {
               g++;
               if(l<9)
                  l++;
               else
                  sg++;
               f=1;
            }
         break;
         case 81:
            if(sg+10<count-11)
            {
               g+=10;
               sg+=10;
               
               f=1;
            }
            else
            {
               g=sg=count-11;
               l=0;
               
               f=1;
            }
         break;
         default:
         if(mouse_event)
         {
            mouse_event=0;
            if((mouse_code & 2) && !(mouse_code & 1))
            {
               int lx,ly;
               
               left_button=0;
               lx=(mouse_cx / 2);
               ly=(mouse_dx - 10) / 16;
               if(lx>=120 && lx<=136)
               {
                  if(mouse_dx>=10 && mouse_dx<=26)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg>0)
                        {
                           sg--;
                           g--;
                           f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
                  else
                  if(mouse_dx>=154 && mouse_dx<=170)
                  {
                     while(!(mouse_code & 4))
                     {
                        if(sg+10<count)
                        {
                           sg++;
                           g++;
                           f=1;
                           print_filelist(filename,count,sg,g,l);
                           delay(50);
                        }
                     }
                  }
               }
               else
               if(lx>=220 && lx<=252 && mouse_dx>=180 && mouse_dx<=196)
               {
                  r=0;
                  goto quit1;
               }
               else
               {
                  if(ly>=count)
                     ly=count-1;
                  if(ly <= 9 && ly>=0 && lx<100)
                  {
                     if(mouse_event)
                        while(mouse_code & 4);
                     g=sg+ly;
                     l=ly;
                     
                     strcpy(filename2,filename[g]);
                     goto quit1;
                  }
               }
            }
         }
      }
   }
   
   quit1:
   
   hide_mouse();
   memfset(screen,0,32000);
   show_mouse();
   delete filename;
   
   return r;
   
}   


void filesystem()
{
   menu main_menu;
   char main_title[12][5]={"清除","取檔","存檔","轉換",
   "LOAD","SAVE","CLS","OPT","離開"};
   char key1,key2;
   int sel,i;
   
   
   memfset(screen,0,32000);
   
   mouse_event=right_button=left_button=0;
   main_menu.set(0,0,1,9,50,20,5);
   main_menu.settitle((char *)main_title);
   
   for(;;)
   {
      sel=main_menu.select();
      switch(sel)
      {
         case 0:
            undo_block.clear();
            picon_count=1;
            entry_count=0;
            manmove_count=manshow_count=0;
            spshow_on=0;
            mainmap->clear_floor();
            tempmap->clear_floor();
            pub_filename[0]=0;
            for(i=0;i<block_count;i++)
               delete use_block[i];
            block_count=0;
            optimize_on=0;
            goto quit1;
         break;
         case 1:
            if(read_iconfile(pub_filename))
            {
               int l=strlen(pub_filename)-4;
               
               undo_block.clear();
               picon_count=1;
               entry_count=0;
               manmove_count=manshow_count=0;
               spshow_on=0;
               optimize_on=0;
               
               mainmap->clear();
               tempmap->clear();
               load_picon(pub_filename);
               strcpy(pub_filename+l,".map");
               mainmap->load(pub_filename);
               /*strcpy(pub_filename+l,".sro");
               mainmap->load_scroll(pub_filename);*/
               strcpy(pub_filename+l,".tma");
               tempmap->load(pub_filename);
               
               pub_filename[l]=0;
            }
            goto quit1;
         break;
         case 2:
            if(lineedit(pub_filename))
            {
               int l,fno,i;
               
               char *su;
               
               hide_mouse();
               
               cutfont(8,83,"檔案儲存中",0x31,2);
               
               if(mainmap->is_scroll)
                  mainmap->change_point();
               
               l=strlen(pub_filename);
               strcat(pub_filename,".ico");
               save_picon(pub_filename);
               strcpy(pub_filename+l,".map");
               mainmap->save(pub_filename);
               /*strcpy(pub_filename+l,".sro");
               mainmap->save_scroll(pub_filename);*/
               strcpy(pub_filename+l,".tma");
               tempmap->save(pub_filename);
               
               strcpy(pub_filename+l,".che");
               fno=creat(pub_filename,S_IREAD | S_IWRITE);
               su=new char [picon_count];
               for(i=0;i<picon_count;i++)
                  su[i]=picon[i].check();
               write(fno,su,picon_count);
               delete su;
               close(fno);
               
               memset(screen,0,64000);
               
               show_mouse();
               
               pub_filename[l]=0;
               
            }
            goto quit1;
         break;
         case 3:
         {
            int w2,h2,sx,sy;
            char nums[20];
            
            itoa(mainmap->the_width(),nums,10);
            //strcpy(nums,"256");
            drawbutton(8,23,180,20,"WIDTH",0x56,0x4A,0x50);
            if(!lineedit(nums))
               goto quit1;
            else
               w2=atoi(nums);
            
            itoa(mainmap->the_high(),nums,10);
            //strcpy(nums,"128");
            drawbutton(8,23,180,20,"HIGH",0x56,0x4A,0x50);
            if(!lineedit(nums))
               goto quit1;
            else
               h2=atoi(nums);
            
            strcpy(nums,"0");
            drawbutton(8,23,180,20,"Start X",0x56,0x4A,0x50);
            if(!lineedit(nums))
               goto quit1;
            else
               sx=atoi(nums);
            
            strcpy(nums,"0");
            drawbutton(8,23,180,20,"Start Y",0x56,0x4A,0x50);
            if(!lineedit(nums))
               goto quit1;
            else
            {
               sy=atoi(nums);
               mainmap->tran(w2,h2,sx,sy);
            }
            
            goto quit1;
         }
         break;
         case 4:
            if(load_man2(pub_manfile))
            {
               int l=strlen(pub_manfile)-4;
               
               cutfont(15,15,pub_manfile,0x02,0x31);
               load_man(pub_manfile);
               
               pub_manfile[l]=0;
            }
            goto quit1;
         break;
         case 5:
            if(lineedit(pub_manfile))
            {
               hide_mouse();
               
               save_man(pub_manfile);
               cutfont(8,83,"檔案儲存中",0x31,2);
               
               show_mouse();
               
            }
            goto quit1;
         break;
         case 6:
            entry_count=0;
            manmove_count=manshow_count=0;
            goto quit1;
         break;
         case 7:
            mainmap->optimize();
            goto quit1;
         break;
         case 8:
            goto quit1;
      }
   }
   quit1:
   return;
}

int quit_pro()
{
   menu quit_menu;
   char quit_title[2][5]={"取消","離開"};
   
   mouse_event=right_button=left_button=0;
   quit_menu.set(0,100,1,2,50,20,5);
   quit_menu.settitle((char *)quit_title);
   
   return quit_menu.select();
}


//class char table[256];
char color_table[4][256];

void black_box(int x,int y,int w,int h,int t1)
{
   char *s1=screen,c;
   int l=320 - w,i,j;
   
   s1+=y * 320 + x;
   
   for(i=0;i<h;i++)
   {
      for(j=0;j<w;j++)
      {
         c=*s1;
         *s1=color_table[t1][c];
         s1++;
      }
      s1+=l;
   }
}


void selector()
{
   menu main_menu;
   char main_title[6][5]={"圖檔","地圖","圖塊","檔案","離開"};
   char key1,key2;
   int sel;
   
   mouse_event=right_button=left_button=0;
   main_menu.set(0,0,5,1,50,20,5);
   main_menu.settitle((char *)main_title);
   
   for(;;)
   {
      sel=main_menu.select();
      switch(sel)
      {
         case 0:
            read_image();
         break;
         case 1:
         {
            label1:
            //undo_block.clear();
            if(mapid==1)
            {
               mainmap->making();
               if(mapid==3)
               {
                  mapid=2;
                  goto label1;
               }
            }
            else
            {
               tempmap->making();
               if(mapid==3)
               {
                  mapid=1;
                  goto label1;
               }
            }
            
         }
         break;
         case 3:
            filesystem();
         break;
         case 4:
         {
            if(quit_pro()==1)
               goto quit1;
         }
         break;
      }
   }
   quit1:
   return;
}

/////////////////////////////////////////////////////////////////
/*
char map45[128][128];

void testmap45(int x,int y)
{
   int i,j,k;
   char *s1,*s2;
   int x2,y2,x3,y3;
   
   mem4set(screen,0,16000);
   
   s1=screen+320*8-16;
   
   x2=x;y3=y2=y;
   for(i=0;i<20;i+=2)
   {
      s2=s1;
      x3=x2;
      if(y3 >= 0 && y3<=127)
      {
         if(x3>=0 && x3<=127)
            ficon[map45[y3][x3]].showl(s1);
         x3++;
         s1-=2544;
         for(j=0;j<i;j++)
         {
            if(x3>=0 && x3<=127)
               ficon[map45[y3][x3]].show(s1);
            x3++;
            s1-=2544;
         }
         if(x3>=0 && x3<=127)
            ficon[map45[y3][x3]].showd(s1);
      }
      s1=s2+320*16;
      x2--;
      y3++;
   }
   
   if(y3 >= 0 && y3<=127)
   {
      s2=s1;
      x3=x2;
      if(x3>=0 && x3<=127)
         ficon[map45[y3][x3]].showl(s1);
      x3++;
      s1-=2544;
      for(j=0;j<19;j++)
      {
         if(x3>=0 && x3<=127)
            ficon[map45[y3][x3]].show(s1);
         x3++;
         s1-=2544;
      }
      if(x3>=0 && x3<=127)
         ficon[map45[y3][x3]].showr(s1);
   }
   s1=s2+320*16;
   x2--;
   y3++;
   
   
   if(y3 >= 0 && y3<=127)
   {
      s2=s1;
      x3=x2;
      if(x3>=0 && x3<=127)
         ficon[map45[y3][x3]].showl(s1);
      x3++;
      s1-=2544;
      for(j=0;j<19;j++)
      {
         if(x3>=0 && x3<=127)
            ficon[map45[y3][x3]].show(s1);
         x3++;
         s1-=2544;
      }
      if(x3>=0 && x3<=127)
          ficon[map45[y3][x3]].showr(s1);
   }
   s1=s2+320*8+16;
   y3++;
   
   for(i=18;i>=0;i-=2)
   {
      s2=s1;
      x3=x2;
      if(y3 >=0 && y3<=127)
      {
         if(x3>=0 && x3<=127)
            ficon[map45[y3][x3]].showt(s1);
         x3++;
         s1-=2544;
         for(j=0;j<i;j++)
         {
            if(x3>=0 && x3<=127)
               ficon[map45[y3][x3]].show(s1);
            x3++;
            s1-=2544;
         }
         if(x3>=0 && x3<=127)
            ficon[map45[y3][x3]].showr(s1);
      }
      s1=s2+32;
      y3++;
      x2++;
   }
}


void usemap45()
{
   char key1,key2;
   int x=1,y=0;
   int f=1;
   char s[50];
   
   for(;;)
   {
      inkey(key1,key2);
      if(f)
      {
         testmap45(x,y);
         sprintf(s,"X=%3d Y=%3d",x,y);
         printfont(0,180,s,5);
      }
      f=1;
      switch(key1)
      {
         case 72: case 71:
            if(y>-10)
            {
               if(x>116)
               {
                  if(y-(x-117) >= -9)
                     y--;
               }
               else
               if(y>0)
               {
                  y--;
               }
               else
               if(x+y>=0)
                  y--;
            }
         break;
         case 80: case 81:
            if(y<116)
            {
               if(x>117)
               {
                  if(y<235-x)
                     y++;
               }
               else
               if(y>105)
               {
                  if(y-x<105)
                     y++;
               }
               else
                  y++;
            }
         break;
         case 75: case 79:
            if(x>1)
            {
               if(y>105)
               {
                  if(y-x < 105)
                     x--;
               }
               else
               if(x+y>=0)
                  x--;
            }
         break;
         case 77: case 73:
            if(x<127)
            {
               if(y<0)
               {
                  if(x-y<127)
                     x++;
               }
               else
               if(y>107)
               {
                  if(x+y<235)
                     x++;
               }
               else
                  x++;
            }   
         break;
         default:
            f=0;
         break;
         case 1:
            goto quit1;
      }
   }
   quit1:
   return;
}
*/
/////////////////////////////////////////////////////////////////

char test5[256];



void main()
{
   int fno,size,i,j,l;
   short width,high;
   image aaa("hill001.img",1);
   char *s1,*s2;
   
   
   /*char key1,key2;
   
   for(;;)
   {
      inkey(key1,key2);
      if(key1)
         printf("key1 = %d , key2 = %d \n",key1,key2);
      if(key1==1)
         break;
   }*/
   
   
   
   
   mainmap = new map;
   tempmap = new map(128,128);
   opti_temp=new short [4096];
   setup();
   
   
   fno=open("..\\map\\color.tab",O_RDONLY | O_BINARY);
   //l=filelength(fno) / 256;
   //color_table = new table [l];
   read(fno,color_table,512);
   close(fno);
   
   fno=open("..\\man\\human.ico",O_RDONLY | O_BINARY);
   l=filelength(fno);
   man_count=l / ( 8 * 24 * 24 );
   useman=new man [man_count];
   read(fno,useman,l);
   close(fno);
   
   use_block=new blockptr [32];
   
   setup_mouse();
   mouse_setrange(639,199);
   fno=open("mouseptr",O_RDONLY | O_BINARY);
   read(fno,mousepoint,256);
   close(fno);
   show_mouse();
   
   mapstr=new short [256 * 128];
   memset(mapstr,0,256 * 128);
   mapstr[0]=2;
   mapstr[1]=1;
   mapstr[3]=1;
   mapstr[10]=2;
   mapstr[128]=1;
   mapstr[267]=1;
   
   showmap(0,0,128,mapstr);
   spoint.show2(screen);
   picon[1].show(screen+32000);
   
   mem4set(test5,0x0f4e3e2b,64);
   
   showicon45(screen+16000,test5);
   showicon45r(screen+16080,test5);
   showicon45l(screen+16160,test5);
   
   showicon45t(screen+16240,test5);
   showicon45d(screen+16240+640,test5);
   
   showicon45r(screen+180 * 320,test5);
   showicon45l(screen+180 * 320,test5);
   
   //waitkey();
   
   ////////////////////////////////////////////
   
   //usemap45();
   
   ////////////////////////////////////////////////////////
   
   
   showmap(2,0,128,mapstr);
   spoint.show2(screen+8);
   //waitkey();
   
   aaa.show(10,10);
   aaa.showm(20,20);
   aaa.cutshow(50,50,5,5,15,15);
   
   selector();
   
   showmap(0,2,128,mapstr);
   spoint.show2(screen);
   
   /*printfont(10,10,"Hello");
   printfont(50,40,"老烏龜仆街！",15,15);
   printfont(0,75,"陳志明  黃喬璟",15,15);
   printfont(0,100,"生意興隆  大吉大利  客似雲來",15,15);*/
   
   
   waitkey();
   
   setmodetext();
   
   //printf("Hello! $ ");
   
   clear_mouse();
   
   
   
   
   
   delete mapstr;
   //delete color_table;
   
   //printf("Hello! 0 ");
   
   for(i=0;i<block_count;i++)
      delete use_block[i];
      
   //printf("Hello! 1 ");   
      
   
   delete use_block;
   delete useman;
   delete opti_temp;
   delete picon;
   delete mainmap;
   delete tempmap;
   fontclose();
   
   for(i=0;i<manshow_count;i++)
   {
      if(use_manxy[i].canmove)
         use_manxy[i].print();
   }
   printf("\n");
   for(i=0;i<manshow_count;i++)
   {
      if(!use_manxy[i].canmove)
         use_manxy[i].print();
   }
}

