/****************************************************************************
 *                                                                          *
 *      16色TIFF (パレット付き) ローダー                       Ver 4.0      *
 *                                                                          *
 ****************************************************************************/

#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>

void setg(void);


unsigned char   far *plane=(unsigned char far *)0xc0000000l;

void main(int argc,char *argv[])
{
int             i,j,k,
		gx,gy,
		l,m,
		r,g,b,
		rr[16],gg[16],bb[16],
		fl=0,
		page=0,
		_seg=0xc000,
		_off=0xff81,

		v=100,
		vl=0,
		x=0, y=0,
		kv=100,
		key=0,
		flg=0;

unsigned char   dat[512] , filename[255],sw[3],str[256],c;

	setg();

	for(i=1;i<argc;i++){
	  strncpy(sw,argv[i],2); sw[3]='\0';
	  if(((sw[0]=='-')||(sw[0]=='/'))&&((sw[1]=='v')||(sw[1]=='V'))){
	    strcpy(str,(argv[i]+2));
	    v=atoi(str);
	    vl=1;
	    }
	  if(((sw[0]=='-')||(sw[0]=='/'))&&((sw[1]=='k')||(sw[1]=='K'))){
	    strcpy(str,(argv[i]+2));
	    kv=atoi(str);
	    key=1;
	    }
	  if(((sw[0]=='-')||(sw[0]=='/'))&&((sw[1]=='o')||(sw[1]=='O'))){
	    j=0;
	    while(*(argv[i]+2+j)!=','){
	      str[j]=*(argv[i]+2+j);
	      j++;
	      }
	    str[j+1]='\0';
	    x=atoi(str);
	    strcpy(str,(argv[i]+3+j));
	    y=atoi(str);
	    }
	  if((sw[0]!='-')&&(sw[0]!='/')){
	    strcpy(filename,argv[i]);
	    fl++;
	    }
	  }

	if(key==0)kv=v;
	if(vl==0)v=kv;
	if(fl==0){
	  printf("*****************************************\n");
	  printf("**  非圧縮16色TIFFローダー  by N.Baba  **\n");
	  printf("*****************************************\n");
	  printf("TIFF.EXE [<options>] <filename>\n");
	  printf("  <options> -O<x,y> 表示開始位置を<x,y>にする \n");
	  printf("            -K<n>   キー入力待ち・キー入力待ち間の明るさ設定（<n>％）\n");
	  printf("            -V<n>   明るさ設定（<n>％）\n");
	  printf("  複数指定可 \n");
	  exit(0);
	  }

	j=0;
	while(filename[j]!='\0')j++;
	for(i=1;i<5;i++){
	  if((flg!=1)&&(filename[j-i]=='\\'))flg=-1;
	  if((flg!=-1)&&(filename[j-i]=='.'))flg=1;
	  }
	if(flg!=1)strcat(filename,".tif");

	printf("Filename : %s\n",filename);
	printf("開始位置  X:%d  Y:%d\n",x/8*8,y);

/*  graphic 表示  */
	j=open(filename,O_RDONLY | O_BINARY);
	if(j==-1){printf("\nFile name error !!...\a\n"); exit(0);}
	read(j,dat,512);
	  gx=((int)(dat[31])<<8)+(int)(dat[30]);
	  gy=((int)(dat[43])<<8)+(int)(dat[42]);
	  printf("X:%d * Y:%d \n",gx,gy);

	for(i=0;i<16;i++){
	  outp(0xfd90,i);

	  rr[i]=((int)(dat[256+i*2])>>4) & 0xf;
	  gg[i]=((int)(dat[288+i*2])>>4) & 0xf;
	  bb[i]=((int)(dat[320+i*2])>>4) & 0xf;

	  r=rr[i]*kv/100;
	  g=gg[i]*kv/100;
	  b=bb[i]*kv/100;

	  if(r>=15)r=15;
	  if(g>=15)g=15;
	  if(b>=15)b=15;
	  outp(0xfd92,b<<4);
	  outp(0xfd94,r<<4);
	  outp(0xfd96,g<<4);
	  }


	for(l=0;l<gy;l++){
	read(j,dat,(gx+1)/2);
	  for(m=0;m<(gx+1)/2;m+=4){
	    if((m*2+x<640)&&(m*2+x>=0)&&(l+y<400)&&(l+y>=0)){

	    c=1;
	    _asm{
	      push ds
	      mov ax,_seg
	      mov ds,ax
	      mov ah,c
	      mov bx,_off
	      mov [bx],ah
	      pop ds
	      }
	    c=((dat[m]&1)<<7)|((dat[m]&16)<<2)|((dat[m+1]&1)<<5)|((dat[m+1]&16))|((dat[m+2]&1)<<3)|((dat[m+2]&16)>>2)|((dat[m+3]&1)<<1)|((dat[m+3]&16)>>4);
	    *(plane + l*0x50 + m/4 +x/8+y*0x50)=c;

	    c=2;
	    _asm{
	      push ds
	      mov ax,_seg
	      mov ds,ax
	      mov ah,c
	      mov bx,_off
	      mov [bx],ah
	      pop ds
	      }
	    c=((dat[m]&2)<<6)|((dat[m]&32)<<1)|((dat[m+1]&2)<<4)|((dat[m+1]&32)>>1)|((dat[m+2]&2)<<2)|((dat[m+2]&32)>>3)|((dat[m+3]&2))|((dat[m+3]&32)>>5);
	    *(plane + l*0x50 + m/4 +x/8+y*0x50)=c;

	    c=4;
	    _asm{
	      push ds
	      mov ax,_seg
	      mov ds,ax
	      mov ah,c
	      mov bx,_off
	      mov [bx],ah
	      pop ds
	      }
	    c=((dat[m]&4)<<5)|((dat[m]&64))|((dat[m+1]&4)<<3)|((dat[m+1]&64)>>2)|((dat[m+2]&4)<<1)|((dat[m+2]&64)>>4)|((dat[m+3]&4)>>1)|((dat[m+3]&64)>>6);
	    *(plane + l*0x50 + m/4 +x/8+y*0x50)=c;

	    c=8;
	    _asm{
	      push ds
	      mov ax,_seg
	      mov ds,ax
	      mov ah,c
	      mov bx,_off
	      mov [bx],ah
	      pop ds
	      }
	    c=((dat[m]&8)<<4)|((dat[m]&128)>>1)|((dat[m+1]&8)<<2)|((dat[m+1]&128)>>3)|((dat[m+2]&8))|((dat[m+2]&128)>>5)|((dat[m+3]&8)>>2)|((dat[m+3]&128)>>7);
	    *(plane + l*0x50 + m/4 +x/8+y*0x50)=c;
	  }
	  }
	}
	close(j);

	if(key==1)getch();

	for(i=0;i<16;i++){
	  outp(0xfd90,i);

	  r=rr[i]*v/100;
	  g=gg[i]*v/100;
	  b=bb[i]*v/100;

	  if(r>=15)r=15;
	  if(g>=15)g=15;
	  if(b>=15)b=15;

	  outp(0xfd92,b<<4);
	  outp(0xfd94,r<<4);
	  outp(0xfd96,g<<4);
	  }
}

