mirror of
https://github.com/dgis/emu48android
synced 2024-11-16 07:48:08 +01:00
This commit is contained in:
parent
d623bcc609
commit
d17ba8394d
8 changed files with 277 additions and 205 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,3 @@ typedef LONG LONG_PTR, *PLONG_PTR;
|
|||
language='*'\"")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//#define DisplayChooseKml DisplayChooseKmlEx
|
||||
//extern BOOL DisplayChooseKmlEx(CHAR cType);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue