Accept intents for local disk images.

This commit is contained in:
James Sanford 2012-11-02 16:28:59 -07:00
parent 0b71b9b65e
commit e62d6044b1
7 changed files with 166 additions and 26 deletions

View File

@ -19,6 +19,44 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:pathPattern=".*\\.2mg" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:pathPattern=".*\\.dsk" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:pathPattern=".*\\.nib" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:pathPattern=".*\\.hdv" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:pathPattern=".*\\.po" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:pathPattern=".*\\.do" />
</intent-filter>
</activity>
</application>
</manifest>

33
assets/boot_slot_6 Normal file
View File

@ -0,0 +1,33 @@
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 06 00 00 00 03 02 02 02
bram1[30] = 00 00 00 00 00 00 00 00 00 00 01 02 03 04 05 06
bram1[40] = 07 00 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d
bram1[50] = 0e 0f ff ff ff ff ff ff ff ff ff ff ff ff ff 81
bram1[60] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[70] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[80] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[90] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[a0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[b0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[c0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[d0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[e0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram1[f0] = ff ff ff ff ff ff ff ff ff ff ff ff 3d 78 97 d2
bram3[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00
bram3[10] = 00 00 07 06 02 01 01 00 00 00 0f 06 06 00 05 06
bram3[20] = 01 00 00 00 00 00 00 01 06 00 00 00 05 02 02 00
bram3[30] = 00 00 2d 2d 00 00 00 00 00 00 02 02 02 06 08 00
bram3[40] = 01 02 03 04 05 06 07 0a 00 01 02 03 04 05 06 07
bram3[50] = 08 09 0a 0b 0c 0d 0e 0f 00 00 ff ff ff ff ff 81
bram3[60] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[70] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[80] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[90] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[a0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[b0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[c0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[d0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[e0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[f0] = ff ff ff ff ff ff ff ff ff ff ff ff 60 0f ca a5

View File

@ -89,10 +89,18 @@ class ConfigFile {
}
}
public String fullPath(final String filename) {
if (filename.startsWith("/")) {
return filename;
} else {
return getImagePath() + "/" + filename;
}
}
public byte[] getConfigPreface(final DiskImage image) {
return String.format("g_limit_speed = %d\n%s = %s/%s\n\n",
return String.format("g_limit_speed = %d\n%s = %s\n\n",
image.speed, image.drive,
getImagePath(), image.filename).getBytes();
fullPath(image.filename)).getBytes();
}
public void setConfig(DiskImage image) {

View File

@ -6,7 +6,9 @@ import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.AsyncTask;
import android.util.Log;
@ -179,6 +181,34 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
loadDiskImageWhenReady(image);
}
private DiskImage getBootDiskImage(Intent intent) {
if (intent != null && intent.getAction() == Intent.ACTION_VIEW) {
final Uri uri = intent.getData();
if (uri != null && uri.getScheme().equals("file")) {
final String path = uri.getPath();
if (path != null) {
return DiskImage.fromPath(path);
}
}
}
return null;
}
// The first boot upon application launch.
private void boot() {
final DiskImage image = getBootDiskImage(getIntent());
if (image != null) {
loadDiskImage(image);
} else {
mConfigFile.defaultConfig();
getThread().allowPowerOn();
mKegsView.postDelayed(new Runnable() { public void run() {
new DiskImageFragment().show(getSupportFragmentManager(),
FRAGMENT_DISKIMAGE);
} }, 1000);
}
}
protected void getRomFile(String romfile) {
final SherlockDialogFragment download = new DownloadDialogFragment();
download.show(getSupportFragmentManager(), FRAGMENT_DOWNLOAD);
@ -208,11 +238,7 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
dialog.show(getSupportFragmentManager(), FRAGMENT_ERROR);
}
} else {
mConfigFile.defaultConfig();
getThread().setReady(true);
mKegsView.postDelayed(new Runnable() { public void run() {
new DiskImageFragment().show(getSupportFragmentManager(), FRAGMENT_DISKIMAGE);
} }, 1000);
boot();
}
}
}
@ -404,6 +430,15 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
return false;
}
@Override
protected void onNewIntent(Intent intent) {
// TODO: consider asking user whether to swap disks or reboot
final DiskImage image = getBootDiskImage(intent);
if (image != null) {
loadDiskImage(image);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -472,11 +507,7 @@ public class KegsMain extends SherlockFragmentActivity implements KegsKeyboard.S
final SherlockDialogFragment chooseRom = new RomDialogFragment();
chooseRom.show(getSupportFragmentManager(), FRAGMENT_ROM);
} else {
mConfigFile.defaultConfig();
getThread().setReady(true);
mKegsView.postDelayed(new Runnable() { public void run() {
new DiskImageFragment().show(getSupportFragmentManager(), FRAGMENT_DISKIMAGE);
} }, 1000);
boot();
}
}

View File

@ -108,6 +108,10 @@ class KegsThread extends Thread {
}
public void doPowerOff() {
if (!mReady) {
return; // bail out, we haven't started doing anything yet
}
// Tell the native thread loop to wait before powering on again.
mPowerWait.lock();
@ -115,8 +119,14 @@ class KegsThread extends Thread {
mEventQueue.add(new Event.KeyKegsEvent(120 + 0x80, true));
}
// Call from the UI thread only.
public void allowPowerOn() {
// Intended to be called from the UI thread.
if (!mReady) {
mReady = true;
onResume(); // Will start the thread if not already started.
return;
}
// As the native thread is allowed to loop by default,
// this is only useful after using doPowerOff().
if (mPowerWait.isHeldByCurrentThread()) {
@ -126,6 +136,10 @@ class KegsThread extends Thread {
// Is native thread loop sitting around waiting for us to allow power on?
public boolean nowWaitingForPowerOn() {
if (!mReady) {
return true; // bail out, we haven't started doing anything yet
}
return mPowerWait.hasQueuedThreads();
}
@ -153,14 +167,4 @@ class KegsThread extends Thread {
getEventQueue().add(new Event.KeyKegsEvent(KegsKeyboard.KEY_CONTROL, true));
getEventQueue().add(new Event.KeyKegsEvent(KegsKeyboard.KEY_OPEN_APPLE, true));
}
public void setReady(boolean ready) {
final boolean wasReady = mReady;
mReady = ready;
if (ready && !wasReady) {
// Will start the thread if not already started.
onResume();
}
}
}

View File

@ -1,5 +1,7 @@
package com.froop.app.kegs;
import java.io.File;
class DiskImage {
public static final String BOOT_SLOT_5 = "boot_slot_5";
public static final String BOOT_SLOT_6 = "boot_slot_6";
@ -20,4 +22,21 @@ class DiskImage {
this.speed = speed;
this.template = template;
}
public static DiskImage fromPath(String path) {
final File file = new File(path);
final long length = file.length();
if (!file.exists()) {
return null;
} else if (length >= 1024 * 1024) {
// TODO: should insert the disk and use the System 6 template
return new DiskImage(path, "s7d1", 3, BOOT_SLOT_7);
} else if (length >= 400 * 1024) {
return new DiskImage(path, "s5d1", 2, BOOT_SLOT_5);
} else if (length > 0) {
return new DiskImage(path, "s6d1", 1, BOOT_SLOT_6);
} else {
return null;
}
}
}

View File

@ -13,13 +13,20 @@ class DownloadImage extends AsyncTask<Void, Void, Boolean> {
private DownloadReady mNotify;
private DiskImage mImage;
private File mDest;
private boolean mLocalPath = false;
DownloadImage(DownloadReady notify, String imagePath, DiskImage image) {
mNotify = notify;
mImage = image;
mDest = new File(imagePath + "/" + mImage.filename);
if (mDest.exists()) {
if (imagePath == null || image.filename.startsWith("/")) {
mLocalPath = true;
mDest = new File(image.filename);
} else {
mDest = new File(imagePath, image.filename);
}
if (mLocalPath || mDest.exists()) {
// Assume whatever is there will work.
// So the caller will immediately see that it's already done.
mNotify.onDownloadReady(true);
@ -30,7 +37,7 @@ class DownloadImage extends AsyncTask<Void, Void, Boolean> {
}
protected Boolean doInBackground(Void... params) {
if (mDest.exists()) {
if (mLocalPath || mDest.exists()) {
// Assume whatever is there will work.
return true;
}