void setg(void)
{
int             _seg=0xc000,
		_off1=0xff82,
		_off2=0xff83,

/*  グラフィックの表示許可  */
	  c=0;                          /*  読み書きページセレクト  */
	  _asm{                         /*  c=0x00  =>  page0  */
	    push ds                     /*  c=0x10  =>  page1  */
	    mov ax,_seg
	    mov ds,ax
	    mov ah,BYTE ptr c
	    mov bx,_off2
	    mov [bx],ah
	    pop ds
	    }
	  c=0x40;                       /*  ディスプレイモード  */
	  _asm{                         /*    cの値             */
	    push ds                     /*  bit7 = 0    bit6 = 1         */
	    mov ax,_seg                 /*  bit5 = pl3  bit4 = 表示page  */
	    mov ds,ax                   /*  bit3 = 0    bit2 = pl2       */
	    mov ah,BYTE ptr c           /*  bit1 = pl1  bit0 = pl0       */
	    mov bx,_off1
	    mov [bx],ah
	    pop ds
	    }

	  c=0x67;                       /*  ディスプレイモード  */
	  _asm{                         /*    cの値             */
	    push ds                     /*  bit7 = 0    bit6 = 1         */
	    mov ax,_seg                 /*  bit5 = pl3  bit4 = 表示page  */
	    mov ds,ax                   /*  bit3 = 0    bit2 = pl2       */
	    mov ah,BYTE ptr c           /*  bit1 = pl1  bit0 = pl0       */
	    mov bx,_off1
	    mov [bx],ah
	    pop ds
	    }

}
