WinUAE/prowizard/rippers/GnuPlayer.c
2010-02-22 21:46:52 +02:00

328 lines
8.9 KiB
C

/* 22 mar 2003
* GnuPlayer.c
* based on XtC's description ! ... good job ! :).
*
*/
/* testGnuPlayer() */
/* Rip_GnuPlayer() */
/* Depack_GnuPlayer() */
#include "globals.h"
#include "extern.h"
short testGnuPlayer ( void )
{
/* test #1 */
if ( PW_i < 0x92 )
{
/*printf ( "#0 (start:%ld) \n", PW_i - 0x92 );*/
return BAD;
}
/* test #2 smp size and loop start */
PW_WholeSampleSize = 0;
PW_o = 0; /* will hold the number of non-null samples */
PW_Start_Address = PW_i - 0x92;
for ( PW_k=0 ; PW_k<31 ; PW_k++ )
{
PW_j = (in_data[PW_Start_Address+20+PW_k*4]*256) + in_data[PW_Start_Address+21+PW_k*4];
PW_l = (in_data[PW_Start_Address+22+PW_k*4]*256) + in_data[PW_Start_Address+23+PW_k*4];
if ( PW_l > (PW_j+1) )
{
/*printf ( "#1 Start:%ld\n" , PW_Start_Address );*/
return BAD;
}
if ( PW_j != 0 ) PW_o += 1;
PW_WholeSampleSize += PW_j;
}
return GOOD;
}
void Rip_GnuPlayer ( void )
{
/*PW_WholeSampleSize is the whole sample size */
/*but it seems to be a fake sample values */
/* size of 1st track + header */
PW_k = (in_data[PW_Start_Address + 0x96]*256)+in_data[PW_Start_Address + 0x97] + 0x96;
/* size of 2nd track */
PW_j = (in_data[PW_k]*256) + in_data[PW_k+1] + PW_k;
/* PW_j points now to the first sample size */
/*printf ( "\nWhere before 1st sample : %ld\n" , PW_j);*/
/* real sample sizes */
PW_m = 0;
while ( PW_m < PW_o )
{
PW_k = (in_data[PW_Start_Address+PW_j]*256) + in_data[PW_Start_Address+PW_j+1];
PW_j += (PW_k + 2);
PW_m += 1;
/*printf ( "sample %ld : siz:%ld where:%ld\n", PW_m,PW_k,PW_j );
fflush (stdout);*/
}
OutputSize = PW_j;
CONVERT = GOOD;
Save_Rip ( "GnuPlayer module", GnuPlayer );
if ( Save_Status == GOOD )
PW_i += 0x96;
}
/*
* GnuPlayer.c 2003 (c) Asle@free.fr
*
*/
#define MAXI(a,b) (a>b?a:b)
void Depack_GnuPlayer ( void )
{
Uchar *Whatever;
long i=0,j=0,k=0,l=0;
long Where = PW_Start_Address;
Uchar * Pattern;
Uchar poss[37][2];
FILE *out;/*,*info;*/
long SizOfTrack,len1,len2;
long SmpSizes[31];
long NbrSmp = 0;
short SfxNbr=0;
if ( Save_Status == BAD )
return;
fillPTKtable(poss);
sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
out = PW_fopen ( Depacked_OutName , "w+b" );
/*info = fopen ( "info", "w+b" );*/
/* read and write title */
fwrite ( &in_data[Where] , 20 , 1 , out );
/* get global sample rate */
/*
for ( SmpRate=0x00 ; i<37 ; SmpRate+=0x01 )
if ( (poss[SmpRate][0] == in_data[Where + 0x90]) && (poss[SmpRate][1] == in_data[Where + 0x91]))
break;
*/
/*take care of pattern right now*/
Pattern = (Uchar *) malloc (65536);
BZERO (Pattern, 65536);
Where = PW_Start_Address + 0x96;
/* track 1 & 2 */
SizOfTrack = (in_data[Where]*256) + in_data[Where+1]; /* size of track 1 */
/*fprintf ( info, "Size of track 1 : %ld (%x)\n", SizOfTrack,SizOfTrack );*/
Where += 2; len1=0;l=0;
for ( i=0 ; i<SizOfTrack ; i+=2 )
{
switch (in_data[Where+i])
{
case 0: /* track end */
/*fprintf ( info, "[%3ld][%4ld] <-- end of track\n\n", i,l );*/
i = SizOfTrack;
break;
case 1: /* set volume */
SfxNbr += 1;
/*fprintf ( info, "[%3ld][%4ld] C fx (arg:%2d) [sfx %d]\n",i,l,in_data[Where+1+i],SfxNbr);*/
Pattern[l+2] |= 0x0C;
Pattern[l+3] = in_data[Where+1+i];
Pattern[l+6] |= 0x0C;
Pattern[l+7] = in_data[Where+1+i];
break;
case 2: /* same a A */
SfxNbr += 1;
/*fprintf ( info, "[%3ld][%4ld] A fx (arg:%2d) [sfx %d]\n",i,l,in_data[Where+1+i],SfxNbr);*/
Pattern[l+2] += 0x0A;
Pattern[l+3] = in_data[Where+1+i];
Pattern[l+6] += 0x0A;
Pattern[l+7] = in_data[Where+1+i];
break;
case 3: /* set speed */
SfxNbr += 1;
/*fprintf ( info, "[%3ld][%4ld] F fx (arg:%2d) [sfx %d]\n",i,l,in_data[Where+1+i],SfxNbr);*/
if ( SfxNbr == 1 )
{
Pattern[l+2] |= 0x0f;
Pattern[l+3] = in_data[Where+1+i];
}
else /* if SfxNbr == 3, I'm in trouble :( */
{
Pattern[l+6] |= 0x0f;
Pattern[l+7] = in_data[Where+1+i];
}
break;
case 4: /* bypass rows */
/*fprintf ( info, "[%3ld][%4ld] bypass rows : %d\n",i,l,in_data[Where+1+i]);*/
l += (in_data[Where+i+1] * 16);
SfxNbr = 0;
break;
case 5: /* set note */
/*fprintf ( info, "[%3ld][%4ld] set note with smp nbr %d\n",i,l,in_data[Where+1+i]);*/
Pattern[l] = (in_data[Where+1+i]&0xf0);
Pattern[l] |= in_data[PW_Start_Address + 0x90];
Pattern[l+1] = in_data[PW_Start_Address + 0x91];
Pattern[l+4] = (in_data[Where+1+i]&0xf0);
Pattern[l+4] |= in_data[PW_Start_Address + 0x90];
Pattern[l+5] = in_data[PW_Start_Address + 0x91];
Pattern[l+2] |= (in_data[Where+1+i]<<4);
Pattern[l+6] |= (in_data[Where+1+i]<<4);
break;
default :
printf ( "\nunsupported case in Depack_GnuPlayer(). Please send this file to \"asle@free.fr\" :)\n" );
break;
}
}
len1 = l/1024;
/* track 3 & 4 */
Where += (SizOfTrack - 2);
SizOfTrack = (in_data[Where]*256) + in_data[Where+1]; /* size of track 2 */
/*fprintf ( info, "Size of track 2 : %ld (%x)\n", SizOfTrack,SizOfTrack );*/
Where += 2; len2=0;l=0;
for ( i=0 ; i<SizOfTrack ; i+=2 )
{
switch (in_data[Where+i])
{
case 0: /* track end */
/*fprintf ( info, "[%3ld][%4ld] <-- end of track\n\n", i,l );*/
i = SizOfTrack;
break;
case 1: /* set volume */
SfxNbr += 1;
/*fprintf ( info, "[%3ld][%4ld] C fx (arg:%d) [Sfx %d]\n",i,l,in_data[Where+1+i],SfxNbr);*/
Pattern[l+10] |= 0x0C;
Pattern[l+11] = in_data[Where+1+i];
Pattern[l+14] |= 0x0C;
Pattern[l+15] = in_data[Where+1+i];
break;
case 2: /* same a A */
SfxNbr += 1;
/*fprintf ( info, "[%3ld][%4ld] A fx (arg:%2d) [Sfx %d]\n",i,l,in_data[Where+1+i],SfxNbr);*/
Pattern[l+10] |= 0x0A;
Pattern[l+11] = in_data[Where+1+i];
Pattern[l+14] |= 0x0A;
Pattern[l+15] = in_data[Where+1+i];
break;
case 3: /* set speed */
SfxNbr += 1;
/*fprintf ( info, "[%3ld][%4ld] F fx (arg:%2d) [Sfx %d]\n",i,l,in_data[Where+1+i],SfxNbr);*/
if ( SfxNbr == 1 )
{
Pattern[l+10] |= 0x0f;
Pattern[l+11] = in_data[Where+1+i];
}
else
{
Pattern[l+14] |= 0x0f;
Pattern[l+15] = in_data[Where+1+i];
}
break;
case 4: /* bypass rows */
/*fprintf ( info, "[%3ld][%4ld] bypass rows : %d\n",i,l,in_data[Where+1+i]);*/
l += (in_data[Where+i+1] * 16);
SfxNbr = 0;
break;
case 5: /* set note */
/*fprintf ( info, "[%3ld][%4ld] set note with smp nbr %d\n",i,l,in_data[Where+1+i]);*/
Pattern[l+8] = (in_data[Where+1+i]&0xf0);
Pattern[l+8] |= in_data[PW_Start_Address + 0x90];
Pattern[l+9] = in_data[PW_Start_Address + 0x91];
Pattern[l+12] = (in_data[Where+1+i]&0xf0);
Pattern[l+12] |= in_data[PW_Start_Address + 0x90];
Pattern[l+13] = in_data[PW_Start_Address + 0x91];
Pattern[l+10] |= (in_data[Where+1+i]<<4);
Pattern[l+14] |= (in_data[Where+1+i]<<4);
break;
default :
printf ( "\nunsupported case in Depack_GnuPlayer(). Please send this file to \"asle@free.fr\" :)\n" );
break;
}
}
len2 = l/1024;
Where += (SizOfTrack - 2);
/*fprintf ( info, "\nWhere before first sample : %ld (%x)\n", Where,Where );*/
/* sample header stuff */
Whatever = (Uchar *) malloc ( 2048 );
BZERO (Whatever, 2048);
/*get nbr of non-null samples */
for ( i=0 ; i< 31 ; i++)
{
k = (in_data[PW_Start_Address + 20 + (i*4)]*256) + in_data[PW_Start_Address + 21 + (i*4)];
if ( k != 0 )
NbrSmp += 1;
SmpSizes[i] = k;
Whatever[22+(i*30)] = in_data[PW_Start_Address + 20 + (i*4)];
Whatever[23+(i*30)] = in_data[PW_Start_Address + 21 + (i*4)];
Whatever[25+(i*30)] = 0x40;
Whatever[26+(i*30)] = in_data[PW_Start_Address + 22 + (i*4)];
Whatever[27+(i*30)] = in_data[PW_Start_Address + 23 + (i*4)];
Whatever[29+(i*30)] = 0x01;
}
k = MAXI(len1,len2);
Whatever[930] = k;
Whatever[931] = 0x7f;
for ( i=0; i<k ;i++ )
Whatever[i+932] = (Uchar) i;
Whatever[1060] = 'M';
Whatever[1061] = '.';
Whatever[1062] = 'K';
Whatever[1063] = '.';
fwrite ( Whatever, 1064, 1, out );
/* write patterns */
/* k being the max of both lengths of tracks */
fwrite ( Pattern, k*1024 , 1 , out );
free ( Pattern );
/* sample stuff */
free ( Whatever );
Whatever = (Uchar *) malloc (65436);
for ( i=0 ; i<NbrSmp ; i++ )
{
long out_end;
char samp;
k = 0;
BZERO (Whatever,65536);
j = (in_data[Where]*256) + in_data[Where+1];
Where += 2;
out_end = (j*2);
/*fprintf ( info, "sample %ld : siz:%ld where:%ld\n" , i,out_end,Where);*/
/*fflush ( info );*/
Whatever[k++] = in_data[Where++];
while ( k < out_end )
{
samp = (in_data[Where]>>4)&0x0f;
if ( samp & 0x08 ) samp -= 0x10;
Whatever[k++] = (Whatever[k-1] + samp);
samp = in_data[Where] & 0x0f;
if ( samp & 0x08 ) samp -= 0x10;
Whatever[k++] = (Whatever[k-1] + samp);
Where += 1;
}
Where -= 1;
fwrite ( &Whatever[0], out_end, 1, out );
}
free ( Whatever );
/* crap */
Crap ( " GnuPlayer " , BAD , BAD , out );
fflush ( out );
fclose ( out );
/*fclose ( info );*/
printf ( "done\n" );
return; /* useless ... but */
}