Skip to content
Permalink
Browse files

front/assets: Split large assets into smaller files.

Assets larger than 1MB cannot be extracted in Android 2.2 and below.
http://stackoverflow.com/questions/2860157/load-files-bigger-than-1m-from-assets-folder

The cheats data files have been split into smaller pieces, and Asset-
Extractor has been updated to reassemble the pieces after extraction.
  • Loading branch information...
littleguy77 committed Jul 8, 2013
1 parent 485e901 commit 4ad77b624fac341c56c8d25156f4445344d27b52
@@ -1,9 +1,10 @@
[28:2.3.2]
- Added auto-frameskip feature to gles2glide64
- Updated core and plugins to version 2.0
- Fixed file extraction failure on Android 2.2 and below
- Added sensitivity preference for controller analog sticks
- Fixed analog scaling for Mayflash N64/USB adapter
- Removed obsolete items in the Advanced menu
- Updated core and plugins to version 2.0
[27:2.3.1]
- Added support for MOGA Pocket/Pro via MOGA Pivot app (no menu navigation in mode A)
- Fixed junk graphics in the margins for gles2rice video plugin

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -50,10 +50,10 @@
* Asset version number, used to determine stale assets. Increment this number every time the
* assets are updated on disk.
*/
private static final int ASSET_VERSION = 18;
private static final int ASSET_VERSION = 19;

/** The total number of assets to be extracted (for computing progress %). */
private static final int TOTAL_ASSETS = 121;
private static final int TOTAL_ASSETS = 123;

/** The minimum duration that the splash screen is shown, in milliseconds. */
private static final int SPLASH_DELAY = 1000;
@@ -24,13 +24,18 @@
package paulscode.android.mupen64plusae.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.res.AssetManager;
import android.util.Log;
@@ -50,7 +55,8 @@
FILE_UNWRITABLE,
FILE_UNCLOSABLE,
ASSET_UNCLOSABLE,
IO_EXCEPTION
ASSET_IO_EXCEPTION,
FILE_IO_EXCEPTION,
}

public static class ExtractionFailure
@@ -71,14 +77,17 @@ public String toString()
switch( reason )
{
case FILE_UNWRITABLE:
return "Failed to open output file " + dstPath;
return "Failed to open file " + dstPath;
case FILE_UNCLOSABLE:
return "Failed to close output file " + dstPath;
return "Failed to close file " + dstPath;
case ASSET_UNCLOSABLE:
return "Failed to close asset " + srcPath;
case IO_EXCEPTION:
default:
case ASSET_IO_EXCEPTION:
return "Failed to extract asset " + srcPath + " to file " + dstPath;
case FILE_IO_EXCEPTION:
return "Failed to add file " + srcPath + " to file " + dstPath;
default:
return "Failed using source " + srcPath + " and destination " + dstPath;
}
}
}
@@ -110,12 +119,29 @@ public String toString()
// Ensure the parent directories exist
new File( dstPath ).mkdirs();

// Some files are too big for Android 2.2 and below, so we break them into parts.
// We use a simple naming scheme where we just append .part0, .part1, etc.
Pattern pattern = Pattern.compile( "(.+)\\.part(\\d+)$" );
HashMap<String, Integer> fileParts = new HashMap<String, Integer>();

// Recurse into each subdirectory
for( String srcSubPath : srcSubPaths )
{
Matcher matcher = pattern.matcher( srcSubPath );
if( matcher.matches() )
{
String name = matcher.group(1);
if( fileParts.containsKey( name ) )
fileParts.put( name, fileParts.get( name ) + 1 );
else
fileParts.put( name, 1 );
}
String suffix = "/" + srcSubPath;
failures.addAll( extractAssets( assetManager, srcPath + suffix, dstPath + suffix, onProgress ) );
}

// Combine the large broken files, if any
combineFileParts( fileParts, dstPath );
}
else // srcPath is a file.
{
@@ -149,7 +175,7 @@ public String toString()
}
catch( IOException e )
{
ExtractionFailure failure = new ExtractionFailure( srcPath, dstPath, FailureReason.IO_EXCEPTION );
ExtractionFailure failure = new ExtractionFailure( srcPath, dstPath, FailureReason.ASSET_IO_EXCEPTION );
Log.e( "AssetExtractor", failure.toString() );
failures.add( failure );
}
@@ -210,4 +236,81 @@ public String toString()

return srcSubPaths;
}

private static List<ExtractionFailure> combineFileParts( Map<String, Integer> filePieces, String dstPath )
{
List<ExtractionFailure> failures = new ArrayList<ExtractionFailure>();
for (String name : filePieces.keySet() )
{
String src = null;
String dst = dstPath + "/" + name;
OutputStream out = null;
InputStream in = null;
try
{
out = new FileOutputStream( dst );
byte[] buffer = new byte[1024];
int read;
for( int i = 0; i < filePieces.get( name ); i++ )
{
src = dst + ".part" + i;
try
{
in = new FileInputStream( src );
while( ( read = in.read( buffer ) ) != -1 )
{
out.write( buffer, 0, read );
}
out.flush();
}
catch( IOException e )
{
ExtractionFailure failure = new ExtractionFailure( src, dst, FailureReason.FILE_IO_EXCEPTION );
Log.e( "AssetExtractor", failure.toString() );
failures.add( failure );
}
finally
{
if( in != null )
{
try
{
in.close();
new File( src ).delete();
}
catch( IOException e )
{
ExtractionFailure failure = new ExtractionFailure( src, dst, FailureReason.FILE_UNCLOSABLE );
Log.e( "AssetExtractor", failure.toString() );
failures.add( failure );
}
}
}
}
}
catch( FileNotFoundException e )
{
ExtractionFailure failure = new ExtractionFailure( src, dst, FailureReason.FILE_UNWRITABLE );
Log.e( "AssetExtractor", failure.toString() );
failures.add( failure );
}
finally
{
if( out != null )
{
try
{
out.close();
}
catch( IOException e )
{
ExtractionFailure failure = new ExtractionFailure( src, dst, FailureReason.FILE_UNCLOSABLE );
Log.e( "AssetExtractor", failure.toString() );
failures.add( failure );
}
}
}
}
return failures;
}
}

0 comments on commit 4ad77b6

Please sign in to comment.
You can’t perform that action at this time.