Use config files from 'assets', copied to external storage directory. Copy 'default' config over on startup, which allows the user to edit the default config.

This commit is contained in:
James Sanford 2012-10-21 02:59:37 -07:00
parent 07ad8717ba
commit a587ba4ed7
9 changed files with 209 additions and 9 deletions

21
assets/default Normal file
View File

@ -0,0 +1,21 @@
# testing:
# g_cfg_rom_path = /mnt/sdcard/ROM.03
# 0 = unlimited 1 = 1mhz 2 = 2.8mhz 3 = 8mhz
g_limit_speed = 2
# By default no disk images are loaded until the user inserts one.
#
# Put your custom config here and KEGS will use it on power on.
# s5d1 = /mnt/sdcard/Downloads/DELTA_DEMO.2MG
# s6d1 = /mnt/sdcard/Downloads/karateka.dsk
# s7d1 = /mnt/sdcard/Downloads/Hard Drive 1.hdv
# s7d2 = /mnt/sdcard/Downloads/Hard Drive 2.hdv
#
# s7d11 = :Partition Name:/path/to/image
# The BRAM below tells it to boot Slot 5.
#
# Delete all the below lines to get the default.
#
# For custom BRAM, copy config_kegs to here while KEGS is running.

View File

@ -292,6 +292,26 @@ x_update_color(int col_num, int red, int green, int blue, word32 rgb)
{
}
// This typically sets g_config_kegs_name to the full path of 'config.kegs'.
void android_config_init(char *output, int maxlen) {
output[0] = 0;
jclass cls = (*g_env)->GetObjectClass(g_env, g_thiz);
jmethodID mid = (*g_env)->GetMethodID(g_env, cls, "getConfigFile", "()Ljava/lang/String;");
(*g_env)->DeleteLocalRef(g_env, cls);
if (mid == NULL) {
return;
}
jstring config_path = (*g_env)->CallObjectMethod(g_env, g_thiz, mid);
if (config_path == NULL) {
return;
}
const char *nativeString = (*g_env)->GetStringUTFChars(g_env, config_path, 0);
strncpy(output, nativeString, maxlen - 1);
output[maxlen - 1] = 0;
(*g_env)->ReleaseStringUTFChars(g_env, config_path, nativeString);
(*g_env)->DeleteLocalRef(g_env, config_path);
}
// Instead of 'KegsView$KegsThread', the $ is encoded as _00024.
// (not any more, but it was KegsView_00024KegsThread_mainLoop)

View File

