コード例 #1
0
ファイル: ash.cpp プロジェクト: CHASECAREY123456789/wiiflow
u8*	DecompressAsh( const u8 *stuff, u32 &len )
{
	if( !IsAshCompressed( stuff, len ) )
	{
		return NULL;
	}

	unsigned int r[32];
	unsigned int count = 0;
	unsigned int t;

	r[4] = (u32)stuff;	  //in

	r[5] = 0x415348;
	r[6] = 0x415348;

	r[5] = s32(*(unsigned int *)(r[4]+4));
	r[5] = r[5] & 0x00FFFFFF;

	u32 size = r[5];
	//gprintf("Decompressed size: %d\n", size);
	u8* buf1 = (u8*)memalign( 32, size );
	if( !buf1 )
	{
		gprintf( "ASH: no memory\n" );
		return NULL;
	}
	r[3] = (u32)buf1;   //out
	memset( (void*)buf1, 0, size );
	//printf("r[3] :%08X\n", r[3]);

	//printf("\n\n");

	r[24] = 0x10;
	r[28] = s32(*(unsigned int *)(r[4]+8));
	r[25] = 0;
	r[29] = 0;
	r[26] = s32(*(unsigned int *)(r[4]+0xC));
	r[30] = s32(*(unsigned int *)(r[4]+r[28]));
	r[28] = r[28] + 4;
	//r[8]  = 0x8108<<16;
	//HACK, pointer to RAM
	u8* workingBuffer = (u8*)memalign( 32, 0x100000 );
	if( !workingBuffer )
	{
		gprintf( "ASH: no memory 2\n" );
		free( buf1 );
		return NULL;
	}
	r[8]  = (u32)workingBuffer;
	memset( (void*)workingBuffer, 0, 0x100000 );
	//printf("r[8] :%08X\n", r[8]);

	r[8]  = r[8];
	r[9]  = r[8]  + 0x07FE;
	r[10] = r[9]  + 0x07FE;
	r[11] = r[10] + 0x1FFE;
	r[31] = r[11] + 0x1FFE;
	r[23] = 0x200;
	r[22] = 0x200;
	r[27] = 0;

loc_81332124:

	if( r[25] != 0x1F )
		goto loc_81332140;

	r[0] = r[26] >> 31;
	r[26]= s32(*(unsigned int *)(r[4] + r[24]));
	r[25]= 0;
	r[24]= r[24] + 4;
	goto loc_8133214C;

loc_81332140:

	r[0] = r[26] >> 31;
	r[25]= r[25] + 1;
	r[26]= r[26] << 1;

loc_8133214C:

	if( r[0] == 0 )
		goto loc_81332174;

	r[0] = r[23] | 0x8000;
	*(unsigned short *)(r[31]) = s16(r[0]);
	r[0] = r[23] | 0x4000;
	*(unsigned short *)(r[31]+2) = s16(r[0]);

	r[31] = r[31] + 4;
	r[27] = r[27] + 2;
	r[23] = r[23] + 1;
	r[22] = r[22] + 1;

	goto loc_81332124;

loc_81332174:

	r[12] = 9;
	r[21] = r[25] + r[12];
	t = r[21];
	if( r[21] > 0x20 )
		goto loc_813321AC;

	r[21] = (~(r[12] - 0x20))+1;
	r[6]  = r[26] >> r[21];
	if( t == 0x20 )
		goto loc_8133219C;

	r[26] = r[26] << r[12];
	r[25] = r[25] +  r[12];
	goto loc_813321D0;

loc_8133219C:

	r[26]= s32(*(unsigned int *)(r[4] + r[24]));
	r[25]= 0;
	r[24]= r[24] + 4;
	goto loc_813321D0;

loc_813321AC:

	r[0] = (~(r[12] - 0x20))+1;
	r[6] = r[26] >> r[0];
	r[26]= s32(*(unsigned int *)(r[4] + r[24]));
	r[0] = (~(r[21] - 0x40))+1;
	r[24]= r[24] + 4;
	r[0] = r[26] >> r[0];
	r[6] = r[6] | r[0];
	r[25] = r[21] - 0x20;
	r[26] = r[26] << r[25];

loc_813321D0:

	r[12]= s16(*(unsigned short *)(r[31] - 2));
	r[31] -= 2;
	r[27]= r[27] - 1;
	r[0] = r[12] & 0x8000;
	r[12]= (r[12] & 0x1FFF) << 1;
	if( r[0] == 0 )
		goto loc_813321F8;

	*(unsigned short *)(r[9]+r[12]) = s16(r[6]);
	r[6] = (r[12] & 0x3FFF)>>1;					 //   extrwi  %r6, %r12, 14,17
	if( r[27] != 0 )
		goto loc_813321D0;

	goto loc_81332204;

loc_813321F8:

	*(unsigned short *)(r[8]+r[12]) = s16(r[6]);
	r[23] = r[22];
	goto loc_81332124;

loc_81332204:

	r[23] = 0x800;
	r[22] = 0x800;

loc_8133220C:

	if( r[29] != 0x1F )
		goto loc_81332228;

	r[0] = r[30] >> 31;
	r[30]= s32(*(unsigned int *)(r[4] + r[28]));
	r[29]= 0;
	r[28]= r[28] + 4;
	goto loc_81332234;

loc_81332228:

	r[0] = r[30] >> 31;
	r[29]= r[29] +  1;
	r[30]= r[30] << 1;

loc_81332234:

	if( r[0] == 0 )
		goto loc_8133225C;

	r[0] = r[23] | 0x8000;
	*(unsigned short *)(r[31]) = s16(r[0]);
	r[0] = r[23] | 0x4000;
	*(unsigned short *)(r[31]+2) = s16(r[0]);

	r[31] = r[31] + 4;
	r[27] = r[27] + 2;
	r[23] = r[23] + 1;
	r[22] = r[22] + 1;

	goto loc_8133220C;

loc_8133225C:

	r[12] = 0xB;
	r[21] = r[29] + r[12];
	t = r[21];
	if( r[21] > 0x20 )
		goto loc_81332294;

	r[21] = (~(r[12] - 0x20))+1;
	r[7]  = r[30] >> r[21];
	if( t == 0x20 )
		goto loc_81332284;

	r[30] = r[30] << r[12];
	r[29] = r[29] +  r[12];
	goto loc_813322B8;

loc_81332284:

	r[30]= s32(*(unsigned int *)(r[4] + r[28]));
	r[29]= 0;
	r[28]= r[28] + 4;
	goto loc_813322B8;

loc_81332294:

	r[0] = (~(r[12] - 0x20))+1;
	r[7] = r[30] >> r[0];
	r[30]= s32(*(unsigned int *)(r[4] + r[28]));
	r[0] = (~(r[21] - 0x40))+1;
	r[28]= r[28] + 4;
	r[0] = r[30] >> r[0];
	r[7] = r[7] | r[0];
	r[29]= r[21] - 0x20;
	r[30]= r[30] << r[29];

loc_813322B8:

	r[12]= s16(*(unsigned short *)(r[31] - 2));
	r[31] -= 2;
	r[27]= r[27] - 1;
	r[0] = r[12] & 0x8000;
	r[12]= (r[12] & 0x1FFF) << 1;
	if( r[0] == 0 )
		goto loc_813322E0;

	*(unsigned short *)(r[11]+r[12]) = s16(r[7]);
	r[7] = (r[12] & 0x3FFF)>>1;					 // extrwi  %r7, %r12, 14,17
	if( r[27] != 0 )
		goto loc_813322B8;

	goto loc_813322EC;

loc_813322E0:

	*(unsigned short *)(r[10]+r[12]) = s16(r[7]);
	r[23] = r[22];
	goto loc_8133220C;

loc_813322EC:

	r[0] = r[5];

loc_813322F0:

	r[12]= r[6];

loc_813322F4:

	if( r[12] < 0x200 )
		goto loc_8133233C;

	if( r[25] != 0x1F )
		goto loc_81332318;

	r[31] = r[26] >> 31;
	r[26] = s32(*(unsigned int *)(r[4] + r[24]));
	r[24] = r[24] + 4;
	r[25] = 0;
	goto loc_81332324;

loc_81332318:

	r[31] = r[26] >> 31;
	r[25] = r[25] +  1;
	r[26] = r[26] << 1;

loc_81332324:

	r[27] = r[12] << 1;
	if( r[31] != 0 )
		goto loc_81332334;

	r[12] = s16(*(unsigned short *)(r[8] + r[27]));
	goto loc_813322F4;

loc_81332334:

	r[12] = s16(*(unsigned short *)(r[9] + r[27]));
	goto loc_813322F4;

loc_8133233C:

	if( r[12] >= 0x100 )
		goto loc_8133235C;

	*(unsigned char *)(r[3]) = r[12];
	r[3] = r[3] + 1;
	r[5] = r[5] - 1;
	if( r[5] != 0 )
		goto loc_813322F0;

	goto loc_81332434;

loc_8133235C:

	r[23] = r[7];

loc_81332360:

	if( r[23] < 0x800 )
		goto loc_813323A8;

	if( r[29] != 0x1F )
		goto loc_81332384;

	r[31] = r[30] >> 31;
	r[30] = s32(*(unsigned int *)(r[4] + r[28]));
	r[28] = r[28] + 4;
	r[29] = 0;
	goto loc_81332390;

loc_81332384:

	r[31] = r[30] >> 31;
	r[29] = r[29] +  1;
	r[30] = r[30] << 1;

loc_81332390:

	r[27] = r[23] << 1;
	if( r[31] != 0 )
		goto loc_813323A0;

	r[23] = s16(*(unsigned short *)(r[10] + r[27]));
	goto loc_81332360;

loc_813323A0:

	r[23] = s16(*(unsigned short *)(r[11] + r[27]));
	goto loc_81332360;

loc_813323A8:

	r[12] = r[12] - 0xFD;
	r[23] = ~r[23] + r[3] + 1;
	r[5]  = ~r[12] + r[5] + 1;
	r[31] = r[12] >> 3;

	if( r[31] == 0 )
		goto loc_81332414;

	count = r[31];

loc_813323C0:

	r[31] = *(unsigned char *)(r[23] - 1);
	*(unsigned char *)(r[3]) = r[31];

	r[31] = *(unsigned char *)(r[23]);
	*(unsigned char *)(r[3]+1) = r[31];

	r[31] = *(unsigned char *)(r[23] + 1);
	*(unsigned char *)(r[3]+2) = r[31];

	r[31] = *(unsigned char *)(r[23] + 2);
	*(unsigned char *)(r[3]+3) = r[31];

	r[31] = *(unsigned char *)(r[23] + 3);
	*(unsigned char *)(r[3]+4) = r[31];

	r[31] = *(unsigned char *)(r[23] + 4);
	*(unsigned char *)(r[3]+5) = r[31];

	r[31] = *(unsigned char *)(r[23] + 5);
	*(unsigned char *)(r[3]+6) = r[31];

	r[31] = *(unsigned char *)(r[23] + 6);
	*(unsigned char *)(r[3]+7) = r[31];

	r[23] = r[23] + 8;
	r[3]  = r[3]  + 8;

	if( --count )
		goto loc_813323C0;

	r[12] = r[12] & 7;
	if( r[12] == 0 )
		goto loc_8133242C;

loc_81332414:

	count = r[12];

loc_81332418:

	r[31] = *(unsigned char *)(r[23] - 1);
	r[23] = r[23] + 1;
	*(unsigned char *)(r[3]) = r[31];
	r[3]  = r[3] + 1;

	if( --count )
		goto loc_81332418;

loc_8133242C:

	if( r[5] != 0 )
		goto loc_813322F0;

loc_81332434:

	r[3] = r[0];
	len = r[3];

	//gprintf("Decompressed %d bytes\n", r[3]);
	free( workingBuffer );
	return buf1;
}
コード例 #2
0
u8* U8NandArchive::GetFileAllocated( const char *path, u32 *size ) const
{
	//gprintf( "U8NandArchive::GetFileAllocated( %s )\n" );
	if( !path || !fst )
	{
		return NULL;
	}

	// find file
	int f = EntryFromPath( path, 0 );
	if( f < 1 || f >= (int)fst[ 0 ].filelen )
	{
		gprintf( "U8: \"%s\" wasn't found in the archive.\n", path );
		return NULL;
	}
	if( fst[ f ].filetype )
	{
		gprintf( "U8: \"%s\" is a folder\n", path );
		return NULL;
	}

	// create a buffer
	u8* ret = (u8*)memalign( 32, RU( fst[ f ].filelen, 32 ) );
	if( !ret )
	{
		gprintf( "U8: out of memory\n" );
		return NULL;
	}

	// seek and read
	if( ISFS_Seek( fd, dataOffset + fst[ f ].fileoffset, SEEK_SET ) != (s32)( dataOffset + fst[ f ].fileoffset )
			|| ISFS_Read( fd, ret, fst[ f ].filelen ) != (s32)fst[ f ].filelen )
	{
		free( ret );
		gprintf( "U8: error reading data from nand\n" );
		gprintf( "fd: %i  fst[ fd ].filelen: %08x\n", fd, fst[ f ].filelen );
		return NULL;
	}

	u32 len = fst[ f ].filelen;
	u8* ret2;
	// determine if it needs to be decompressed
	if( IsAshCompressed( ret, len ) )
	{
		// ASH0
		ret2 = DecompressAsh( ret, len );
		if( !ret2 )
		{
			free( ret );
			gprintf( "out of memory\n" );
			return NULL;
		}
		free( ret );
	}
	else if( isLZ77compressed( ret ) )
	{
		// LZ77 with no magic word
		if( decompressLZ77content( ret, len, &ret2, &len ) )
		{
			free( ret );
			return NULL;
		}
		free( ret );
	}
	else if( *(u32*)( ret ) == 0x4C5A3737 )// LZ77
	{
		// LZ77 with a magic word
		if( decompressLZ77content( ret + 4, len - 4, &ret2, &len ) )
		{
			free( ret );
			return NULL;
		}
		free( ret );
	}
	else
	{
		// already got what we are after
		ret2 = ret;
	}

	if( size )
	{
		*size = len;
	}

	// flush the cache so if there are any textures in this data, it will be ready for the GX
	DCFlushRange( ret2, len );
	return ret2;
}
コード例 #3
0
u8* U8Archive::GetFileAllocated( const char *path, u32 *size ) const
{
	u32 len;
	const u8 *stuff = GetFile( path, &len );
	if( !stuff )
	{
		return NULL;
	}

	// check for IMD5 header and skip it
	if( len > 0x40 && *(u32*)stuff == 0x494d4435 )// IMD5
	{
		stuff += 0x20;
		len -= 0x20;
	}

	u8* ret = NULL;
	// determine if it needs to be decompressed
	if( IsAshCompressed( stuff, len ) )
	{
		//u32 len2 = len;
		// ASH0
		ret = DecompressAsh( stuff, len );
		if( !ret )
		{
			gprintf( "out of memory\n" );
			return NULL;
		}
		/*
		u8* ret2 = DecompressAsh2( stuff, len2 );
		if( !ret2 )
		{
			gprintf( "out of memory 2\n" );
			return NULL;
		}
		if( len != len2 || memcmp( ret, ret2, len ) )
		{
			gprintf( "doesn\'t match\n" );
		}
		else
		{
			gprintf( "matches\n" );
		}
		exit( 0 );*/
	}
	else if( isLZ77compressed( stuff ) )
	{
		// LZ77 with no magic word
		if( decompressLZ77content( stuff, len, &ret, &len ) )
		{
			return NULL;
		}
	}
	else if( *(u32*)( stuff ) == 0x4C5A3737 )// LZ77
	{
		// LZ77 with a magic word
		if( decompressLZ77content( stuff + 4, len - 4, &ret, &len ) )
		{
			return NULL;
		}
	}
	else
	{
		// just copy the data out of the archive
		ret = (u8*)memalign( 32, len );
		if( !ret )
		{
			gprintf( "out of memory\n" );
			return NULL;
		}
		memcpy( ret, stuff, len );
	}
	if( size )
	{
		*size = len;
	}

	// flush the cache so if there are any textures in this data, it will be ready for the GX
	DCFlushRange( ret, len );
	return ret;
}
コード例 #4
0
u8 *U8Archive::DecompressCopy( const u8 * stuff, u32 len, u32 *size ) const
{
	// check for IMD5 header and skip it
	if( len > 0x40 && *(u32*)stuff == 0x494d4435 )// IMD5
	{
		stuff += 0x20;
		len -= 0x20;
	}

	u8* ret = NULL;
	// determine if it needs to be decompressed
	if( IsAshCompressed( stuff, len ) )
	{
		//u32 len2 = len;
		// ASH0
		ret = DecompressAsh( stuff, len );
		if( !ret )
		{
			gprintf( "out of memory\n" );
			return NULL;
		}
	}
	else if( (len > 8) && *(u32*)( stuff ) == 0x59617a30 )// Yaz0
	{
		// Yaz0 with a magic word
		Yaz0_Header *header = (Yaz0_Header *) stuff;
		// set decompress length
		len = header->decompressed_size;
		// allocate memory
		ret = (u8*) memalign(32, ALIGN32(len));
		if(!ret)
		{
			gprintf("out of memory\n");
			return NULL;
		}
		// function can not fail at this point
		uncompressYaz0(stuff, ret, len);
	}
	else if( isLZ77compressed( stuff ) )
	{
		// LZ77 with no magic word
		if( decompressLZ77content( stuff, len, &ret, &len ) )
		{
			return NULL;
		}
	}
	else if( *(u32*)( stuff ) == 0x4C5A3737 )// LZ77
	{
		// LZ77 with a magic word
		if( decompressLZ77content( stuff + 4, len - 4, &ret, &len ) )
		{
			return NULL;
		}
	}
	else
	{
		// just copy the data out of the archive
		ret = (u8*)memalign( 32, ALIGN32( len ) );
		if( !ret )
		{
			gprintf( "out of memory\n" );
			return NULL;
		}
		memcpy( ret, stuff, len );
	}
	if( size )
	{
		*size = len;
	}

	// flush the cache so if there are any textures in this data, it will be ready for the GX
	DCFlushRange( ret, len );
	return ret;
}
コード例 #5
0
u8*	DecompressAsh( const u8 *stuff, u32 &len )
{
	if( !IsAshCompressed( stuff, len ) )
	{
		return NULL;
	}

	u32 r[32];
	u32 t;

	r[4] = (u32)stuff;      //in


	r[5] = *(u32*)( r[4] + 4 );
	r[5] = r[5] & 0x00FFFFFF;

	u32 size = r[5];

	//gprintf("Decompressed size: %d\n", size);
	u8* buf1 = (u8*)memalign( 32, size );
	if( !buf1 )
	{
		gprintf( "ASH: no memory\n" );
		return NULL;
	}
	r[3] = (u32)buf1;   //out
	//memset( (void*)buf1, 0, size );
	//printf("r[3] :%08X\n", r[3]);

	//printf("\n\n");

	r[24] = 0x10;
	r[28] = *(u32 *)(r[4]+8);
	r[25] = 0;
	r[29] = 0;
	r[26] = *(u32 *)(r[4]+0xC);
	r[30] = *(u32 *)(r[4]+r[28]);
	r[28] = r[28] + 4;
	//r[8]  = 0x8108<<16;
	//HACK, pointer to RAM
	u8* workingBuffer = (u8*)memalign( 32, MAX( 0x100000, size ) );
	if( !workingBuffer )
	{
		gprintf( "ASH: no memory 2\n" );
		free( buf1 );
		return NULL;
	}
	r[8]  = (u32)workingBuffer;
	//memset( (void*)workingBuffer, 0, 0x100000 );

	r[9]  = r[8]  + 0x07FE;
	r[10] = r[9]  + 0x07FE;
	r[11] = r[10] + 0x1FFE;
	r[31] = r[11] + 0x1FFE;
	r[23] = 0x200;
	r[22] = 0x200;
	r[27] = 0;

	while( 1 )
	{
		// loc_81332124:
		r[0] = r[26] >> 31;
		if( r[25] != 0x1F )
		{
			// loc_81332140:
			r[25]++;
			r[26] <<= 1;
		}
		else
		{
			// 8133212C
			r[26]= *(u32 *)( r[4] + r[24] );
			r[25]= 0;
			r[24] += 4;
		}

		// loc_8133214C:
		if( r[0] )
		{
			// 81332150
			*(u16*)( r[31] )	 = r[23] | 0x8000;
			*(u16*)( r[31] + 2 ) = r[23] | 0x4000;

			r[31] += 4;
			r[27] += 2;
			r[23]++;
			r[22]++;
			continue;
		}

		// loc_81332174:
		r[21] = r[25] + 9;
		t = r[21];
		if( r[21] > 0x20 )
		{
			// loc_813321AC:
			r[0] = 0x17;
			r[6] = r[26] >> r[0];
			r[26]= *(u32*)( r[4] + r[24 ]);
			r[0] = (~(r[21] - 0x40))+1;
			r[24] += 4;
			r[0] = r[26] >> r[0];
			r[6] |= r[0];
			r[25] = r[21] - 0x20;
			r[26] = r[26] << r[25];
		}
		else
		{