#include    <stdio.h>
#include    <stdlib.h>
#include    <stdarg.h>
#include    <string.h>
#include    <egb.h>
#include    <mos.h>
#include    <snd.h>
#include    <msdos.cf>
#include    "graphic.h"
#include    "coldef.h"

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

int	tick_timer=0;
int	now_mos=0;
char	work[EgbWorkSize];
char	mwork[MosWorkSize];
char	swork[16384];

static char	*timer_addr=NULL;
static struct _PLT {
	char	b,r,g;
    } plt_tbl[16]={
	{ 0x00,0x00,0x00 },{ 0x50,0xC0,0x40 },
	{ 0x40,0xC0,0x40 },{ 0x60,0x60,0x70 },
	{ 0x90,0x80,0x90 },{ 0x70,0x80,0x80 },
	{ 0x60,0x60,0x60 },{ 0xC0,0xC0,0xC0 },
	{ 0xD0,0xE0,0xD0 },{ 0x60,0x60,0x60 },
	{ 0x40,0xF0,0x40 },{ 0x70,0x70,0x90 },
	{ 0xA0,0x90,0xA0 },{ 0x90,0xA0,0xA0 },
	{ 0xB0,0xB0,0xB0 },{ 0xF0,0xF0,0xF0 }
    };

static char	mosptn[][66]={
	{ 2, 16,
	0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 
	0x30, 0x00, 0x58, 0x00, 0x3C, 0x00, 0x5E, 0x00, 
	0x2F, 0x00, 0x5F, 0x80, 0x2E, 0x00, 0x7C, 0x00, 
	0x66, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 
	0x7F, 0xFF, 0x3F, 0xFF, 0x5F, 0xFF, 0x6F, 0xFF, 
	0x37, 0xFF, 0x5B, 0xFF, 0x3D, 0xFF, 0x5E, 0xFF, 
	0x2F, 0x7F, 0x5F, 0xBF, 0x2E, 0x7F, 0x7D, 0xFF, 
	0x66, 0xFF, 0x16, 0xFF, 0x7B, 0x7F, 0xF8, 0x7F },
	{ 2, 16,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 
	0x05, 0x40, 0x05, 0x50, 0x15, 0x50, 0x15, 0x50, 
	0x1F, 0xF0, 0x1F, 0xF0, 0x1F, 0xF0, 0x0F, 0xF0, 
	0x07, 0xE0, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xBF, 0xF5, 0x5F, 
	0xF5, 0x4F, 0xE5, 0x57, 0xD5, 0x57, 0xD5, 0x57, 
	0xDF, 0xF7, 0xDF, 0xF7, 0xDF, 0xF7, 0xEF, 0xF7, 
	0xF7, 0xEF, 0xFB, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF },
	{ 2, 16,
	0x00, 0x00, 0x2F, 0xF4, 0x2F, 0xF4, 0x2F, 0xF4, 
	0x37, 0xEC, 0x39, 0x9C, 0x3C, 0x3C, 0x3E, 0x7C, 
	0x3E, 0x7C, 0x3D, 0xBC, 0x3B, 0xDC, 0x36, 0x6C, 
	0x2C, 0x34, 0x28, 0x14, 0x20, 0x04, 0x00, 0x00,
	0x00, 0x00, 0xAF, 0xF5, 0xAF, 0xF5, 0xAF, 0xF5, 
	0xB7, 0xED, 0xB9, 0x9D, 0xBC, 0x3D, 0xBE, 0x7D, 
	0xBE, 0x7D, 0xBD, 0xBD, 0xBB, 0xDD, 0xB6, 0x6D, 
	0xAC, 0x35, 0xA8, 0x15, 0xA0, 0x05, 0x00, 0x00 },
	{ 2, 16,
	0x03, 0x00, 0x03, 0x80, 0x02, 0xC0, 0x02, 0x40, 
	0x02, 0x40, 0x02, 0x00, 0x0E, 0x00, 0x1E, 0x00, 
	0x1E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x6A, 0xE0, 
	0x4A, 0xA0, 0x6A, 0xE0, 0x4A, 0x80, 0x6E, 0x80,
	0xFB, 0x7F, 0xFB, 0xBF, 0xFA, 0xDF, 0xFA, 0x5F, 
	0xFA, 0x5F, 0xE2, 0x9F, 0xCE, 0xFF, 0xDE, 0xFF, 
	0xDE, 0xFF, 0xCD, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
	{ 2, 16,
	0x00, 0x00, 0x07, 0x00, 0x08, 0x80, 0x0A, 0x40, 
	0x01, 0x40, 0x05, 0x40, 0x02, 0x40, 0x08, 0x40, 
	0x04, 0x80, 0x07, 0x00, 0x00, 0x00, 0x75, 0x60, 
	0x47, 0x50, 0x77, 0x50, 0x17, 0x50, 0x75, 0x60,
	0xF0, 0x7F, 0xF7, 0x7F, 0xE8, 0xBF, 0xEA, 0x5F, 
	0xE1, 0x5F, 0xE5, 0x5F, 0xE2, 0x5F, 0xE8, 0x5F, 
	0xF4, 0xBF, 0xF7, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } };

void	DSP_mos(int no)
{
    now_mos = no;
    MOS_type(1,0,0,mosptn[no]);
}
BLOCK	*DSP_push_vram(int x1,int y1,int x2,int y2)
{
    register BLOCK *para;
    int     n;

    n = ((x2 - x1 + 8) / 8 * 4) * (y2 - y1 + 1) + 16;	/* 4 Bit Pix */

    if ( (para = (BLOCK *)malloc(n)) == NULL )
	return NULL;

    para->ptn = para->img;
    para->sel = getds();
    para->x1 = x1;
    para->y1 = y1;
    para->x2 = x2;
    para->y2 = y2;
    EGB_getBlock(work,(char *)para);
    return para;
}
void	DSP_pop_vram(BLOCK *para)
{
    if ( para == NULL )
	return;
    EGB_putBlock(work,0,(char *)para);
    free(para);
}
void	DSP_putptn(char *ptn,int x1,int y1,int x2,int y2,
			int fc,int bc,int md)
{
    BLOCK para;

    para.ptn = ptn;
    para.sel = getds();
    para.x1 = x1;
    para.y1 = y1;
    para.x2 = x2;
    para.y2 = y2;
    EGB_color(work,0,fc);
    EGB_color(work,1,bc);
    EGB_writeMode(work,md);
    EGB_putBlockColor(work,0,(char *)(&para));
    EGB_writeMode(work,0);
}
void	DSP_msg(char *str,int x,int y,int font,int fc,int bc,int mod)
{
    struct {
	short int	x,y;
	short int	len;
	char		str[120];
    } msg;

    msg.x = x;
    msg.y = y + 15;
    msg.len = strlen(str);
    strcpy(msg.str,str);

    EGB_textSpace(work,0);
    EGB_fontStyle(work,font);
    EGB_color(work,0,fc);
    EGB_color(work,1,bc);
    EGB_writeMode(work,mod);
    EGB_sjisString(work,(char *)&msg);
}
void	DSP_line(int x1,int y1,int x2,int y2,int col,int mod)
{
    struct {
	short int	x1,y1,x2,y2;
    } line;

    line.x1 = x1;
    line.y1 = y1;
    line.x2 = x2;
    line.y2 = y2;
    EGB_paintMode(work,0x002);
    EGB_color(work,0,col);
    EGB_writeMode(work,mod);
    EGB_rectangle(work,(char *)&line);
    EGB_writeMode(work,0);
}
void	DSP_box(int x1,int y1,int x2,int y2,int col,int mod)
{
    struct {
	short int	x1,y1,x2,y2;
    } line;

    line.x1 = x1;
    line.y1 = y1;
    line.x2 = x2;
    line.y2 = y2;
    EGB_paintMode(work,0x022);
    EGB_color(work,0,col);
    EGB_color(work,2,col);
    EGB_writeMode(work,mod);
    EGB_rectangle(work,(char *)&line);
    EGB_writeMode(work,0);
}
void	DSP_rbox(int x1,int y1,int x2,int y2,int lin,int col,int mod)
{
    struct {
	short int	x1,y1,x2,y2;
    } line;

    line.x1 = x1;
    line.y1 = y1;
    line.x2 = x2;
    line.y2 = y2;
    EGB_paintMode(work,0x022);
    EGB_color(work,0,lin);
    EGB_color(work,2,col);
    EGB_writeMode(work,mod);
    EGB_rectangle(work,(char *)&line);
    EGB_writeMode(work,0);
}
void	DSP_wbox(int x1,int y1,int x2,int y2,int lin,int col,int mod)
{
    struct {
	short int	point;
	short int	trx2,try2;
	short int	trx3,try3;
	short int	brx1,bry1;
	short int	brx2,bry2;
	short int	brx3,bry3;
	short int	blx1,bly1;
	short int	blx2,bly2;
	short int	blx3,bly3;
	short int	tlx1,tly1;
	short int	tlx2,tly2;
	short int	tlx3,tly3;
	short int	trx1,try1;
    } poly;

    poly.point = 12;

    poly.tlx1 = x1+0; poly.tlx2 = x1+1; poly.tlx3 = x1+2;
    poly.tly1 = y1+2; poly.tly2 = y1+1; poly.tly3 = y1+0;

    poly.trx1 = x2-2; poly.trx2 = x2-1; poly.trx3 = x2+0;
    poly.try1 = y1+0; poly.try2 = y1+1; poly.try3 = y1+2;

    poly.brx1 = x2+0; poly.brx2 = x2-1; poly.brx3 = x2-2;
    poly.bry1 = y2-2; poly.bry2 = y2-1; poly.bry3 = y2+0;

    poly.blx1 = x1+2; poly.blx2 = x1+1; poly.blx3 = x1+0;
    poly.bly1 = y2-0; poly.bly2 = y2-1; poly.bly3 = y2-2;

    EGB_paintMode(work,0x022);
    EGB_color(work,0,lin);
    EGB_color(work,2,col);
    EGB_writeMode(work,mod);
    EGB_polygon(work,(char *)&poly);

    poly.point = 7;
    EGB_paintMode(work,0x002);
    EGB_color(work,0,lin ^ 0x08);
    EGB_connect(work,(char *)&poly);

    EGB_writeMode(work,0);
}
void	DSP_vsync(void)
{
    while ( (peek(0xFDA0) & 1) != 0 );
    while ( (peek(0xFDA0) & 1) == 0 );
}
void	DSP_opbox(int x1,int y1,int x2,int y2)
{
    int     i;
    int     ix1,iy1,ix2,iy2;
    int     sx1,sy1,sx2,sy2;

    ix1 = (x1 + x2) / 2 - 8;
    ix2 = ix1 + 15;
    iy1 = (y1 + y2) / 2 - 8;
    iy2 = iy1 + 15;

    sx1 = (ix1 - x1) / 10;
    sy1 = (iy1 - y1) / 10;
    sx2 = (x2 - ix2) / 10;
    sy2 = (y2 - iy2) / 10;

    for ( i = 10 ; i >= 0 ; i-- ) {
	DSP_line(ix1,iy1,ix2,iy2,15,4);
	DSP_vsync();
	DSP_line(ix1,iy1,ix2,iy2,15,4);
	ix1 -= sx1;
	iy1 -= sy1;
	ix2 += sx2;
	iy2 += sy2;
    }
}
void	DSP_clbox(int x1,int y1,int x2,int y2)
{
    int     i;
    int     ix1,iy1,ix2,iy2;
    int     sx1,sy1,sx2,sy2;

    ix1 = (x1 + x2) / 2 - 8;
    ix2 = ix1 + 15;
    iy1 = (y1 + y2) / 2 - 8;
    iy2 = iy1 + 15;

    sx1 = (ix1 - x1) / 10;
    sy1 = (iy1 - y1) / 10;
    sx2 = (x2 - ix2) / 10;
    sy2 = (y2 - iy2) / 10;

    for ( i = 10 ; i >= 0 ; i-- ) {
	DSP_line(x1,y1,x2,y2,15,4);
	DSP_vsync();
	DSP_line(x1,y1,x2,y2,15,4);
	x1 += sx1;
	y1 += sy1;
	x2 -= sx2;
	y2 -= sy2;
    }
}
void	TICK_count(void)
{
    tick_timer++;
    SND_fm_timer_a_start();
}
void	DSP_palette(void)
{
    struct {
	int	cnt;
	int	col;
	char	b,r,g;
	char	btm;
    } para;
    int     i;

    for ( i = 0 ; i < 16 ; i++ ) {
	para.cnt = 1;
	para.col = i;
	para.b = plt_tbl[i].b;
	para.r = plt_tbl[i].r;
	para.g = plt_tbl[i].g;
	para.btm = 0;
        EGB_palette(work,0,(char *)&para);
    }
}

#define HSW1	0
#define HSW2	1
#define HST 	4
#define CR1 	29
#define HDS0	9
#define HDE0	10
#define HDS1	11
#define HDE1	11
#define HAJ0	18
#define HAJ1	22

#define	CRTC(r,n)	vram_offset(r,n)

void	DSP_init(void)
{
    SND_init(swork);
    SND_elevol_mute(0xB3);

    timer_addr = SND_int_timer_a_get();
    SND_int_timer_a_set((char *)TICK_count);
    SND_fm_timer_a_set(1,900);

    EGB_init(work,EgbWorkSize);
    EGB_resolution(work,0,3);
    EGB_resolution(work,1,3);
    EGB_displayPage(work,0,3);
    EGB_writePage(work,1);
    DSP_palette();
    EGB_writePage(work,0);
    DSP_palette();

    MOS_start(mwork,MosWorkSize);
    MOS_resolution(0,3);
    MOS_resolution(1,3);
    MOS_writePage(0);
    MOS_horizon(0,632);
    MOS_vertical(0,470);
    DSP_mos(MOS_NOMAL);
    MOS_disp(TRUE);
    ctblset(15,SCRN_COL);
}
void	DSP_end(void)
{
    SND_fm_timer_a_set(0,900);
    SND_int_timer_a_set(timer_addr);
    MOS_end();
    SND_elevol_mute(0x00);
    SND_end();
}
void	gprintf(int x,int y,int c,int b,char *form,...)
{
    va_list arg;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    wrtstr(tmp,0,x,y,c,b,16);
    va_end(arg);
}
void	gputs(int x,int y,int c,int b,char *str)
{
    wrtstr(str,0,x,y,c,b,16);
}
void	DSP_offset(int page,int x,int y)
{
    vram_offset((page == 0 ? 17:21),x/8+y*128);
}
void	DSP_clear(int no)
{
    EGB_writePage(work,no);
    EGB_color(work,1,0);
    EGB_clearScreen(work);
    EGB_writePage(work,0);
}
void	DSP_page(int no)
{
    EGB_writePage(work,no);
}
#include    "sysicon.c"

int	ESR_setupInfo(char *out_buf);

char	drv_tbl[]={
	IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,
	IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,
	IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON,IS_NON };

void	ICON_init(void)
{
    int     i;
    char    tmp[256];

    ESR_setupInfo((char *)tmp);
    for ( i = 0 ; i < 16 ; i++ )
	drv_tbl[i] = tmp[0x30 + i * 2];
    drv_tbl[2] = IS_NON;			/* C: drive delete */
    drv_tbl[16] = IS_CDR;			/* Q: drive apend */
}
void	ICON_disp(int x,int y,int drv)
{
    DSP_rbox(x,y,x+33,y+33,LINE_COL,WIND_COL,M_PSET);
    if ( drv_tbl[drv] <= IS_CDR )
	DSP_putptn(ICON_ptn[drv_tbl[drv]],x+1,y+1,x+32,y+32,
				CHR_COL,WIND_COL,M_PSET);
    else
	gprintf(x+12,y+12,CHR_COL,WIND_COL,"%d",drv_tbl[drv]);
    DSP_box(x+2,y+2,x+15,y+14,WIND_COL,M_PSET);
    DSP_putptn(DIGIT_ptn[drv],x+2,y+2,x+15,y+14,CHR_COL,WIND_COL,M_PSET);
}

/********************************************************************

	Palette Control

	0	  1	    2	      3		4	  5
	0123456789012345678901234567890123456789012345678901234567890
0	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
1	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
2	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
3	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
4	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
5	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
6	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >
7	■  < 00 >  < 00 >  < 00 >	■  < 00 >  < 00 >  < 00 >

********************************************************************/

#define	PLT_X	80
#define	PLT_Y	140

#define	PLT_X1	PLT_X-8
#define	PLT_Y1	PLT_Y-40
#define	PLT_X2	PLT_X+480
#define	PLT_Y2	PLT_Y+192

void	PLT_node(int col)
{
    int     x,y;
    struct {
	int	cnt;
	int	col;
	char	b,r,g;
	char	btm;
    } para;
    
    MOS_disp(0);

    x = PLT_X + (col / 8) * 256;
    y = PLT_Y + (col % 8) * 22;

    DSP_wbox(x,y,x+19,y+19,LINE_COL,col,M_PSET);

    DSP_wbox(x+32,y,x+32+11,y+19,LINE_COL,WIND_COL,M_PSET);
    gputs(x+32+2,y+2,CHR_COL,WIND_COL,"<");
    DSP_wbox(x+72,y,x+72+11,y+19,LINE_COL,WIND_COL,M_PSET);
    gputs(x+72+2,y+2,CHR_COL,WIND_COL,">");

    DSP_wbox(x+96,y,x+96+11,y+19,LINE_COL,WIND_COL,M_PSET);
    gputs(x+96+2,y+2,CHR_COL,WIND_COL,"<");
    DSP_wbox(x+136,y,x+136+11,y+19,LINE_COL,WIND_COL,M_PSET);
    gputs(x+136+2,y+2,CHR_COL,WIND_COL,">");

    DSP_wbox(x+160,y,x+160+11,y+19,LINE_COL,WIND_COL,M_PSET);
    gputs(x+160+2,y+2,CHR_COL,WIND_COL,"<");
    DSP_wbox(x+200,y,x+200+11,y+19,LINE_COL,WIND_COL,M_PSET);
    gputs(x+200+2,y+2,CHR_COL,WIND_COL,">");

    gprintf(x+48+2,y+2,CHR_COL,WIND_COL,"%02d",plt_tbl[col].b/16);
    gprintf(x+112+2,y+2,CHR_COL,WIND_COL,"%02d",plt_tbl[col].r/16);
    gprintf(x+176+2,y+2,CHR_COL,WIND_COL,"%02d",plt_tbl[col].g/16);

    para.cnt = 1;
    para.col = col;
    para.b = plt_tbl[col].b;
    para.r = plt_tbl[col].r;
    para.g = plt_tbl[col].g;
    para.btm = 0;
    EGB_palette(work,0,(char *)&para);

    MOS_disp(1);
}
void	PLT_chk(int mx,int my,int col)
{
    int     x,y;

    x = PLT_X + (col / 8) * 256;
    y = PLT_Y + (col % 8) * 22;

    if      ( (mx >= (x+32)) && (my >= y) && 
	      (mx <= (x+32+11)) && (my <= (y+19)) )
	plt_tbl[col].b = (plt_tbl[col].b - 0x10) & 0xF0;

    else if ( (mx >= (x+72)) && (my >= y) && 
	      (mx <= (x+72+11)) && (my <= (y+19)) )
	plt_tbl[col].b = (plt_tbl[col].b + 0x10) & 0xF0;

    else if ( (mx >= (x+96)) && (my >= y) && 
	      (mx <= (x+96+11)) && (my <= (y+19)) )
	plt_tbl[col].r = (plt_tbl[col].r - 0x10) & 0xF0;

    else if ( (mx >= (x+136)) && (my >= y) && 
	      (mx <= (x+136+11)) && (my <= (y+19)) )
	plt_tbl[col].r = (plt_tbl[col].r + 0x10) & 0xF0;

    else if ( (mx >= (x+160)) && (my >= y) && 
	      (mx <= (x+160+11)) && (my <= (y+19)) )
	plt_tbl[col].g = (plt_tbl[col].g - 0x10) & 0xF0;

    else if ( (mx >= (x+200)) && (my >= y) && 
	      (mx <= (x+200+11)) && (my <= (y+19)) )
	plt_tbl[col].g = (plt_tbl[col].g + 0x10) & 0xF0;

    else
	return;

    PLT_node(col);
}
void	PLT_control(void)
{
    int     n,i;
    int     x,y,sw;
    BLOCK   *vp;

    MOS_disp(0);
    vp = DSP_push_vram(PLT_X1,PLT_Y1,PLT_X2,PLT_Y2);
    DSP_opbox(PLT_X1,PLT_Y1,PLT_X2,PLT_Y2);
/****
    DSP_wbox(PLT_X1,PLT_Y1,PLT_X2,PLT_Y2,LINE_COL,WIND_COL,M_PSET);
*****/
    DSP_wbox(PLT_X1+8,PLT_Y1+8,PLT_X1+38,PLT_Y1+27,LINE_COL,WIND_COL,M_PSET);
    gputs(PLT_X1+10,PLT_Y1+10,CHR_COL,WIND_COL,"END");
    MOS_disp(1);

    for ( i = 0 ; i < 16 ; i++ )
	PLT_node(i);

    for ( ; ; ) {
	MOS_rdpos(&sw,&x,&y);

	if ( (sw == 0)    ||
	     (x < PLT_X1) || (y < PLT_Y1) ||
	     (x > PLT_X2) || (y > PLT_Y2) )
	    continue;

	else if ( (x >= (PLT_X1+8))  && (y >= (PLT_Y1+8)) &&
	          (x <= (PLT_X1+38)) && (y <= (PLT_Y1+27)) )
	    break;

	else {
	    for ( i = 0 ; i < 16 ; i++ )
	        PLT_chk(x,y,i);
	}

	do {
	    MOS_rdpos(&sw,&x,&y);
	} while ( sw != 0 );
    }

    MOS_disp(0);
    DSP_pop_vram(vp);
    MOS_disp(1);
}

/****************************************************

	TIFF Graphic Display and SND or EUP Play

*****************************************************/
char    *getins(env,file)
char	*env,*file;
{
    static char tmp[128];
    char *p;

    if ( (p = getenv(env)) == NULL )
	return NULL;
    sprintf(tmp,"%s\\%s",p,file);
    return tmp;
}
char	*xopen(char *file)
{
    FILE    *fp;
    long    fsz;
    char    *buf;

    if( (fp = fopen(file,"rb")) == NULL )
	return NULL;

    fseek(fp,0L,SEEK_END);
    fsz = ftell(fp);
    rewind(fp);

    if( (buf = (char *)malloc(fsz)) == NULL)
	goto ERROR;

    fread(buf,fsz,1,fp);

ERROR:
    fclose(fp);
    return buf;
}
void	xclose(char *buf)
{
    free(buf);
}
void	DSP_tiff(char *file)
{
    int	    l,n;
    int     sw,x,y;
    int     len,lzw,plt;
    BLOCK   para;
    BLOCK   *save;
    char    *buf;
    short   *rp,*gp,*bp;
    struct _TIF {
	short	tf_tag;
	short	tf_type;
	int	tf_len;
	int	tf_data;
    } *ifd;
    struct {
	int	cnt;
	int	col;
	char	b,r,g;
	char	btm;
    } plpara;

    if ( (buf = xopen(file)) == NULL ) {
	kakunin("TIFFファイルの読み込みに失敗しました");
	return;
    }

    if ( buf[0] != 0x49 || buf[1] != 0x49 || buf[2] != 0x2A ) {
	kakunin("このファイルはTIFF形式ではありません？");
	goto ENDOF;
    }

    x = y = len = plt = 0;
    lzw = 1;
    n = WORD(buf + DWORD(buf+4));
    ifd = (struct _TIF *)(buf + DWORD(buf+4) + 2);

    while ( n-- > 0) {
	if ( ifd->tf_tag == 0 )
	    break;
	switch(ifd->tf_tag){
	case 0x0100: x = ifd->tf_data; break;
	case 0x0101: y = ifd->tf_data; break;
	case 0x0102: len = ifd->tf_data; break;
	case 0x0103: lzw = ifd->tf_data; break;
	case 0x0140: plt = ifd->tf_data; break;
	case 0x0111: l = ifd->tf_data; break;
	}
	ifd++;
    }

    if ( lzw != 1 ) {
	kakunin("残念ながら圧縮TIFFに対応してません");
	goto ENDOF;
    }
    if ( len != 1 && len != 4 && len != 8 && len != 16 ) {
	kakunin("対応していないピクセルモ−ドです");
	goto ENDOF;
    }

    para.ptn = buf + l;
    para.sel = getds();
    para.x1 = 0;
    para.y1 = 0;
    para.x2 = x-1;
    para.y2 = y-1;

    MOS_disp(OFF);
    save = DSP_push_vram(0,0,639,479);
    EGB_displayPage(work,0,0);

    switch(len) {
    case 1:
        EGB_resolution(work,0,3);
	EGB_writePage(work,0);
	EGB_clearScreen(work);
	EGB_color(work,0,15);
	EGB_putBlockColor(work,0,(char *)&para);
	break;

    case 4:
        EGB_resolution(work,0,3);
	EGB_writePage(work,0);
	EGB_clearScreen(work);
	EGB_putBlock(work,0,(char *)&para);
	if ( plt != 0 ) {
	    rp = (short *)(buf + plt);
	    gp = (short *)(buf + plt + 32);
	    bp = (short *)(buf + plt + 64);
	    for ( n = 0 ; n < 16 ; n++ ) {
		plpara.cnt = 1;
		plpara.col = n;
		plpara.b = *(bp++);
		plpara.r = *(rp++);
		plpara.g = *(bp++);
		plpara.btm = 0;
		EGB_palette(work,0,(char *)&plpara);
	    }
	}
	break;

    case 8:
	EGB_resolution(work,0,12);
	EGB_clearScreen(work);
	EGB_putBlock(work,0,(char *)&para);
	if ( plt != 0 ) {
	    rp = (short *)(buf + plt);
	    gp = (short *)(buf + plt + 512);
	    bp = (short *)(buf + plt + 1024);
	    for ( n = 0 ; n < 256 ; n++ ) {
		plpara.cnt = 1;
		plpara.col = n;
		plpara.b = *(bp++);
		plpara.r = *(rp++);
		plpara.g = *(bp++);
		plpara.btm = 0;
		EGB_palette(work,0,(char *)&plpara);
	    }
	}
	break;

    case 16:
        EGB_resolution(work,0,10);
	EGB_writePage(work,0);
	EGB_clearScreen(work);
	EGB_displayStart(work,2,2,2);
	EGB_displayStart(work,3,320,240);
	EGB_putBlock(work,0,(char *)&para);
	break;

    }

    EGB_displayPage(work,0,1);

    do {
	MOS_rdpos(&sw,&x,&y);
    } while ( sw == 0 );

    EGB_displayPage(work,0,0);
    EGB_resolution(work,0,3);
    EGB_resolution(work,1,3);
    EGB_writePage(work,1);
    DSP_palette();
    EGB_clearScreen(work);
    EGB_writePage(work,0);
    DSP_palette();
    EGB_clearScreen(work);
    DSP_pop_vram(save);
    EGB_displayPage(work,0,3);
    MOS_disp(ON);

ENDOF:
    xclose(buf);
}
void	DSP_pxx(char *file)
{
    int     n;
    int     sw,x,y;
    int     objs;
    int     plat;
    int     mode;
    long    size;
    short   *sp;
    char    *data;
    char    *buf;
    BLOCK   para;
    BLOCK   *save;
    struct {
	int	cnt;
	int	col;
	char	b,r,g;
	char	btm;
    } plpara;

    if ( (buf = xopen(file)) == NULL ) {
	kakunin("Pxxファイルの読み込みに失敗しました");
	return;
    }

    if ( buf[0] != 0x59 || buf[1] != 0x55 || 
	 buf[2] != 0x4B || buf[3] != 0x49 ) {
	kakunin("このファイルはPxx形式ではありません？");
	goto ENDOF;
    }

    objs = WORD(buf + 0x10);
    mode = WORD(buf + 0x12);	/* 3 or 12 or 10 */
    plat = (mode == 3 ? 96:(mode == 12 ? 1536:448));
    data = buf + 0x18 + plat;

    if ( mode != 3 && mode != 12 && mode != 10 ) {
	kakunin("対応していない画面モ−ドです");
	goto ENDOF;
    }

    MOS_disp(OFF);
    save = DSP_push_vram(0,0,639,479);
    EGB_displayPage(work,0,0);
    EGB_resolution(work,0,mode);
    EGB_writePage(work,0);
    EGB_clearScreen(work);
    if ( mode == 10 ) {
	EGB_displayStart(work,2,2,2);
	EGB_displayStart(work,3,320,240);
    } else {
	sp = (short *)(buf + 0x18);
	for ( n = 0 ; n < (plat / 6) ; n++ ) {
	    plpara.cnt = 1;
	    plpara.col = n;
	    plpara.r = *(sp++) >> 8;
	    plpara.g = *(sp++) >> 8;
	    plpara.b = *(sp++) >> 8;
	    plpara.btm = 0;
	    EGB_palette(work,0,(char *)&plpara);
	}
    }

    EGB_displayPage(work,0,1);
    para.sel = getds();

    while ( objs-- > 0 ) {
	if ( WORD(data) == 0 ) {	/* Haikei */
	    size = DWORD(data + 2);
	    para.x1 = WORD(data + 6);
	    para.y1 = WORD(data + 8);
	    para.x2 = WORD(data + 10);
	    para.y2 = WORD(data + 12);
	    para.ptn = data + 14;
	    EGB_putBlock(work,0,(char *)&para);
	    data += (14 + size);

	} else {			/* Object */
	    size = DWORD(data + 2) + DWORD(data + 6);
	    para.x1 = WORD(data + 10);
	    para.y1 = WORD(data + 12);
	    para.x2 = WORD(data + 14);
	    para.y2 = WORD(data + 16);
	    para.ptn = data + 18;
	    EGB_maskData(work,2,(char *)&para);
	    data += (18 + size);
	}

    }

    do {
	MOS_rdpos(&sw,&x,&y);
    } while ( sw == 0 );

    EGB_displayPage(work,0,0);
    EGB_resolution(work,0,3);
    EGB_resolution(work,1,3);
    EGB_writePage(work,1);
    DSP_palette();
    EGB_clearScreen(work);
    EGB_writePage(work,0);
    DSP_palette();
    EGB_clearScreen(work);
    DSP_pop_vram(save);
    EGB_displayPage(work,0,3);
    MOS_disp(ON);

ENDOF:
    xclose(buf);
}
void	PLAY_snd(file)
char	*file;
{
    int     sw,x,y;
    char    *snd_buf;

    SND_pcm_sound_delete(-1);
    SND_pcm_mode_set(1);

    if ( (snd_buf = xopen(file)) == NULL ) {
	kakunin("SNDファイルの読み込みに失敗しました");
	return;
    }

    SND_pan_set(71,64);
    *(int *)(snd_buf+20) = 0;
    SND_pcm_play(71,snd_buf[28],127,snd_buf);

    while ( SND_pcm_status(71) ) {
	MOS_rdpos(&sw,&x,&y);
	if ( sw != 0 )
	    break;
    }

    SND_pcm_play_stop(71);
    SND_pcm_rec_stop();
    xclose(snd_buf);
}
void	PLAY_eup(file)
char	*file;
{
    int     i;
    int     sw,x,y;
    int     err,size,signa,tempo;
    char    *p;
    char    *eup_buf;
    char    tmp[16];
    char    dmy[16];
    char    wrk[80];

    if( (eup_buf = xopen(file)) == NULL ) {
	kakunin("EUPファイルの読み込みに失敗しました");
	return;
    }

    SND_eup_init(swork);
    SND_elevol_mute(0xB3);

    p = &eup_buf[852];		/* trk mute */
    for( i = 0 ; i < 32 ; i++ )
	err = SND_eup_mute_set(i,*(p++));

    p = &eup_buf[884];		/* trk port */
    for( i = 0 ; i < 32 ; i++ )
	err = SND_eup_port_set(i,*(p++));

    p = &eup_buf[916];		/* trk midi ch */
    for( i = 0 ; i < 32 ; i++ )
	err = SND_eup_midi_ch_set(i,*(p++));

    p = &eup_buf[948];		/* trk key bias */
    for( i = 0 ; i < 32 ; i++ )
	err = SND_eup_bias_set(i,*(p++));

    p = &eup_buf[980];		/* trk transpose */
    for( i = 0 ; i < 32 ; i++ )
	err = SND_eup_transpose_set(i,*(p++));

/********************
    channel assign
*********************/

    p = &eup_buf[1748];		/* fm midi ch */
    for( i = 0 ; i < 6 ; i++ )
	err = SND_midi_ch_assign(i,*(p++));

    p = &eup_buf[1754];		/* pcm midi ch */
    for( i = 0 ; i < 8 ; i++ )
	err = SND_midi_ch_assign(i+64,*(p++));

/****************
    bank load
*****************/

    SND_pcm_mode_set(0);

    strncpy(tmp,&eup_buf[1762],8);	/* fm file name */
    tmp[8] = '\0';
    if ( tmp[0] != '\0' ) {
	strcat(tmp,".FMB");
	strcpy(wrk,file);
	if ( (p = strrchr(wrk,'\\')) != NULL ) {
	    strcpy(p+1,tmp);
	    p = wrk;
	} else
	    p = tmp;
	p = tmp;
    	if ( SND_fm_bank_load(p,dmy) != 0 ) {
	    if ( (p = getins("FMINST",tmp)) != NULL )
		 SND_fm_bank_load(p,dmy);
	}
    }

    strncpy(tmp,&eup_buf[1770],8);	/* pcm file name */
    tmp[8] = '\0';
    if ( tmp[0] != '\0' ) {
	strcat(tmp,".PMB");
	strcpy(wrk,file);
	if ( (p = strrchr(wrk,'\\')) != NULL ) {
	    strcpy(p+1,tmp);
	    p = wrk;
	} else
	    p = tmp;
	p = tmp;
    	if ( SND_pcm_bank_load(p,dmy) != 0 ) {
	    if ( (p = getins("PCMINST",tmp)) != NULL )
		 SND_pcm_bank_load(p,dmy);
	}
    }

/*******************
    play eup file
********************/

    p = &eup_buf[2048];		/* data top */
    size = *((int *)p); p += 4;
    signa = *(p++);
    tempo = *(p++);

    SND_eup_loop_set(0);
    SND_eup_tempo_set(tempo);
    SND_eup_play_start(p,size,signa);

    while ( SND_eup_stat_flag() ) {
	MOS_rdpos(&sw,&x,&y);
	if ( sw != 0 )
	    break;
    }

    SND_eup_play_stop();
    SND_eup_end();
    xclose(eup_buf);
}
int	JOKE_run(char *file)
{
    char    *p;

    if ( (p = strrchr(file,'\\')) == NULL )
	p = file;
    if ( (p = strrchr(p,'.')) == NULL )
	return FALSE;

    if ( strcmp(p,".TIF") == 0 )
	DSP_tiff(file);
    else if ( strcmp(p,".P16") == 0 ||
	      strcmp(p,".P25") == 0 ||
	      strcmp(p,".P32") == 0 )
	DSP_pxx(file);
    else if ( strcmp(p,".SND") == 0 )
	PLAY_snd(file);
    else if ( strcmp(p,".EUP") == 0 )
	PLAY_eup(file);
    else
	return FALSE;

    return TRUE;
}
