/*
 *		Mac Paint file Loader
 *                                        (C) 1989-1991 Waku Factory
 */
 
#include <stdio.h>
#include <egb.h>
#include <mos.h>
#include <snd.h>
#include <msdos.cf>
#include "crtc.h"

#define PIXWIDTH 576
#define PIXHEIGHT 720
#define PIXDWORD (PIXWIDTH/8)
#define VHO 16

static char name[] = "Mac-Paint Loader V1.0   (C) 1989-1991 Waku Factory" ;

char lbuf[ PIXDWORD ] ;

char work[1536] ;
char mwork[4096] ;
unsigned long pixbuf[PIXDWORD*PIXHEIGHT] ;
int headsize ;

long table[256] ;
void mktable()
{
	int i,j,b ;
	unsigned long p ;
	for( i = 0 ; i < 256 ; i++ ) {
		p = 0 ;
		b = i ;
		for( j = 0 ; ; j++ ) {
			if( b & 1 ) p += 0xF ;
			if( j == 7 ) break ;
			b >>= 1 ;
			p <<= 4 ;
		}
		table[i] = p ;
	}
}


void setsmode( )
{
	EGB_init( work, 1536 ) ;
	EGB_resolution( work, 0, 3 ) ;
	EGB_displayPage( work, 1, 3 ) ;
	MOS_start( mwork, 4096 ) ;
	SND_elevol_init() ;		 /* cd mute off */
	SND_elevol_set( 1,127,127 ) ;
	MOS_writePage( 1 ) ;
	MOS_color( 0, 8 ) ;
	MOS_vertical( 0, 479 ) ;
	MOS_horizon( 0, 639 ) ;

	putstr( 40, 477, "Waku Factory" ) ;

	MOS_disp( 1 ) ;
/*
	CRTC( CA_LO0, LOFS/8 ) ;
	CRTC( CA_HDE0, 714 ) ;
*/
}

putstr( x,y, str )
int x,y ;
char *str ;
{
	struct {
		short x,y,len ;
		char s[80] ;
	} p ;
	
	p.x = x ;
	p.y = y ;
	p.len = strlen( str ) ;
	strcpy( p.s, str ) ;
	EGB_sjisString( work, (char *)&p ) ;
}


int fl = 0 ;
void rollup( l )
int l ;
{
	if( (fl += l) > 511 ) fl -= 512 ;
	CRTC( CA_FA0, (1024/8) * fl ) ;
}

void rolldown( l )
int l ;
{
	if( (fl -= l) < 0 ) fl += 512 ;
	CRTC( CA_FA0, (1024/8) * fl ) ;
}


int getimage( sfp ) 
FILE *sfp ;
{
	int l,x,cnt,ch ;
	 	
	fseek( sfp, headsize, SEEK_SET ) ;
	
	for( l = 0 ; l < PIXHEIGHT ; l++ ) {
		x = cnt = 0 ;
		while( (ch = getc( sfp )) != EOF ) {
			ch &= 0xFF ;
			if( cnt-- == 0 )
				if( ch < 72 ) {
					cnt = ch + 1 ;
				}
				else {
					cnt = 257 - ch ;
					ch = getc( sfp ) ^ 0xFF ;
					while( cnt-- > 0 ) {
						lbuf[x++] = ch ;
						if( x == 72 ) goto exit ;
					}
					cnt = 0 ;
				}
			else {
				lbuf[x++] = ch ^ 0xFF ;
				if( x == 72 ) goto exit ;
			}
		}
	exit:	
		putlbuf( l ) ;
	}
}

putlbuf( l )
int l ;
{
	short w[8] ;
	int i,ofs ;

	ofs = l * PIXDWORD ;
	for( i = 0 ; i < PIXDWORD ; i++ ) {
		pixbuf[ofs+i] = table[ lbuf[i] ] ;
	}
}

int scroll()
{
	unsigned long *p ;
	int ofs, b, x, y ;
	int uofs,dofs ;
	
	p = pixbuf ;
	ofs = 0 ;
	for( y = 0 ; y < 480 ; y++ ) {
		for( x = 0 ; x < PIXDWORD ; x++,p++ ){
			putVRAMd( ofs+VHO, *p, 0x104 ) ;
			ofs += 4 ;
		}
		ofs += (1024 - PIXWIDTH)/2 ;
	}
	uofs = 0 ;
	dofs = 479 ;
	for(;;) {
		MOS_rdpos( &b,&x,&y ) ;
		if( b != 0 ) break ;
		if( (y == 0) && (uofs != 0) ) {
			rolldown( 1 ) ;
			--dofs ;
			p = &pixbuf[(--uofs) * PIXDWORD] ;
			b = fl * 1024/2 ;
			for( ofs = b ; ofs < b + PIXWIDTH/2 ; ofs+=4 )
				putVRAMd( ofs+VHO, *p++ , 0x104 ) ;
		} else if( (y == 479) && (dofs != (PIXHEIGHT-1))) {
			rollup( 1 ) ;
			++uofs ;
			p = &pixbuf[(++dofs) * PIXDWORD] ;
			b = ((fl + 479)*1024/2) & 0x3FFFF ;
			for( ofs=b ; ofs < b + PIXWIDTH/2 ; ofs+=4 )
				putVRAMd( ofs+VHO, *p++, 0x104 ) ;
		}
	}
	while( uofs ) {
		rolldown( 1 ) ;
		p = &pixbuf[(--uofs) * PIXDWORD] ;
		b = fl * 1024/2 ;
		for( ofs = b ; ofs < b + PIXWIDTH/2 ; ofs+=4 )
			putVRAMd( ofs+VHO, *p++ , 0x104 ) ;
	}
	return b ;
}

void main(ac,av) 
char **av ;
int ac ;
{
	FILE *fp ;
	int i,r ;
	
	mktable() ;
	setsmode() ;

	r = 1 ;
	headsize = 512 + 128 ;
	if( *av[1] == '-' && *(av[1]+1) == 'r' ) {
		headsize = 512 ;
		r++ ;
	}
	i = r ;
	for( ; ; ) {
		if( (fp = fopen( av[i], "rb" )) == NULL )
			 continue ;
		getimage( fp ) ;
		fclose( fp ) ;
		if( scroll() == 2 ) break ;
		if( ac == r+1 ) break ; 
		if( ++i == ac ) i = r ;
	}
	MOS_end() ;
}
