Initial support for downloaded images.

This commit is contained in:
James Sanford 2012-10-28 00:14:52 -07:00
parent 8d8653ab21
commit f7432b5481
9 changed files with 207 additions and 58 deletions

View File

@ -1,8 +1,3 @@
g_limit_speed = 2
s5d1 = XMAS_DEMO.2MG
bram1[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00
bram1[10] = 00 00 07 06 02 01 01 00 00 00 0f 06 06 00 05 06
bram1[20] = 01 00 00 00 00 00 00 01 05 00 00 00 03 02 02 02

View File

@ -1,8 +1,3 @@
g_limit_speed = 3
s7d1 = System 6.hdv
bram1[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00
bram1[10] = 00 00 07 06 02 01 01 00 00 00 0f 06 06 00 05 06
bram1[20] = 01 00 00 00 00 00 00 01 07 00 00 00 03 02 02 02

View File

@ -3,43 +3,50 @@ package com.froop.app.kegs;
import android.util.Log;
import android.os.AsyncTask;
import java.io.File;
class AssetImages extends AsyncTask<Void, Void, Boolean> {
interface AssetsReady {
void onAssetsReady(boolean success);
void onAssetsReady(boolean result);
}
private KegsMain mContext;
private AssetsReady mNotify;
private ConfigFile mConfigFile;
AssetImages(KegsMain context, ConfigFile config) {
mContext = context;
AssetImages(AssetsReady notify, ConfigFile config) {
mNotify = notify;
mConfigFile = config;
}
private void checkOldImagePath(String filename) {
final File oldPath = new File(mConfigFile.getConfigPath(), filename);
final File newPath = new File(mConfigFile.getImagePath(), filename);
if (oldPath != null && oldPath.exists()) {
new File(mConfigFile.getImagePath()).mkdirs();
oldPath.renameTo(newPath);
}
}
protected void onPreExecute() {
// We used to drop images directly into the config dir.
// Make sure any images in the config dir get moved to the images dir.
checkOldImagePath("XMAS_DEMO.2MG");
checkOldImagePath("System 6.hdv");
}
protected Boolean doInBackground(Void... params) {
mConfigFile.ensureAssetCopied("XMAS_DEMO.2MG");
mConfigFile.ensureAssetCopied("System 6 Shareware.zip",
"System 6.hdv");
mConfigFile.ensureAssetCopied(mConfigFile.getImagePath(), "XMAS_DEMO.2MG");
mConfigFile.ensureAssetCopied(mConfigFile.getImagePath(),
"System 6 Shareware.zip", "System 6.hdv");
// TODO: could check to make sure they actually exist now.
// For testing:
// try { Thread.sleep(20000); } catch (InterruptedException e) {}
return true;
}
protected void onCancelled(final Boolean success) {
mContext.runOnUiThread(new Runnable() {
public void run() { mContext.onAssetsReady(false); }
});
protected void onCancelled(final Boolean result) {
mNotify.onAssetsReady(false);
}
protected void onPostExecute(final Boolean success) {
mContext.runOnUiThread(new Runnable() {
public void run() { mContext.onAssetsReady(success); }
});
protected void onPostExecute(final Boolean result) {
mNotify.onAssetsReady(result);
}
}

View File

@ -31,9 +31,13 @@ class ConfigFile {
return mConfigPath;
}
public void ensureAssetCopied(String zipfile, String exampleFile) {
public String getImagePath() {
return mConfigPath + "/images";
}
public void ensureAssetCopied(String destPath, String zipfile, String exampleFile) {
// We only check for a local copy of a single file before unzipping...
final File local_copy = new File(mConfigPath, exampleFile);
final File local_copy = new File(destPath, exampleFile);
if (local_copy != null && local_copy.exists()) {
// Assume that whatever is there will work.
return;
@ -44,8 +48,8 @@ class ConfigFile {
ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(mContext.getAssets().open(zipfile)));
ZipEntry zipEntry;
while ((zipEntry = zipStream.getNextEntry()) != null) {
new CopyHelper(zipStream, false,
mConfigPath, zipEntry.getName()).copy();
new CopyHelper(zipStream, destPath,
zipEntry.getName()).withClose(false).copy();
}
} catch (java.io.IOException e) {
// KEGS will just fail.
@ -54,9 +58,9 @@ class ConfigFile {
}
}
public void ensureAssetCopied(String assetName) {
public void ensureAssetCopied(String destPath, String assetName) {
// Make sure there's a user-readable copy of whatever from assets.
final File local_copy = new File(mConfigPath, assetName);
final File local_copy = new File(destPath, assetName);
if (local_copy != null && local_copy.exists()) {
// Assume that whatever is there will work.
return;
@ -64,7 +68,7 @@ class ConfigFile {
try {
new CopyHelper(mContext.getAssets().open(assetName),
mConfigPath, assetName).copy();
destPath, assetName).copy();
} catch (java.io.IOException e) {
// KEGS will just fail.
Log.e("kegs", Log.getStackTraceString(e));
@ -73,7 +77,7 @@ class ConfigFile {
}
public void defaultConfig() {
ensureAssetCopied(mConfigDefault);
ensureAssetCopied(mConfigPath, mConfigDefault);
// Then, copy whatever is there over to the actual 'config.kegs' file.
try {
new CopyHelper(new FileInputStream(new File(mConfigPath, mConfigDefault)),
@ -85,11 +89,17 @@ class ConfigFile {
}
}
public void internalConfig(String configName) {
// Overwrite 'config.kegs' with a config from the assets directory.
public byte[] getConfigPreface(final DiskImage image) {
return String.format("g_limit_speed = %d\n%s = %s/%s\n\n",
image.speed, image.drive,
getImagePath(), image.filename).getBytes();
}
public void setConfig(DiskImage image) {
// Overwrite 'config.kegs' with a config based on a template.
try {
new CopyHelper(mContext.getAssets().open(configName),
mConfigPath, mConfigFile).copy();
new CopyHelper(mContext.getAssets().open(image.template), mConfigPath,
mConfigFile).withPreface(getConfigPreface(image)).copy();
} catch (java.io.IOException e) {
// KEGS will just fail.
Log.e("kegs", Log.getStackTraceString(e));

View File

@ -6,21 +6,29 @@ import java.io.InputStream;
import java.io.FileOutputStream;
public class CopyHelper {
private byte[] mPreface;
private InputStream mInput;
private boolean mClose;
private String mDir;
private String mFile;
private static final String mTmp = "tmp_";
CopyHelper(InputStream input, boolean close, String dir, String filename) {
CopyHelper(InputStream input, String dir, String filename) {
mPreface = null;
mInput = input;
mClose = close;
mClose = true;
mDir = dir;
mFile = filename;
}
CopyHelper(InputStream input, String dir, String filename) {
this(input, true, dir, filename);
public CopyHelper withPreface(byte[] preface) {
mPreface = preface;
return this;
}
public CopyHelper withClose(boolean close) {
mClose = close;
return this;
}
// This leaves a partial temporary file on error and doesn't let you know
@ -43,6 +51,9 @@ public class CopyHelper {
byte buf[] = new byte[4096];
FileOutputStream out = new FileOutputStream(output_file);
if (mPreface != null) {
out.write(mPreface, 0, mPreface.length);
}
do {
int numread = mInput.read(buf);
if (numread <= 0) {

View File

@ -24,7 +24,7 @@ import com.actionbarsherlock.app.SherlockDialogFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.StickyReset, AssetImages.AssetsReady {
public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.StickyReset, AssetImages.AssetsReady, DownloadImage.DownloadReady {
private static final String FRAGMENT_ROM = "rom";
private static final String FRAGMENT_DOWNLOAD = "download";
private static final String FRAGMENT_ERROR = "error";
@ -43,6 +43,9 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
private TouchJoystick mJoystick;
private boolean mAssetsReady = false;
private boolean mDownloadReady = false;
private boolean mDownloadAborted = false;
private boolean mModeMouse = true;
private long mScreenSizeTime = 0;
@ -99,34 +102,75 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
}
public void onAssetsReady(boolean success) {
// TODO FIXME: this needs to throw an error if it fails.
mAssetsReady = success;
}
private void loadConfigWhenReady(final String configfile) {
public void onDownloadReady(boolean success) {
// TODO FIXME: this needs to throw an error if it fails.
mDownloadReady = success;
}
private void loadDiskImageWhenReady(final DiskImage image) {
final AssetFragment frag = (AssetFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_ASSET);
if (!getThread().nowWaitingForPowerOn() || !mAssetsReady) {
if (frag == null && !mAssetsReady) {
// This code is lame.
if (mDownloadAborted) {
if (frag != null) {
frag.dismiss();
}
if (image.primary) {
getThread().allowPowerOn();
}
return; // don't schedule another pass.
}
boolean nativeReady;
if (image.primary) {
nativeReady = getThread().nowWaitingForPowerOn();
} else {
nativeReady = true;
}
if (!nativeReady || !mAssetsReady || !mDownloadReady) {
if (frag == null && (!mAssetsReady || !mDownloadReady)) {
// Only the asset part will take time, so only show the dialog
// when waiting for the asset.
final SherlockDialogFragment assetProgress = new AssetFragment();
assetProgress.show(getSupportFragmentManager(), FRAGMENT_ASSET);
}
mKegsView.postDelayed(new Runnable() {
public void run() { loadConfigWhenReady(configfile); }
public void run() { loadDiskImageWhenReady(image); }
}, 100);
} else {
if (frag != null) {
frag.dismiss();
}
mConfigFile.internalConfig(configfile);
getThread().allowPowerOn();
if (image.primary) {
mConfigFile.setConfig(image);
getThread().allowPowerOn();
} else {
// TODO FIXME: eject/insert the new disk.
}
}
}
protected void loadConfig(String configfile) {
getThread().doPowerOff();
loadConfigWhenReady(configfile);
protected void loadDiskImage(DiskImage image) {
if (image.primary) {
getThread().doPowerOff();
}
mDownloadReady = false;
mDownloadAborted = false;
final String imagePath = mConfigFile.getImagePath();
if (android.os.Build.VERSION.SDK_INT >= 11) {
new DownloadImage(this, imagePath, image).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new DownloadImage(this, imagePath, image).execute();
}
loadDiskImageWhenReady(image);
}
protected void getRomFile(String romfile) {
@ -230,6 +274,12 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
mDownloadAborted = true;
}
}
public KegsThread getThread() {

View File

@ -0,0 +1,23 @@
package com.froop.app.kegs;
class DiskImage {
public static final String BOOT_SLOT_5 = "boot_slot_5";
public static final String BOOT_SLOT_6 = "boot_slot_6";
public static final String BOOT_SLOT_7 = "boot_slot_7";
public boolean primary = true;
public String filename;
public String drive;
public int speed;
public String template;
// Example:
// DiskImage("XMAS_DEMO.2MG", "s5d1", 2, "boot_slot_5");
public DiskImage(final String filename, final String drive,
final int speed, final String template) {
this.filename = filename;
this.drive = drive;
this.speed = speed;
this.template = template;
}
}

View File

@ -19,7 +19,7 @@ import com.actionbarsherlock.app.SherlockDialogFragment;
public class DiskImageFragment extends SherlockDialogFragment {
private String[] mImages = {
"System 6", "X-MAS Demo (FTA)"};
"System 6", "X-MAS Demo (FTA)", "Prince of Persia"};
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@ -29,10 +29,19 @@ public class DiskImageFragment extends SherlockDialogFragment {
builder.setItems(mImages, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
dismiss();
DiskImage image = null;
if (item == 0) {
((KegsMain)getActivity()).loadConfig("boot_slot_7");
image = new DiskImage("System 6.hdv", "s7d1", 3, DiskImage.BOOT_SLOT_7);
} else if (item == 1) {
((KegsMain)getActivity()).loadConfig("boot_slot_5");
image = new DiskImage("XMAS_DEMO.2MG", "s5d1", 2, DiskImage.BOOT_SLOT_5);
} else if (item == 2) {
// TODO: There should be an adapter on the ListView instead.
image = new DiskImage("prince.2mg", "s5d1", 2, DiskImage.BOOT_SLOT_5);
}
if (image != null) {
((KegsMain)getActivity()).loadDiskImage(image);
}
}
});

View File

@ -0,0 +1,49 @@
package com.froop.app.kegs;
import android.util.Log;
import android.os.AsyncTask;
import java.io.File;
class DownloadImage extends AsyncTask<Void, Void, Boolean> {
interface DownloadReady {
void onDownloadReady(boolean result);
}
private DownloadReady mNotify;
private DiskImage mImage;
private File mDest;
DownloadImage(DownloadReady notify, String imagePath, DiskImage image) {
mNotify = notify;
mImage = image;
mDest = new File(imagePath + "/" + mImage.filename);
if (mDest.exists()) {
// Assume whatever is there will work.
// So the caller will immediately see that it's already done.
mNotify.onDownloadReady(true);
}
}
protected void onPreExecute() {
}
protected Boolean doInBackground(Void... params) {
if (mDest.exists()) {
// Assume whatever is there will work.
return true;
}
return new DownloadHelper().save(
"http://jsan.co/KEGS/images/" + mImage.filename, mDest.getPath());
}
protected void onCancelled(final Boolean result) {
mNotify.onDownloadReady(false);
}
protected void onPostExecute(final Boolean result) {
mNotify.onDownloadReady(result);
}
}