mirror of
https://github.com/dgis/emu48android
synced 2024-12-26 09:58:49 +01:00
- Add a RAM card generator for the port 2 of the HP48SX and HP48GX.
- Add the possibility to hide the status and/or the navigation bars.
This commit is contained in:
parent
7679d2d460
commit
32bc5a0983
18 changed files with 255 additions and 63 deletions
28
ReadMe.txt
28
ReadMe.txt
|
@ -1,5 +1,8 @@
|
|||
DESCRIPTION
|
||||
|
||||
WARNING: WITH VERSION 1.3, THE STATUS FILE HAS BEEN MODIFIED AND IS NOW FULLY COMPATIBLE WITH THE WINDOWS VERSION AS IT SHOULD HAVE BEEN.
|
||||
HOWEVER, BEFORE THE UPDATE, BACK UP YOUR DATA BECAUSE YOU COULD LOSE THEM.
|
||||
|
||||
This project ports the Windows application Emu48 written in C to Android.
|
||||
It uses the Android NDK. The former Emu48 source code remains untouched because of a thin win32 emulation layer above Linux/NDK!
|
||||
This win32 layer will allow to easily update from the original Emu48 source code.
|
||||
|
@ -24,11 +27,22 @@ QUICK START
|
|||
NOTES
|
||||
|
||||
- When using a custom KML script by selecting a folder, you must take care of the case sensitivity of its dependency files.
|
||||
- By default, in Emu48 for Windows with the HP49/50, the "HKEY_CURRENT_USER\Software\Emu48\ROM[Writeable]=1",
|
||||
which allows to write the port2 (128KB) in the ROM! Because in Android, it is not possible to write in the embedded ROM,
|
||||
we have the same behavior as under Windows with "HKEY_CURRENT_USER\Software\Emu48\ROM[Writeable]=0".
|
||||
The port 2 is well saved in the state file "*.e49", but once this state file is reloaded,
|
||||
this causes a warmstart and the port 2 is never loaded.
|
||||
- Starting with the version 1.4, a RAM card generator for the port 2 of the HP48SX and HP48GX has been added.
|
||||
Like with the MKSHARED.EXE on Windows, you can generate the card in a file (i.e.: SHARED.BIN).
|
||||
And then, to use with the HP48SX or the HP48GX, you must select this generated file in the "Settings/Port2 File".
|
||||
- By default when you create a new HP49/50 with the embedded readonly file "rom.49g",
|
||||
everything that you store in port 2 is lost just because the file "rom.49g" is READONLY.
|
||||
But it works exactly like with Windows. If you can write in the ROM file,
|
||||
it should save the content of port 2 in the ROM file with Android too.
|
||||
To save the port 2 in the HP49/50 with Emu48 for Android:
|
||||
* copy "real50g-lc.kml", "real50g-lc.png", "keyb4950.kmi", "rom.49g" in a FOLDER of your Android device,
|
||||
* in the menu:
|
||||
- touch "New..." to create a new device
|
||||
- or touch "Change KML Script..." to change the current KML script and ROM location
|
||||
* select "[Custom KML script...]"
|
||||
* select the FOLDER
|
||||
* pick the calculator (which should be "Eric's Real 50g (Large Cropped)")!
|
||||
And because, the file "FOLDER/rom.49g" is not readonly anymore, you can save your port 2.
|
||||
|
||||
|
||||
NOT WORKING YET
|
||||
|
@ -44,9 +58,11 @@ CHANGES
|
|||
|
||||
Version 1.4 (2019-04-xx)
|
||||
|
||||
- Add a RAM card generator for the port 2 of the HP48SX and HP48GX.
|
||||
- Add the possibility to hide the status and/or the navigation bars.
|
||||
- Update the Win32 layer.
|
||||
- Fix the authentic speed issue at the first start.
|
||||
- Fix the non working Restore/Delete backup.
|
||||
- Update the Win32 layer.
|
||||
|
||||
|
||||
Version 1.3 (2019-04-04)
|
||||
|
|
|
@ -20,6 +20,7 @@ cmake_minimum_required(VERSION 3.4.1)
|
|||
|
||||
#add_compile_options(-DNEW_WIN32_SOUND_ENGINE)
|
||||
|
||||
add_compile_options(-DEMUXX=48)
|
||||
|
||||
include_directories(src/main/cpp/win32)
|
||||
|
||||
|
@ -72,8 +73,8 @@ add_library( # Sets the name of the library.
|
|||
|
||||
src/main/cpp/win32-layer.c
|
||||
src/main/cpp/android-layer.c
|
||||
src/main/cpp/android-emu48.c # Emu48.c rewrite
|
||||
src/main/cpp/emu48-jni.c
|
||||
src/main/cpp/android-emu.c # Emu48.c rewrite
|
||||
src/main/cpp/emu-jni.c
|
||||
)
|
||||
|
||||
# Specifies libraries CMake should link to your target library. You
|
||||
|
|
|
@ -33,8 +33,8 @@ android {
|
|||
applicationId "org.emulator.forty.eight"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 28
|
||||
versionCode 4
|
||||
versionName "1.3"
|
||||
versionCode 5
|
||||
versionName "1.4"
|
||||
setProperty("archivesBaseName", "Emu48-v$versionName")
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
|
@ -76,11 +76,11 @@ android {
|
|||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha5'
|
||||
implementation 'androidx.preference:preference:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.1.0-alpha04'
|
||||
implementation 'com.google.android.material:material:1.1.0-alpha05'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.2-alpha02'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0-alpha04'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha04'
|
||||
}
|
||||
|
|
|
@ -27,11 +27,23 @@ QUICK START
|
|||
NOTES
|
||||
|
||||
- When using a custom KML script by selecting a folder, you must take care of the case sensitivity of its dependency files.
|
||||
- By default, in Emu48 for Windows with the HP49/50, the "HKEY_CURRENT_USER\Software\Emu48\ROM[Writeable]=1",
|
||||
which allows to write the port2 (128KB) in the ROM! Because in Android, it is not possible to write in the embedded ROM,
|
||||
we have the same behavior as under Windows with "HKEY_CURRENT_USER\Software\Emu48\ROM[Writeable]=0".
|
||||
The port 2 is well saved in the state file "*.e49", but once this state file is reloaded,
|
||||
this causes a warmstart and the port 2 is never loaded.
|
||||
- Starting with the version 1.4, a RAM card generator for the port 2 of the HP48SX and HP48GX has been added.
|
||||
Like with the MKSHARED.EXE on Windows, you can generate the card in a file (i.e.: SHARED.BIN).
|
||||
And then, to use with the HP48SX or the HP48GX, you must select this generated file in the "Settings/Port2 File".
|
||||
- By default when you create a new HP49/50 with the embedded readonly file "rom.49g",
|
||||
everything that you store in port 2 is lost just because the file "rom.49g" is READONLY.
|
||||
But it works exactly like with Windows. If you can write in the ROM file,
|
||||
it should save the content of port 2 in the ROM file with Android too.
|
||||
To save the port 2 in the HP49/50 with Emu48 for Android:
|
||||
* copy "real50g-lc.kml", "real50g-lc.png", "keyb4950.kmi", "rom.49g" in a FOLDER of your Android device,
|
||||
* in the menu:
|
||||
- touch "New..." to create a new device
|
||||
- or touch "Change KML Script..." to change the current KML script and ROM location
|
||||
* select "[Custom KML script...]"
|
||||
* select the FOLDER
|
||||
* pick the calculator (which should be "Eric's Real 50g (Large Cropped)")!
|
||||
And because, the file "FOLDER/rom.49g" is not readonly anymore, you can save your port 2.
|
||||
|
||||
|
||||
NOT WORKING YET
|
||||
|
||||
|
@ -46,6 +58,9 @@ CHANGES
|
|||
|
||||
Version 1.4 (2019-04-xx)
|
||||
|
||||
- Add a RAM card generator for the port 2 of the HP48SX and HP48GX.
|
||||
- Add the possibility to hide the status and/or the navigation bars.
|
||||
- Update the Win32 layer.
|
||||
- Fix the authentic speed issue at the first start.
|
||||
- Fix the non working Restore/Delete backup.
|
||||
|
||||
|
@ -110,4 +125,4 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Note: some included files are not covered by the GPL; these include ROM image files (copyrighted by HP), KML files and faceplate images (copyrighted by their authors).
|
||||
The Eric's Real scripts ("real*.kml" and "real*.bmp") are embedded in this application with the kind permission of Eric Rechlin.
|
||||
The Eric's Real scripts ("real*.kml" and "real*.bmp") are embedded in this application with the kind permission of Eric Rechlin.
|
||||
|
|
|
@ -90,7 +90,7 @@ static LRESULT OnPaint(HWND hWindow)
|
|||
PAINTSTRUCT Paint;
|
||||
HDC hPaintDC;
|
||||
|
||||
PAINT_LOGD("Emu48-PAINT OnPaint()");
|
||||
PAINT_LOGD("PAINT OnPaint()");
|
||||
|
||||
//UpdateWindowBars(); // update visibility of title and menu bar
|
||||
|
||||
|
@ -108,7 +108,7 @@ static LRESULT OnPaint(HWND hWindow)
|
|||
UINT nLines = MAINSCREENHEIGHT;
|
||||
|
||||
// redraw background bitmap
|
||||
PAINT_LOGD("Emu48-PAINT OnPaint() BitBlt()");
|
||||
PAINT_LOGD("PAINT OnPaint() BitBlt()");
|
||||
BitBlt(hPaintDC, Paint.rcPaint.left, Paint.rcPaint.top,
|
||||
Paint.rcPaint.right-Paint.rcPaint.left, Paint.rcPaint.bottom-Paint.rcPaint.top,
|
||||
hMainDC, rcMainPaint.left, rcMainPaint.top, SRCCOPY);
|
|
@ -803,7 +803,7 @@ JNIEXPORT void JNICALL Java_org_emulator_forty_eight_NativeLib_onViewReset(JNIEn
|
|||
SwitchToState(SM_RUN);
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL Java_org_emulator_forty_eight_NativeLib_onViewScript(JNIEnv *env, jobject thisz, jstring kmlFilename) {
|
||||
JNIEXPORT jint JNICALL Java_org_emulator_forty_eight_NativeLib_onViewScript(JNIEnv *env, jobject thisz, jstring kmlFilename) {
|
||||
|
||||
TCHAR szKmlFile[MAX_PATH];
|
||||
// BOOL bKMLChanged,bSucc;
|
|
@ -14,7 +14,6 @@ extern JavaVM *java_machine;
|
|||
extern jobject bitmapMainScreen;
|
||||
extern AndroidBitmapInfo androidBitmapInfo;
|
||||
|
||||
|
||||
HANDLE hWnd;
|
||||
LPTSTR szTitle;
|
||||
LPTSTR szCurrentAssetDirectory = NULL;
|
||||
|
@ -94,12 +93,14 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
{
|
||||
FILE_LOGD("CreateFile(lpFileName: \"%s\", dwDesiredAccess: 0x%08x)", lpFileName, dwShareMode);
|
||||
BOOL forceNormalFile = FALSE;
|
||||
// if(_tcscmp(lpFileName, szPort2Filename) == 0) {
|
||||
// // Special case for Port2 filename
|
||||
// forceNormalFile = TRUE;
|
||||
// if(!settingsPort2wr && (dwDesiredAccess & GENERIC_WRITE))
|
||||
// return (HANDLE) INVALID_HANDLE_VALUE;
|
||||
// }
|
||||
#if EMUXX == 48
|
||||
if(_tcscmp(lpFileName, szPort2Filename) == 0) {
|
||||
// Special case for Port2 filename
|
||||
forceNormalFile = TRUE;
|
||||
if(!settingsPort2wr && (dwDesiredAccess & GENERIC_WRITE))
|
||||
return (HANDLE) INVALID_HANDLE_VALUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
TCHAR * foundDocumentScheme = _tcsstr(lpFileName, documentScheme);
|
||||
|
||||
|
@ -117,7 +118,9 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
if(filename) {
|
||||
*filename = _T('\0');
|
||||
}
|
||||
//_tcscpy(szRomDirectory, szEmuDirectory);
|
||||
#if EMUXX == 48
|
||||
_tcscpy(szRomDirectory, szEmuDirectory);
|
||||
#endif
|
||||
SetCurrentDirectory(szEmuDirectory);
|
||||
} else if(foundDocumentScheme) {
|
||||
// With a recorded "document:" scheme, extract the folder URL with content:// scheme
|
||||
|
@ -126,11 +129,15 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
if(filename) {
|
||||
*filename = _T('\0');
|
||||
}
|
||||
//_tcscpy(szRomDirectory, szEmuDirectory);
|
||||
#if EMUXX == 48
|
||||
_tcscpy(szRomDirectory, szEmuDirectory);
|
||||
#endif
|
||||
SetCurrentDirectory(szEmuDirectory);
|
||||
} else {
|
||||
_tcscpy(szEmuDirectory, "assets/calculators/");
|
||||
//_tcscpy(szRomDirectory, "assets/calculators/");
|
||||
#if EMUXX == 48
|
||||
_tcscpy(szRomDirectory, "assets/calculators/");
|
||||
#endif
|
||||
SetCurrentDirectory(szEmuDirectory);
|
||||
}
|
||||
}
|
||||
|
@ -902,6 +909,9 @@ void onPlayerDoneTimerCallback(void *context) {
|
|||
WAVE_OUT_LOGD("waveOut onPlayerDoneTimerCallback()");
|
||||
HWAVEOUT hwo = context;
|
||||
onPlayerDone(hwo);
|
||||
|
||||
//TODO May be needed if an attached occurs in the future
|
||||
//jniDetachCurrentThread();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2151,6 +2161,8 @@ void timerCallback(int timerId) {
|
|||
TIMER_LOGD("timerCallback remove timer uTimerID [%d]", timerId + 1);
|
||||
deleteTimeEvent((UINT) (timerId + 1));
|
||||
}
|
||||
|
||||
jniDetachCurrentThread();
|
||||
}
|
||||
}
|
||||
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent) {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <android/bitmap.h>
|
||||
#include <android/asset_manager.h>
|
||||
#include <android/log.h>
|
||||
#define LOG_TAG "NDK_NativeEmu48"
|
||||
#define LOG_TAG "NDK_NativeEmuXX"
|
||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
|
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.emulator.forty.eight;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
|
@ -24,20 +25,34 @@ import android.view.SubMenu;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
@ -52,17 +67,6 @@ import java.util.Set;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.content.FileProvider;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
||||
|
||||
private static final String TAG = "MainActivity";
|
||||
|
@ -81,12 +85,15 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
public static final int INTENT_PICK_KML_FOLDER_FOR_NEW_FILE = 7;
|
||||
public static final int INTENT_PICK_KML_FOLDER_FOR_CHANGING = 8;
|
||||
public static final int INTENT_PICK_KML_FOLDER_FOR_SETTINGS = 9;
|
||||
public static final int INTENT_CREATE_RAM_CARD = 10;
|
||||
|
||||
private String kmlMimeType = "application/vnd.google-earth.kml+xml";
|
||||
private boolean kmlFolderUseDefault = true;
|
||||
private String kmlFolderURL = "";
|
||||
private boolean kmFolderChange = true;
|
||||
|
||||
private int selectedRAMSize = -1;
|
||||
|
||||
private int MRU_ID_START = 10000;
|
||||
private int MAX_MRU = 5;
|
||||
private LinkedHashMap<String, String> mruLinkedHashMap = new LinkedHashMap<String, String>(5, 1.0f, true) {
|
||||
|
@ -245,7 +252,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||
if (drawer.isDrawerOpen(GravityCompat.START)) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
} else {
|
||||
|
@ -312,6 +318,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
OnBackupDelete();
|
||||
} else if (id == R.id.nav_change_kml_script) {
|
||||
OnViewScript();
|
||||
} else if (id == R.id.nav_create_ram_card) {
|
||||
OnCreateRAMCard();
|
||||
} else if (id == R.id.nav_help) {
|
||||
OnTopics();
|
||||
} else if (id == R.id.nav_about) {
|
||||
|
@ -337,7 +345,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
|
||||
}
|
||||
|
||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
|
@ -615,6 +622,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
case 'S': //HP48SX
|
||||
case 'G': //HP48GX
|
||||
extension = "e48";
|
||||
break;
|
||||
case '6': //HP38G 64K RAM
|
||||
case 'A': //HP38G 32K RAM
|
||||
extension = "e38";
|
||||
|
@ -814,6 +822,54 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
}).show();
|
||||
}
|
||||
|
||||
private void OnCreateRAMCard() {
|
||||
String[] stringArrayRAMCards = getResources().getStringArray(R.array.ram_cards);
|
||||
new AlertDialog.Builder(MainActivity.this)
|
||||
.setTitle(getResources().getString(R.string.create_ram_card_title))
|
||||
.setItems(stringArrayRAMCards, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
String sizeTitle = "2mb";
|
||||
selectedRAMSize = -1;
|
||||
switch (which) {
|
||||
case 0: // 32kb (1 port: 2)
|
||||
sizeTitle = "32kb";
|
||||
selectedRAMSize = 32;
|
||||
break;
|
||||
case 1: // 128kb (1 port: 2)
|
||||
sizeTitle = "128kb";
|
||||
selectedRAMSize = 128;
|
||||
break;
|
||||
case 2: // 256kb (2 ports: 2,3)
|
||||
sizeTitle = "256kb";
|
||||
selectedRAMSize = 256;
|
||||
break;
|
||||
case 3: // 512kb (4 ports: 2 through 5)
|
||||
sizeTitle = "512kb";
|
||||
selectedRAMSize = 512;
|
||||
break;
|
||||
case 4: // 1mb (8 ports: 2 through 9)
|
||||
sizeTitle = "1mb";
|
||||
selectedRAMSize = 1024;
|
||||
break;
|
||||
case 5: // 2mb (16 ports: 2 through 17)
|
||||
sizeTitle = "2mb";
|
||||
selectedRAMSize = 2048;
|
||||
break;
|
||||
case 6: // 4mb (32 ports: 2 through 33)
|
||||
sizeTitle = "4mb";
|
||||
selectedRAMSize = 4096;
|
||||
break;
|
||||
}
|
||||
intent.putExtra(Intent.EXTRA_TITLE, "shared-" + sizeTitle + ".bin");
|
||||
startActivityForResult(intent, INTENT_CREATE_RAM_CARD);
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void OnTopics() {
|
||||
startActivity(new Intent(this, InfoWebActivity.class));
|
||||
}
|
||||
|
@ -910,6 +966,30 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
}
|
||||
break;
|
||||
}
|
||||
case INTENT_CREATE_RAM_CARD: {
|
||||
//Log.d(TAG, "onActivityResult INTENT_CREATE_RAM_CARD " + url);
|
||||
if(selectedRAMSize > 0) {
|
||||
int size = 2 * selectedRAMSize;
|
||||
FileOutputStream fileOutputStream = null;
|
||||
try {
|
||||
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "w");
|
||||
fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
|
||||
byte[] zero = new byte[1024];
|
||||
Arrays.fill(zero, (byte) 0);
|
||||
for (int i = 0; i < size; i++)
|
||||
fileOutputStream.write(zero);
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
selectedRAMSize = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1208,7 +1288,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
if(key == null) {
|
||||
String[] settingKeys = {
|
||||
"settings_realspeed", "settings_grayscale", "settings_allow_rotation", "settings_fill_screen",
|
||||
"settings_scale", "settings_allow_sound", "settings_haptic_feedback",
|
||||
"settings_hide_bar", "settings_scale", "settings_allow_sound", "settings_haptic_feedback",
|
||||
"settings_background_kml_color", "settings_background_fallback_color",
|
||||
"settings_kml", "settings_port1", "settings_port2" };
|
||||
for (String settingKey : settingKeys) {
|
||||
|
@ -1232,6 +1312,15 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
case "settings_fill_screen":
|
||||
mainScreenView.setFillScreen(sharedPreferences.getBoolean("settings_fill_screen", false));
|
||||
break;
|
||||
case "settings_hide_bar":
|
||||
case "settings_hide_bar_status":
|
||||
case "settings_hide_bar_nav":
|
||||
if(sharedPreferences.getBoolean("settings_hide_bar_status", false)
|
||||
|| sharedPreferences.getBoolean("settings_hide_bar_nav", false))
|
||||
hideSystemUI();
|
||||
else
|
||||
showSystemUI();
|
||||
break;
|
||||
case "settings_scale":
|
||||
//mainScreenView.setScale(1.0f); //sharedPreferences.getFloat("settings_scale", 0.0f));
|
||||
break;
|
||||
|
@ -1288,4 +1377,29 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus && (
|
||||
sharedPreferences.getBoolean("settings_hide_bar_status", false)
|
||||
|| sharedPreferences.getBoolean("settings_hide_bar_nav", false)
|
||||
)) {
|
||||
hideSystemUI();
|
||||
}
|
||||
}
|
||||
|
||||
private void hideSystemUI() {
|
||||
int flags = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
if(sharedPreferences.getBoolean("settings_hide_bar_status", false))
|
||||
flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
if(sharedPreferences.getBoolean("settings_hide_bar_nav", false))
|
||||
flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
|
||||
|
||||
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
}
|
||||
|
||||
private void showSystemUI() {
|
||||
getWindow().getDecorView().setSystemUiVisibility(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ public class MainScreenView extends SurfaceView {
|
|||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
//Log.d(TAG, "Emu48-PAINT onDraw() mIsScaling: " + mIsScaling + ", mIsPanning: " + mIsPanning + ", mIsFlinging: " + mIsFlinging);
|
||||
//Log.d(TAG, "PAINT onDraw() mIsScaling: " + mIsScaling + ", mIsPanning: " + mIsPanning + ", mIsFlinging: " + mIsFlinging);
|
||||
|
||||
canvas.drawColor(getBackgroundColor());
|
||||
|
||||
|
@ -242,13 +242,13 @@ public class MainScreenView extends SurfaceView {
|
|||
int updateCallback(int type, int param1, int param2, String param3, String param4) {
|
||||
switch (type) {
|
||||
case CALLBACK_TYPE_INVALIDATE:
|
||||
//Log.d(TAG, "Emu48-PAINT updateCallback() postInvalidate()");
|
||||
//Log.d(TAG, "PAINT updateCallback() postInvalidate()");
|
||||
postInvalidate();
|
||||
break;
|
||||
case CALLBACK_TYPE_WINDOW_RESIZE:
|
||||
// New Bitmap size
|
||||
if(bitmapMainScreen == null || bitmapMainScreen.getWidth() != param1 || bitmapMainScreen.getHeight() != param2) {
|
||||
//Log.d(TAG, "Emu48-PAINT updateCallback() Bitmap.createBitmap(x: " + Math.max(1, param1) + ", y: " + Math.max(1, param2) + ")");
|
||||
//Log.d(TAG, "PAINT updateCallback() Bitmap.createBitmap(x: " + Math.max(1, param1) + ", y: " + Math.max(1, param2) + ")");
|
||||
Bitmap oldBitmapMainScreen = bitmapMainScreen;
|
||||
bitmapMainScreen = Bitmap.createBitmap(Math.max(1, param1), Math.max(1, param2), Bitmap.Config.ARGB_8888);
|
||||
int globalColor = NativeLib.getGlobalColor();
|
||||
|
|
9
app/src/main/res/drawable/ic_memory_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_memory_black_24dp.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15,9L9,9v6h6L15,9zM13,13h-2v-2h2v2zM21,11L21,9h-2L19,7c0,-1.1 -0.9,-2 -2,-2h-2L15,3h-2v2h-2L11,3L9,3v2L7,5c-1.1,0 -2,0.9 -2,2v2L3,9v2h2v2L3,13v2h2v2c0,1.1 0.9,2 2,2h2v2h2v-2h2v2h2v-2h2c1.1,0 2,-0.9 2,-2v-2h2v-2h-2v-2h2zM17,17L7,17L7,7h10v10z"/>
|
||||
</vector>
|
|
@ -6,8 +6,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="org.emulator.forty.eight.MainActivity"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:openDrawer="start">
|
||||
<!--android:fitsSystemWindows="true"-->
|
||||
|
||||
<include
|
||||
layout="@layout/app_bar_main"
|
||||
|
|
|
@ -24,13 +24,4 @@
|
|||
|
||||
<include layout="@layout/content_main" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:visibility="gone"
|
||||
app:srcCompat="@android:drawable/ic_dialog_email" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -90,6 +90,14 @@
|
|||
android:title="@string/nav_change_kml_script" />
|
||||
</menu>
|
||||
</item>
|
||||
<item android:title="@string/nav_tool">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/nav_create_ram_card"
|
||||
android:icon="@drawable/ic_memory_black_24dp"
|
||||
android:title="@string/nav_create_ram_card" />
|
||||
</menu>
|
||||
</item>
|
||||
<item android:title="@string/nav_help">
|
||||
<menu>
|
||||
<item
|
||||
|
|
|
@ -12,4 +12,14 @@
|
|||
<!--<item>2</item>-->
|
||||
</string-array>
|
||||
|
||||
<string-array name="ram_cards">
|
||||
<item>32kb (1 port: 2)</item>
|
||||
<item>128kb (1 port: 2)</item>
|
||||
<item>256kb (2 ports: 2,3)</item>
|
||||
<item>512kb (4 ports: 2 through 5)</item>
|
||||
<item>1mb (8 ports: 2 through 9)</item>
|
||||
<item>2mb (16 ports: 2 through 17)</item>
|
||||
<item>4mb (32 ports: 2 through 33)</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
|
@ -4,5 +4,4 @@
|
|||
<!--<dimen name="activity_vertical_margin">16dp</dimen>-->
|
||||
<dimen name="nav_header_vertical_spacing">8dp</dimen>
|
||||
<!--<dimen name="nav_header_height">176dp</dimen>-->
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -40,12 +40,19 @@
|
|||
<string name="nav_delete_backup">Delete Backup</string>
|
||||
<string name="nav_view">View</string>
|
||||
<string name="nav_change_kml_script">Change KML Script...</string>
|
||||
<string name="nav_tool">Tool</string>
|
||||
<string name="nav_create_ram_card">Create RAM Card...</string>
|
||||
<string name="nav_help">Help</string>
|
||||
<string name="nav_item_help">Help</string>
|
||||
<string name="nav_about">About Emu48...</string>
|
||||
|
||||
<string name="load_custom_kml">[Custom KML script...]</string>
|
||||
<string name="load_default_kml">[Default KML script]</string>
|
||||
<string name="pick_calculator">Pick a calculator</string>
|
||||
|
||||
<string name="create_ram_card_title">Create RAM Card</string>
|
||||
|
||||
|
||||
<string name="message_state_saved">State saved</string>
|
||||
<string name="message_do_you_want_to_save">Do you want to save changes?\n(BACK to cancel)</string>
|
||||
<string name="message_yes">Yes</string>
|
||||
|
@ -64,6 +71,8 @@
|
|||
<string name="settings_alwaysdisplog_title">Always Show KML Compilation Result</string>
|
||||
<string name="settings_allow_rotation_title">Allow rotation</string>
|
||||
<string name="settings_fill_screen_title">Fill screen</string>
|
||||
<string name="settings_hide_bar_status">Hide the status bar</string>
|
||||
<string name="settings_hide_bar_nav">Hide the navigation bar</string>
|
||||
<string name="settings_allow_sound_title">Allow sounds</string>
|
||||
<string name="settings_haptic_feedback_title">Allow haptic feedback</string>
|
||||
<string name="settings_category_background_title">Background Color</string>
|
||||
|
|
|
@ -32,6 +32,14 @@
|
|||
android:key="settings_fill_screen"
|
||||
android:title="@string/settings_fill_screen_title"
|
||||
android:defaultValue="false" />
|
||||
<SwitchPreference
|
||||
android:key="settings_hide_bar_status"
|
||||
android:title="@string/settings_hide_bar_status"
|
||||
android:defaultValue="false" />
|
||||
<SwitchPreference
|
||||
android:key="settings_hide_bar_nav"
|
||||
android:title="@string/settings_hide_bar_nav"
|
||||
android:defaultValue="false" />
|
||||
<SwitchPreference
|
||||
android:key="settings_allow_sound"
|
||||
android:title="@string/settings_allow_sound_title"
|
||||
|
|
Loading…
Reference in a new issue