This commit is contained in:
dgis 2018-12-12 20:25:24 +00:00
parent d623bcc609
commit d17ba8394d
8 changed files with 277 additions and 205 deletions

View file

@ -2,6 +2,7 @@ ABOUT
This project ports the Windows application Emu48 written in C to Android.
It uses the Android NDK. The former Emu48 source code remains untouch because a thin win32 emulation layer above Linux/NDK!
This win32 layer will allow to easily update from the original Emu48 source code.
It can open or save the exact same state files (state.e48/e49) than the original Windows application!
NOT WORKING
- Sound
@ -12,7 +13,7 @@ NOT WORKING
- Serial Ports (Wire or Ir)
TODO
- Choose KML/Change KML/NewDocument
- Bug: No refresh with the clock
- Option to allow rotation
- Option to auto hide the menu
- Bitmap corruption when touching the buttons
@ -22,3 +23,4 @@ TODO
DONE
- Bug Red and Blue seems inverted.
- Multitouch
- Choose KML/Change KML/NewDocument

View file

@ -1372,69 +1372,69 @@ static LRESULT OnViewSettings(VOID)
//
/*static*/ LRESULT OnViewScript(VOID)
{
// TCHAR szKmlFile[MAX_PATH];
// BOOL bKMLChanged,bSucc;
//
// BYTE cType = cCurrentRomType;
// if (nState != SM_RUN)
// {
// InfoMessage(_T("You cannot change the KML script when Emu48 is not running.\n")
// _T("Use the File,New menu item to create a new calculator."));
// return 0;
// }
// SwitchToState(SM_INVALID);
//
// // make a copy of the current KML script file name
// _ASSERT(sizeof(szKmlFile) == sizeof(szCurrentKml));
// lstrcpyn(szKmlFile,szCurrentKml,ARRAYSIZEOF(szKmlFile));
//
// bKMLChanged = FALSE; // KML script not changed
// bSucc = TRUE; // KML script successful loaded
//
// do
// {
// if (!DisplayChooseKml(cType)) // quit with Cancel
// {
// if (!bKMLChanged) // KML script not changed
// break; // exit loop with current loaded KML script
//
// // restore KML script file name
// lstrcpyn(szCurrentKml,szKmlFile,ARRAYSIZEOF(szCurrentKml));
//
// // try to restore old KML script
// if ((bSucc = InitKML(szCurrentKml,FALSE)))
// break; // exit loop with success
//
// // restoring failed, save document
// if (IDCANCEL != SaveChanges(bAutoSave))
// break; // exit loop with no success
//
// _ASSERT(bSucc == FALSE); // for continuing loop
// }
// else // quit with Ok
// {
// bKMLChanged = TRUE; // KML script changed
// bSucc = InitKML(szCurrentKml,FALSE);
// }
// }
// while (!bSucc); // retry if KML script is invalid
//
// if (bSucc)
// {
// if (Chipset.wRomCrc != wRomCrc) // ROM changed
// {
// CpuReset();
// Chipset.Shutdn = FALSE; // automatic restart
//
// Chipset.wRomCrc = wRomCrc; // update current ROM fingerprint
// }
// if (pbyRom) SwitchToState(SM_RUN); // continue emulation
// }
// else
// {
// ResetDocument(); // close document
// SetWindowTitle(NULL);
// }
TCHAR szKmlFile[MAX_PATH];
BOOL bKMLChanged,bSucc;
BYTE cType = cCurrentRomType;
if (nState != SM_RUN)
{
InfoMessage(_T("You cannot change the KML script when Emu48 is not running.\n")
_T("Use the File,New menu item to create a new calculator."));
return 0;
}
SwitchToState(SM_INVALID);
// make a copy of the current KML script file name
_ASSERT(sizeof(szKmlFile) == sizeof(szCurrentKml));
lstrcpyn(szKmlFile,szCurrentKml,ARRAYSIZEOF(szKmlFile));
bKMLChanged = FALSE; // KML script not changed
bSucc = TRUE; // KML script successful loaded
do
{
if (!DisplayChooseKml(cType)) // quit with Cancel
{
if (!bKMLChanged) // KML script not changed
break; // exit loop with current loaded KML script
// restore KML script file name
lstrcpyn(szCurrentKml,szKmlFile,ARRAYSIZEOF(szCurrentKml));
// try to restore old KML script
if ((bSucc = InitKML(szCurrentKml,FALSE)))
break; // exit loop with success
// restoring failed, save document
if (IDCANCEL != SaveChanges(bAutoSave))
break; // exit loop with no success
_ASSERT(bSucc == FALSE); // for continuing loop
}
else // quit with Ok
{
bKMLChanged = TRUE; // KML script changed
bSucc = InitKML(szCurrentKml,FALSE);
}
}
while (!bSucc); // retry if KML script is invalid
if (bSucc)
{
if (Chipset.wRomCrc != wRomCrc) // ROM changed
{
CpuReset();
Chipset.Shutdn = FALSE; // automatic restart
Chipset.wRomCrc = wRomCrc; // update current ROM fingerprint
}
if (pbyRom) SwitchToState(SM_RUN); // continue emulation
}
else
{
ResetDocument(); // close document
SetWindowTitle(NULL);
}
return 0;
}
@ -1710,31 +1710,31 @@ static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
//
static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
// switch (message)
// {
// case WM_INITDIALOG:
// SetDlgItemText(hDlg,IDC_VERSION,szNoTitle);
// SetDlgItemText(hDlg,IDC_LICENSE,szLicence);
// return TRUE;
// case WM_COMMAND:
// wParam = LOWORD(wParam);
// if ((wParam==IDOK)||(wParam==IDCANCEL))
// {
// EndDialog(hDlg, wParam);
// return TRUE;
// }
// break;
// }
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg,IDC_VERSION,szNoTitle);
SetDlgItemText(hDlg,IDC_LICENSE,szLicence);
return TRUE;
case WM_COMMAND:
wParam = LOWORD(wParam);
if ((wParam==IDOK)||(wParam==IDCANCEL))
{
EndDialog(hDlg, wParam);
return TRUE;
}
break;
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
}
static LRESULT OnToolDisasm(VOID) // disasm dialogbox call
{
// if (pbyRom) SwitchToState(SM_SLEEP);
// if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DISASM), hWnd, (DLGPROC)Disasm) == -1)
// AbortMessage(_T("Disassembler Dialog Box Creation Error!"));
// if (pbyRom) SwitchToState(SM_RUN);
if (pbyRom) SwitchToState(SM_SLEEP);
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DISASM), hWnd, (DLGPROC)Disasm) == -1)
AbortMessage(_T("Disassembler Dialog Box Creation Error!"));
if (pbyRom) SwitchToState(SM_RUN);
return 0;
}
@ -1746,8 +1746,8 @@ static LRESULT OnTopics(VOID)
static LRESULT OnAbout(VOID)
{
// if (DialogBox(hApp, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About) == -1)
// AbortMessage(_T("About Dialog Box Creation Error!"));
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About) == -1)
AbortMessage(_T("About Dialog Box Creation Error!"));
return 0;
}
@ -2249,16 +2249,16 @@ BOOL emu48Start()
// ShowWindow(hWnd,nCmdShow); // show emulator menu
// no default document, ask for new one
if (NewDocument()) SetWindowTitle(_T("Untitled"));
mainViewResizeCallback(nBackgroundW, nBackgroundH);
//BitBlt(hWindowDC, 0, 0, hMainDC->selectedBitmap->bitmapInfoHeader->biWidth, hMainDC->selectedBitmap->bitmapInfoHeader->biHeight, hMainDC, 0, 0, 0);
OnPaint(NULL);
//start:
if (bStartupBackup) SaveBackup(); // make a RAM backup at startup
if (pbyRom) SwitchToState(SM_RUN);
// if (NewDocument()) SetWindowTitle(_T("Untitled"));
//
// mainViewResizeCallback(nBackgroundW, nBackgroundH);
//
//
// //BitBlt(hWindowDC, 0, 0, hMainDC->selectedBitmap->bitmapInfoHeader->biWidth, hMainDC->selectedBitmap->bitmapInfoHeader->biHeight, hMainDC, 0, 0, 0);
// OnPaint(NULL);
////start:
// if (bStartupBackup) SaveBackup(); // make a RAM backup at startup
// if (pbyRom) SwitchToState(SM_RUN);
// while (GetMessage(&msg, NULL, 0, 0))
// {
@ -2307,12 +2307,6 @@ BOOL emu48Start()
}
//BOOL DisplayChooseKmlEx(CHAR cType) {
// lstrcpy(szCurrentKml, "hello.kml");
// return TRUE;
//}
void draw() {
OnPaint(NULL);
}