@ -339,9 +339,14 @@ config_init()
// Find the config.kegs file
g_config_kegs_name[0] = 0;
#ifdef __ANDROID__
extern void android_config_init(char *, int);
android_config_init(&g_config_kegs_name[0], sizeof(g_config_kegs_name));
#else
can_create = 1;
setup_kegs_file(&g_config_kegs_name[0], sizeof(g_config_kegs_name), 0,
can_create, &g_config_kegs_name_list[0]);
#endif
config_parse_config_kegs_file();
}
@ -687,6 +692,7 @@ config_parse_config_kegs_file()
g_highest_smartport_unit = -1;
cfg_get_base_path(&g_cfg_cwd_str[0], g_config_kegs_name, 0);
#if !defined(__ANDROID__)
if(g_cfg_cwd_str[0] != 0) {
ret = chdir(&g_cfg_cwd_str[0]);
if(ret != 0) {
@ -696,6 +702,7 @@ config_parse_config_kegs_file()
/* In any case, copy the directory path to g_cfg_cwd_str */
(void)getcwd(&g_cfg_cwd_str[0], CFG_PATH_MAX);
#endif
fconf = fopen(g_config_kegs_name, "r");
if(fconf == 0) {

View File

@ -20,7 +20,6 @@ const char rcsid_sim65816_c[] = "@(#)$KmKId: sim65816.c,v 1.367 2004-11-22 02:39
#define vsnprintf _vsnprintf
#endif
#define PC_LOG_LEN (8*1024)
int g_speed_fast ; // OG Expose fast parameter
@ -1215,7 +1214,14 @@ setup_kegs_file(char *outname, int maxlen, int ok_if_missing,
outname[0] = 0;
#ifdef __ANDROID__
extern char g_cfg_cwd_str[];
// For this to work, g_config_kegs_name must have already been set.
const char *tmp_paths[2] = { g_cfg_cwd_str, 0 };
path_ptr = &tmp_paths[0];
#else
path_ptr = &g_kegs_default_paths[0];
#endif
save_path_ptr = path_ptr;
while(*path_ptr) {

View File

@ -0,0 +1,84 @@
package com.froop.app.kegs;
import android.content.Context;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class ConfigFile {
public static final String ROM03 = "ROM.03";
public static final String ROM01 = "ROM.01";
private static final String mConfigFile = "config.kegs";
private static final String mConfigDefault = "default";
private Context mContext;
private String mConfigPath;
ConfigFile(Context context) {
mContext = context;
mConfigPath = mContext.getExternalFilesDir(null).getPath();
}
public String getConfigFile() {
return mConfigPath + "/" + mConfigFile;
}
public String getConfigPath() {
return mConfigPath;
}
public void ensureAssetCopied(String assetName) {
// Make sure there's a user-readable copy of whatever from assets.
final File local_copy = new File(mConfigPath, assetName);
if (local_copy != null && local_copy.exists()) {
// Assume that whatever is there will work.
return;
}
try {
new CopyHelper(mContext.getAssets().open(assetName),
mConfigPath, assetName).copy();
} catch (java.io.IOException e) {
// KEGS will just fail.
return;
}
}
public void defaultConfig() {
ensureAssetCopied(mConfigDefault);
// Then, copy whatever is there over to the actual 'config.kegs' file.
try {
new CopyHelper(new FileInputStream(new File(mConfigPath, mConfigDefault)),
mConfigPath, mConfigFile).copy();
} catch (java.io.IOException e) {
// KEGS will just fail.
return;
}
}
public void internalConfig(String configName) {
// Overwrite 'config.kegs' with a config from the assets directory.
try {
new CopyHelper(mContext.getAssets().open(configName),
mConfigPath, mConfigFile).copy();
} catch (java.io.IOException e) {
// KEGS will just fail.
return;
}
}
public String whichRomFile() {
File rom = new File(mConfigPath, ROM03);
if (rom != null && rom.exists()) {
return rom.getPath();
}
rom = new File(mConfigPath, ROM01);
if (rom != null && rom.exists()) {
return rom.getPath();
}
return null;
}
}

View File

@ -0,0 +1,48 @@
package com.froop.app.kegs;
import android.util.Log;
import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
public class CopyHelper {
private InputStream mInput;
private String mDir;
private String mFile;
private static final String mTmp = "tmp_";
CopyHelper(InputStream input, String dir, String filename) {
mInput = input;
mDir = dir;
mFile = filename;
}
public void copy() throws java.io.IOException {
Log.e("kegs", "CopyHelper to " + mDir + "/" + mFile);
final File dir = new File(mDir);
dir.mkdirs();
final File output_file = new File(mDir, mTmp + mFile);
final File final_file = new File(mDir, mFile);
if (output_file == null || final_file == null) {
throw new java.io.IOException("null File in " + mDir);
}
output_file.delete();
output_file.createNewFile();
byte buf[] = new byte[4096];
FileOutputStream out = new FileOutputStream(output_file);
do {
int numread = mInput.read(buf);
if (numread <= 0) {
break;
} else {
out.write(buf, 0, numread);
}
} while (true);
out.close();
output_file.renameTo(final_file);
mInput.close();
}
}

View File

@ -30,6 +30,7 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset {
private static final String FRAGMENT_SPEED = "speed";
private static final String FRAGMENT_DISKIMAGE = "diskimage";
private ConfigFile mConfigFile;
private KegsThread mKegsThread;
// For the software renderer, use 'KegsView' here and in res/layout/main.xml
@ -104,7 +105,8 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset {
protected Boolean doInBackground(String ... raw_romfile) {
mRomfile = raw_romfile[0];
return new DownloadHelper().save(
"http://jsan.co/" + mRomfile, Config.mPath.getPath() + "/" + mRomfile);
"http://jsan.co/KEGS/" + mRomfile,
mConfigFile.getConfigPath() + "/" + mRomfile);
}
protected void onPostExecute(Boolean success) {
final DialogFragment frag = (DialogFragment)getFragmentManager().findFragmentByTag(FRAGMENT_DOWNLOAD);
@ -117,7 +119,7 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset {
dialog.show(getFragmentManager(), FRAGMENT_ERROR);
}
} else {
Config.defaultConfig(mRomfile);
mConfigFile.defaultConfig();
getThread().setReady(true);
}
}
@ -301,7 +303,10 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset {
mKegsView = (KegsViewGL)findViewById(R.id.kegsview);
mKegsThread = new KegsThread(mKegsView.getBitmap());
mConfigFile = new ConfigFile(this);
mKegsThread = new KegsThread(mConfigFile.getConfigFile(),
mKegsView.getBitmap());
mKegsThread.registerUpdateScreenInterface(mKegsView);
workaroundScreenSize();
@ -336,12 +341,15 @@ public class KegsMain extends Activity implements KegsKeyboard.StickyReset {
findViewById(R.id.key_up).setOnClickListener(mButtonClick);
findViewById(R.id.key_down).setOnClickListener(mButtonClick);
final String romfile = Config.whichRomFile();
// TODO: Kick this off in the background for built in images.
// mConfigFile.ensureAssetCopied("XMAS_DEMO.2MG");
final String romfile = mConfigFile.whichRomFile();
if (romfile == null) {
final DialogFragment chooseRom = new RomDialogFragment();
chooseRom.show(getFragmentManager(), FRAGMENT_ROM);
} else {
Config.defaultConfig(romfile);
mConfigFile.defaultConfig();
getThread().setReady(true);
}
}

View File

@ -12,6 +12,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
class KegsThread extends Thread {
private ConcurrentLinkedQueue<Event.KegsEvent> mEventQueue = new ConcurrentLinkedQueue<Event.KegsEvent>();
private String mConfigFile; // full path to config_kegs
private Bitmap mBitmap;
private final ReentrantLock mPauseLock = new ReentrantLock();
private final ReentrantLock mPowerWait = new ReentrantLock();
@ -25,7 +26,8 @@ class KegsThread extends Thread {
}
private UpdateScreen mUpdateScreen;
public KegsThread(Bitmap bitmap) {
public KegsThread(String configFile, Bitmap bitmap) {
mConfigFile = configFile;
mBitmap = bitmap;
}
@ -51,6 +53,10 @@ class KegsThread extends Thread {
}
}
private String getConfigFile() {
return mConfigFile;
}
// See jni/android_driver.c:mainLoop()
private native void mainLoop(Bitmap b, ConcurrentLinkedQueue q);

View File

@ -19,9 +19,9 @@ public class RomDialogFragment extends DialogFragment {
if (item == 0) {
((KegsMain)getActivity()).finish();
} else if (item == 1) {
((KegsMain)getActivity()).getRomFile(Config.mROM01);
((KegsMain)getActivity()).getRomFile(ConfigFile.ROM01);
} else if (item == 2) {
((KegsMain)getActivity()).getRomFile(Config.mROM03);
((KegsMain)getActivity()).getRomFile(ConfigFile.ROM03);
}
}
});