View file

@ -105,7 +105,3 @@ typedef LONG LONG_PTR, *PLONG_PTR;
language='*'\"")
#endif
#endif
//#define DisplayChooseKml DisplayChooseKmlEx
//extern BOOL DisplayChooseKmlEx(CHAR cType);

View file

@ -16,6 +16,7 @@ static jobject viewToUpdate = NULL;
static jobject mainActivity = NULL;
jobject bitmapMainScreen;
AndroidBitmapInfo androidBitmapInfo;
TCHAR szChosenCurrentKml[MAX_PATH];
extern void win32Init();
@ -67,9 +68,7 @@ JNIEnv *getJNIEnvironment() {
enum CALLBACK_TYPE {
CALLBACK_TYPE_INVALIDATE = 0,
CALLBACK_TYPE_WINDOW_RESIZE = 1,
CALLBACK_TYPE_GETOPENFILENAME = 2,
CALLBACK_TYPE_GETSAVEFILENAME = 3
CALLBACK_TYPE_WINDOW_RESIZE = 1
};
void mainViewUpdateCallback() {
@ -87,65 +86,6 @@ void mainViewResizeCallback(int x, int y) {
}
}
TCHAR * fillNullCharacter(TCHAR * fileFilter) {
TCHAR * pos = fileFilter;
int length = 0;
if(pos) {
for (;; pos++, length++) {
if (*pos == 0) {
if (*(pos + 1) == 0)
break;
}
}
TCHAR * newFileFilter = malloc(length + 1);
TCHAR * newPos = newFileFilter;
pos = fileFilter;
for (;; pos++, newPos++) {
if (*pos == 0) {
*newPos = _T('|');
if (*(pos + 1) == 0) {
*(newPos + 1) = 0;
break;
}
} else
*newPos = *pos;
}
return newFileFilter;
}
return NULL;
}
int mainViewGetOpenFileNameCallback(OPENFILENAME * ofn) {
//https://stackoverflow.com/a/53031083
//https://developer.android.com/guide/topics/providers/document-provider
// ofn->lpstrFilter =
// _T("Emu48 Files (*.e38;*.e39;*.e48;*.e49)\0")
// _T("*.e38;*.e39;*.e48;*.e49\0")
// _T("HP-38 Files (*.e38)\0*.e38\0")
// _T("HP-39 Files (*.e39)\0*.e39\0")
// _T("HP-48 Files (*.e48)\0*.e48\0")
// _T("HP-49 Files (*.e49)\0*.e49\0")
// _T("Win48 Files (*.w48)\0*.w48\0");
// ofn->nFilterIndex = 1;
// ofn->lpstrDefExt = _T("e48"); // HP48SX/GX
// ofn->Flags |= OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
//
//
// ofn->nMaxFile = ARRAYSIZEOF(szBuffer);
// ofn->lpstrFile = szBuffer;
TCHAR * lpstrFilter = fillNullCharacter(ofn->lpstrFilter);
mainViewCallback(CALLBACK_TYPE_GETOPENFILENAME, ofn->nFilterIndex, ofn->Flags, lpstrFilter, ofn->lpstrDefExt);
free(lpstrFilter);
}
int mainViewGetSaveFileNameCallback(OPENFILENAME * ofn) {
TCHAR * lpstrFilter = fillNullCharacter(ofn->lpstrFilter);
mainViewCallback(CALLBACK_TYPE_GETSAVEFILENAME, ofn->nFilterIndex, ofn->Flags, lpstrFilter, ofn->lpstrDefExt);
free(lpstrFilter);
}
// https://stackoverflow.com/questions/9630134/jni-how-to-callback-from-c-or-c-to-java
int mainViewCallback(int type, int param1, int param2, const TCHAR * param3, const TCHAR * param4) {
if (viewToUpdate) {
@ -172,6 +112,8 @@ int openFileFromContentResolver(const TCHAR * url, int writeAccess) {
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_start(JNIEnv *env, jobject thisz, jobject assetMgr, jobject bitmapMainScreen0, jobject activity, jobject view) {
szChosenCurrentKml[0] = '\0';
bitmapMainScreen = (*env)->NewGlobalRef(env, bitmapMainScreen0);
mainActivity = (*env)->NewGlobalRef(env, activity);
viewToUpdate = (*env)->NewGlobalRef(env, view);
@ -199,9 +141,9 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_stop(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_resize(JNIEnv *env, jobject thisz, jint width, jint height) {
}
//JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_resize(JNIEnv *env, jobject thisz, jint width, jint height) {
//
//}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_draw(JNIEnv *env, jobject thisz) {
draw();
@ -221,19 +163,21 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_keyUp(JNIEnv *env,
JNIEXPORT jstring JNICALL Java_com_regis_cosnier_emu48_NativeLib_getCurrentFilename(JNIEnv *env, jobject thisz) {
jstring result = (*env)->NewStringUTF(env, szBufferFilename);
return result;
}
//JNIEXPORT jstring JNICALL Java_com_regis_cosnier_emu48_NativeLib_getCurrentFilename(JNIEnv *env, jobject thisz) {
// jstring result = (*env)->NewStringUTF(env, szBufferFilename);
// return result;
//}
//JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_setCurrentFilename(JNIEnv *env, jobject thisz, jstring newFilename) {
// const char *newFilenameUTF8 = (*env)->GetStringUTFChars(env, newFilename , NULL) ;
// _tcscpy(szBufferFilename, newFilenameUTF8);
// (*env)->ReleaseStringUTFChars(env, newFilename, newFilenameUTF8);
//}
JNIEXPORT jint JNICALL Java_com_regis_cosnier_emu48_NativeLib_getCurrentModel(JNIEnv *env, jobject thisz) {
return cCurrentRomType;
}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileNew(JNIEnv *env, jobject thisz) {
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileNew(JNIEnv *env, jobject thisz, jstring kmlFilename) {
//OnFileNew();
if (bDocumentAvail)
{
@ -242,11 +186,19 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileNew(JNIEnv *
SaveDocument();
}
}
const char *filenameUTF8 = (*env)->GetStringUTFChars(env, kmlFilename , NULL) ;
_tcscpy(szChosenCurrentKml, filenameUTF8);
if (NewDocument()) SetWindowTitle(_T("Untitled"));
mainViewResizeCallback(nBackgroundW, nBackgroundH);
draw();
if (bStartupBackup) SaveBackup(); // make a RAM backup at startup
if (pbyRom) SwitchToState(SM_RUN);
}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileOpen(JNIEnv *env, jobject thisz, jstring filename) {
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileOpen(JNIEnv *env, jobject thisz, jstring stateFilename) {
//OnFileOpen();
if (bDocumentAvail)
{
@ -255,13 +207,14 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileOpen(JNIEnv
SaveDocument();
}
}
const char *filenameUTF8 = (*env)->GetStringUTFChars(env, filename , NULL) ;
_tcscpy(szBufferFilename, filenameUTF8);
const char *stateFilenameUTF8 = (*env)->GetStringUTFChars(env, stateFilename , NULL) ;
_tcscpy(szBufferFilename, stateFilenameUTF8);
if (OpenDocument(szBufferFilename))
MruAdd(szBufferFilename);
(*env)->ReleaseStringUTFChars(env, filename, filenameUTF8);
mainViewResizeCallback(nBackgroundW, nBackgroundH);
if (pbyRom) SwitchToState(SM_RUN);
draw();
(*env)->ReleaseStringUTFChars(env, stateFilename, stateFilenameUTF8);
}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileSave(JNIEnv *env, jobject thisz) {
// szBufferFilename must be set before calling that!!!
@ -274,13 +227,13 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileSave(JNIEnv
}
}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileSaveAs(JNIEnv *env, jobject thisz, jstring newFilename) {
const char *newFilenameUTF8 = (*env)->GetStringUTFChars(env, newFilename , NULL) ;
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileSaveAs(JNIEnv *env, jobject thisz, jstring newStateFilename) {
const char *newStateFilenameUTF8 = (*env)->GetStringUTFChars(env, newStateFilename , NULL) ;
if (bDocumentAvail)
{
SwitchToState(SM_INVALID);
_tcscpy(szBufferFilename, newFilenameUTF8);
_tcscpy(szBufferFilename, newStateFilenameUTF8);
if (SaveDocumentAs(szBufferFilename))
MruAdd(szCurrentFilename);
else {
@ -289,7 +242,7 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileSaveAs(JNIEn
SwitchToState(SM_RUN);
}
(*env)->ReleaseStringUTFChars(env, newFilename, newFilenameUTF8);
(*env)->ReleaseStringUTFChars(env, newStateFilename, newStateFilenameUTF8);
}
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileClose(JNIEnv *env, jobject thisz) {
@ -301,6 +254,8 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onFileClose(JNIEnv
SaveDocument();
ResetDocument();
SetWindowTitle(NULL);
mainViewResizeCallback(nBackgroundW, nBackgroundH);
draw();
}
}

View file

@ -583,10 +583,12 @@ HGLOBAL WINAPI GlobalFree(HGLOBAL hMem) {
}
BOOL GetOpenFileName(LPOPENFILENAME openFilename) {
return mainViewGetOpenFileNameCallback(openFilename);
//return mainViewGetOpenFileNameCallback(openFilename);
return FALSE;
}
BOOL GetSaveFileName(LPOPENFILENAME openFilename) {
return mainViewGetSaveFileNameCallback(openFilename);
//return mainViewGetSaveFileNameCallback(openFilename);
return FALSE;
}
HANDLE LoadImage(HINSTANCE hInst, LPCSTR name, UINT type, int cx, int cy, UINT fuLoad) {
@ -950,6 +952,7 @@ HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppv
// For DIB_RGB_COLORS only
int size = pbmi->bmiHeader.biWidth * abs(pbmi->bmiHeader.biHeight) * 4; //(pbmi->bmiHeader.biBitCount >> 3);
newHDC->bitmapBits = malloc(size); //pbmi->bmiHeader.biSizeImage);
memset(newHDC->bitmapBits, 0, size);
*ppvBits = newHDC->bitmapBits;
return newHDC;
}
@ -1182,11 +1185,12 @@ PIDLIST_ABSOLUTE SHBrowseForFolderA(LPBROWSEINFOA lpbi) {
return NULL;
}
extern TCHAR szCurrentKml[MAX_PATH];
extern TCHAR szChosenCurrentKml[MAX_PATH];
//extern TCHAR szLog[MAX_PATH];
INT_PTR DialogBoxParamA(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) {
//TODO
if(lpTemplateName == MAKEINTRESOURCE(IDD_CHOOSEKML)) {
lstrcpy(szCurrentKml, "real48sx.kml");
lstrcpy(szCurrentKml, szChosenCurrentKml);
} else if(lpTemplateName == MAKEINTRESOURCE(IDD_KMLLOG)) {
//LOGD(szLog);
lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);

View file

@ -1,7 +1,9 @@
package com.regis.cosnier.emu48;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@ -14,6 +16,7 @@ import com.google.android.material.snackbar.Snackbar;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
@ -24,9 +27,18 @@ import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
@ -162,9 +174,103 @@ public class MainActivity extends AppCompatActivity
return true;
}
private void OnFileNew() {
NativeLib.onFileNew();
class KMLScriptItem {
public String filename;
public String title;
public String model;
}
ArrayList<KMLScriptItem> kmlScripts;
private void OnFileNew() {
if(kmlScripts == null) {
kmlScripts = new ArrayList<>();
AssetManager assetManager = getAssets();
String[] calculatorsAssetFilenames = new String[0];
try {
calculatorsAssetFilenames = assetManager.list("calculators");
} catch (IOException e) {
e.printStackTrace();
}
String cKmlType = null; //"S";
kmlScripts.clear();
Pattern patternGlobalTitle = Pattern.compile("\\s*Title\\s+\"(.*)\"");
Pattern patternGlobalModel = Pattern.compile("\\s*Model\\s+\"(.*)\"");
Matcher m;
for (String calculatorsAssetFilename : calculatorsAssetFilenames) {
if (calculatorsAssetFilename.toLowerCase().lastIndexOf(".kml") != -1) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(assetManager.open("calculators/" + calculatorsAssetFilename), "UTF-8"));
// do reading, usually loop until end of file reading
String mLine;
boolean inGlobal = false;
String title = null;
String model = null;
while ((mLine = reader.readLine()) != null) {
//process line
if (mLine.indexOf("Global") == 0) {
inGlobal = true;
title = null;
model = null;
continue;
}
if (inGlobal) {
if (mLine.indexOf("End") == 0) {
KMLScriptItem newKMLScriptItem = new KMLScriptItem();
newKMLScriptItem.filename = calculatorsAssetFilename;
newKMLScriptItem.title = title;
newKMLScriptItem.model = model;
kmlScripts.add(newKMLScriptItem);
title = null;
model = null;
break;
}
m = patternGlobalTitle.matcher(mLine);
if (m.find()) {
title = m.group(1);
}
m = patternGlobalModel.matcher(mLine);
if (m.find()) {
model = m.group(1);
}
}
}
} catch (IOException e) {
//log the exception
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
}
}
}
}
}
Collections.sort(kmlScripts, new Comparator<KMLScriptItem>() {
@Override
public int compare(KMLScriptItem lhs, KMLScriptItem rhs) {
return lhs.title.compareTo(rhs.title);
}
});
}
final String[] kmlScriptTitles = new String[kmlScripts.size()];
for (int i = 0; i < kmlScripts.size(); i++)
kmlScriptTitles[i] = kmlScripts.get(i).title;
new AlertDialog.Builder(this)
.setTitle("Pick a calculator")
.setItems(kmlScriptTitles, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String kmlScriptFilename = kmlScripts.get(which).filename;
NativeLib.onFileNew(kmlScriptFilename);
}
}).show();
}
public static int INTENT_GETOPENFILENAME = 1;
@ -175,9 +281,8 @@ public class MainActivity extends AppCompatActivity
intent.addCategory(Intent.CATEGORY_OPENABLE);
//intent.setType("YOUR FILETYPE"); //not needed, but maybe usefull
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, "emu48-state.e48"); //not needed, but maybe usefull
intent.putExtra(Intent.EXTRA_TITLE, "emu48-state.e48");
startActivityForResult(intent, INTENT_GETOPENFILENAME);
}
private void OnFileSave() {
NativeLib.onFileSave();
@ -185,9 +290,22 @@ public class MainActivity extends AppCompatActivity
private void OnFileSaveAs() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
//intent.setType("YOUR FILETYPE"); //not needed, but maybe usefull
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, "emu48-state.e48"); //not needed, but maybe usefull
int model = NativeLib.getCurrentModel();
String extension = "e48"; // HP48SX/GX
switch (model) {
case '6':
case 'A':
extension = "e38"; // HP38G
break;
case 'E':
extension = "e39"; // HP39/40G
break;
case 'X':
extension = "e49"; // HP49G
break;
}
intent.putExtra(Intent.EXTRA_TITLE, "emu48-state." + extension);
startActivityForResult(intent, INTENT_GETSAVEFILENAME);
}
private void OnFileClose() {
@ -207,6 +325,7 @@ public class MainActivity extends AppCompatActivity
}
private void OnStackCopy() {
//https://developer.android.com/guide/topics/text/copy-paste
NativeLib.onStackCopy();
}

View file

@ -3,13 +3,11 @@ package com.regis.cosnier.emu48;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import androidx.core.view.ViewCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
@ -30,13 +28,13 @@ public class MainScreenView extends SurfaceView {
public MainScreenView(Context context) {
super(context);
AssetManager mgr = getResources().getAssets();
AssetManager assetManager = getResources().getAssets();
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
bitmapMainScreen = Bitmap.createBitmap(displayMetrics.widthPixels, displayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
bitmapMainScreen.eraseColor(Color.LTGRAY);
NativeLib.start(mgr, bitmapMainScreen, (MainActivity)context, this);
bitmapMainScreen.eraseColor(Color.BLACK);
NativeLib.start(assetManager, bitmapMainScreen, (MainActivity)context, this);
vkmap = new HashMap<Integer, Integer>();
vkmap.put(KeyEvent.KEYCODE_BACK, 0x08); // VK_BACK
@ -202,6 +200,10 @@ public class MainScreenView extends SurfaceView {
protected void onSizeChanged(int viewWidth, int viewHeight, int oldViewWidth, int oldViewHeight) {
super.onSizeChanged(viewWidth, viewHeight, oldViewWidth, oldViewHeight);
calcTranslateAndScale(viewWidth, viewHeight);
}
private void calcTranslateAndScale(int viewWidth, int viewHeight) {
float imageSizeX = bitmapMainScreen.getWidth();
float imageSizeY = bitmapMainScreen.getHeight();
@ -224,8 +226,6 @@ public class MainScreenView extends SurfaceView {
screenOffsetX = translateX;
screenOffsetY = translateY;
}
//NativeLib.resize(viewWidth, viewHeight);
}
@Override
@ -248,8 +248,9 @@ public class MainScreenView extends SurfaceView {
break;
case CALLBACK_TYPE_WINDOW_RESIZE:
// New Bitmap size
bitmapMainScreen.reconfigure(/* x */ param1, /* y */ param2, Bitmap.Config.ARGB_8888);
bitmapMainScreen.eraseColor(Color.LTGRAY);
bitmapMainScreen.reconfigure(/* x */ Math.max(1, param1), /* y */ Math.max(1, param2), Bitmap.Config.ARGB_8888);
bitmapMainScreen.eraseColor(Color.BLACK);
calcTranslateAndScale(getWidth(), getHeight());
break;
}
return -1;

View file

@ -22,9 +22,10 @@ public class NativeLib {
public static native void keyUp(int virtKey);
public static native String getCurrentFilename();
//public static native String getCurrentFilename();
public static native int getCurrentModel();
public static native void onFileNew();
public static native void onFileNew(String kmlFilename);
public static native void onFileOpen(String filename);
public static native void onFileSave();
public static native void onFileSaveAs(String newFilename);