Prevent some calculator to sleep. Fix crash. Attempt to fix haptic feedback.

This commit is contained in:
dgis 2023-06-24 23:32:55 +02:00
parent bc8bd5b821
commit 547d20aed3
46 changed files with 127 additions and 65 deletions

View file

@ -58,6 +58,14 @@ LINKS
CHANGES
Version 2.7 (2022-09-XX)
- Attempt to fix haptic feedback with Android 13 (API deprecation).
- Patch the ROM files to prevent the calculator to sleep for HP38G, HP39G, HP40G, HP48SX and HP48GX.
There is an issue with this patch and the Flashcard for the HP49/50 because an already existing Flashcard embed the non patched ROM file,
and the CRC check failed and make a CPU reset!
- Fix a potential crash about the permission to access the files.
Version 2.6 (2022-08-19)
- Updated source code from Eric Rechlin's Emu48 version 1.64+ that was merged from Christoph Gießelink's Emu48 version 1.65. This new version improve the serial communication.
@ -252,8 +260,16 @@ The Eric's Real scripts ("real*.kml" and "real*.bmp/png") are embedded in this a
Portions of this source code (about the usb-serial) were originally created by Google Inc. in 2011-2013 and Mike Wakerly in 2013.
FAQ
* Can you do something about Android removing access permissions to the state file? I can't run the app for more than a week before the OS takes it away and then I have to create a new state file.
> It should be possible to prevent Android from forgetting the permissions in Google Play Store app, Account/Play Protect/App permissions removed/See apps/All apps/Emu48/"Remove permissions if app isn't used" uncheck.
TODO
- Test XSEND.
- Haptic feedback does not seems to work on Android 13, should check (J. Majors).
- Add an "haptic" feedback with a sound instead of a vibration (F. Giampietro).
- Add a Cancel button to the HP48 memory card creator dialog.
- Manage the HP 48 port 2 with the same kind of interface for the memory card.
- The render pixels are very nice. A solution to obtain uniform pixel size could be a preset (a multiplier, auto) so the user could decide and upscale/downscale (Michael P).

View file

@ -28,22 +28,16 @@ if (keystorePropertiesFile.exists()) {
}
android {
compileSdkVersion 32
namespace 'org.emulator.forty.eight'
compileSdk 33
defaultConfig {
applicationId "org.emulator.forty.eight"
minSdkVersion 19
targetSdkVersion 32
versionCode 25
versionName "2.6"
minSdk 19
targetSdk 33
versionCode 26
versionName "2.7"
setProperty("archivesBaseName", "Emu48-v$versionName")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
//abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
//abiFilters 'x86_64'
//version "3.10.2"
}
}
}
if (canSign) {
@ -71,25 +65,26 @@ android {
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
path file('CMakeLists.txt')
//version '3.18.1'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.preference:preference:1.2.0'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.documentfile:documentfile:1.0.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.emulator.forty.eight">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.usb.host" android:required="false"/>

View file

@ -21,7 +21,7 @@ Global
Author "Casey Patterson && Sebastien Carlier"
Model "G"
Rom "rom.48g"
Patch "BEEP.48"
Patch "PATCHES.48"
Bitmap "cp_48g3.bmp"
Debug 0
End

View file

@ -13,7 +13,7 @@ Global
Author "Casey Patterson"
Model "S"
Rom "rom.48s"
Patch "BEEP.48"
Patch "PATCHES.48"
Bitmap "cp_48s3.bmp"
Debug 0
End

View file

@ -9,7 +9,7 @@ Global
Author "Christoph Giesselink"
Model "A"
Rom "rom.38g"
Patch "BEEP.38G"
Patch "PATCHES.38G"
Debug 0
Bitmap "DEFAUL38.BMP"
End

View file

@ -3,7 +3,7 @@ Global
Author "Sebastien Carlier"
Model "G"
Rom "rom.48g"
Patch "BEEP.48"
Patch "PATCHES.48"
Debug 0
Bitmap "DEFAULTG.BMP"
End

View file

@ -3,7 +3,7 @@ Global
Author "Sebastien Carlier"
Model "S"
Rom "rom.48s"
Patch "BEEP.48"
Patch "PATCHES.48"
Debug 0
Bitmap "DEFAULTS.BMP"
End

View file

@ -13,7 +13,7 @@ Global
Author "Casey Patterson"
Model "G"
Rom "rom.48g"
Patch "BEEP.48"
Patch "PATCHES.48"
Debug 0
Bitmap "float_gx.bmp"
End

View file

@ -3,7 +3,7 @@ Global
Author "Jeffery L. McMahan"
Model "G"
Rom "rom.48g"
Patch "BEEP.48"
Patch "PATCHES.48"
Bitmap "jemac.bmp"
Debug 0
End

View file

@ -0,0 +1,2 @@
014A1:6300; disable 10 min auto off (internal, undocumented)
;017D0:81B1; =makebeep (internal, undocumented)

View file

@ -0,0 +1,3 @@
0148D:6300; disable 10 min auto off (internal, undocumented)
;017BC:81B1; =makebeep (internal, undocumented)
0212D:000; set =BounceTiming to 0 (internal, undocumented)

View file

@ -0,0 +1,2 @@
01477:6300; disable 10 min auto off (internal, undocumented)
;017A6:81B1; =makebeep

View file

@ -0,0 +1,4 @@
;41262:6300; disable 10 min auto off (internal for 1.19-6, undocumented)
412B9:6300; disable 10 min auto off (internal for 1.24/2.09, undocumented)
;4157A:81B1; =makebeep (internal for 1.18/1.19-5/1.19-6, undocumented)
;41609:81B1; =makebeep (internal for 1.24/2.01/2.09, undocumented)

View file

@ -10,7 +10,7 @@ Global
Hardware "Yorke"
Model "G"
Rom "rom.48g"
Patch "BEEP.48"
Patch "PATCHES.48"
Bitmap "Wombat3 48GX.bmp"
Debug 0
End

View file

@ -10,7 +10,7 @@ Global
Hardware "Yorke"
Model "S"
Rom "rom.48s"
Patch "BEEP.48"
Patch "PATCHES.48"
Bitmap "Wombat3 48SX.bmp"
Debug 0
End

View file

@ -11,6 +11,7 @@ Global
Model "Q"
Class 50
Rom "rom.49g"
Patch "PATCHES.49G"
Bitmap "calypso2k.png"
Color 0 0 0 0
#Scale 3 9

View file

@ -11,6 +11,7 @@ Global
Model "Q"
Class 50
Rom "rom.49g"
Patch "PATCHES.49G"
Bitmap "calypso4k.png"
Color 0 0 0 0
#Scale 3 18

View file

@ -15,6 +15,7 @@ Global
Author "Eric Rechlin"
Model "6" # 6 for 64K RAM, A for 32K RAM
Rom "rom.38g"
Patch "PATCHES.38G"
Bitmap "real38g-l.png"
Icon "38g.ico"
Color 0 190 190 190

View file

@ -15,6 +15,7 @@ Global
Author "Eric Rechlin"
Model "6" # 6 for 64K RAM, A for 32K RAM
Rom "rom.38g"
Patch "PATCHES.38G"
Bitmap "real38g-lc.png"
Icon "38g.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 39
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39g-l.png"
Icon "39g.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 39
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39g-lc.png"
Icon "39g.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 39
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39gp-l.png"
Icon "39gp.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 39
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39gp-lc.png"
Icon "39gp.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 39
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39gs-l.png"
Icon "39gs.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 39
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39gs-lc.png"
Icon "39gs.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 40
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real40g-l.png"
Icon "39g.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 40
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real39g-lc.png"
Icon "40g.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 40
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real40gs-l.png"
Icon "40gs.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Model "E"
Class 40
Rom "rom.39g"
Patch "PATCHES.39G"
Bitmap "real40gs-lc.png"
Icon "40gs.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Author "Eric Rechlin"
Model "G"
Rom "rom.48g"
Patch "PATCHES.48"
Bitmap "real48gx-l.png"
Icon "48gx.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Author "Eric Rechlin"
Model "G"
Rom "rom.48g"
Patch "PATCHES.48"
Bitmap "real48gx-lc.png"
Icon "48gx.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Author "Eric Rechlin"
Model "S"
Rom "rom.48s"
Patch "PATCHES.48"
Bitmap "real48sx-l.png"
Icon "48sx.ico"
Color 0 190 190 190

View file

@ -14,6 +14,7 @@ Global
Author "Eric Rechlin"
Model "S"
Rom "rom.48s"
Patch "PATCHES.48"
Bitmap "real48sx-lc.png"
Icon "48sx.ico"
Color 0 190 190 190

View file

@ -521,16 +521,19 @@ JNIEXPORT void JNICALL Java_org_emulator_calculator_NativeLib_stop(JNIEnv *env,
hWindowDC = NULL; // hWindowDC isn't valid any more
hWnd = NULL;
DeleteCriticalSection(&csGDILock);
DeleteCriticalSection(&csLcdLock);
DeleteCriticalSection(&csKeyLock);
DeleteCriticalSection(&csIOLock);
DeleteCriticalSection(&csT1Lock);
DeleteCriticalSection(&csT2Lock);
DeleteCriticalSection(&csTxdLock);
DeleteCriticalSection(&csRecvLock);
DeleteCriticalSection(&csSlowLock);
DeleteCriticalSection(&csDbgLock);
// Prevent crash+++
// FORTIFY: pthread_mutex_destroy called on a destroyed mutex (0x<sanitized>)
// DeleteCriticalSection(&csGDILock);
// DeleteCriticalSection(&csLcdLock);
// DeleteCriticalSection(&csKeyLock);
// DeleteCriticalSection(&csIOLock);
// DeleteCriticalSection(&csT1Lock);
// DeleteCriticalSection(&csT2Lock);
// DeleteCriticalSection(&csTxdLock);
// DeleteCriticalSection(&csRecvLock);
// DeleteCriticalSection(&csSlowLock);
// DeleteCriticalSection(&csDbgLock);
// Prevent crash---
SoundClose(); // close waveform-audio output device
soundEnabled = FALSE;

View file

@ -1879,6 +1879,8 @@ HPALETTE CreatePalette(CONST LOGPALETTE * plpal) {
return handle;
}
HPALETTE SelectPalette(HDC hdc, HPALETTE hPal, BOOL bForceBkgd) {
if(!hdc)
return NULL;
HPALETTE hOldPal = hdc->selectedPalette;
hdc->selectedPalette = hPal;
return hOldPal;

View file

@ -27,8 +27,7 @@ public class EmuApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
customPreferenceDataStore = new Settings(PreferenceManager.getDefaultSharedPreferences(this));
super.onCreate();
}
}

View file

@ -15,8 +15,6 @@
package org.emulator.calculator;
import android.app.Dialog;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.text.util.Linkify;
@ -64,9 +62,7 @@ public class InfoFragment extends AppCompatDialogFragment {
Toolbar toolbar = view.findViewById(Utils.resId(this, "id", "my_toolbar"));
toolbar.setTitle(title);
Utils.colorizeDrawableWithColor(requireContext(), toolbar.getNavigationIcon(), android.R.attr.colorForeground);
toolbar.setNavigationOnClickListener(v -> {
dismiss();
});
toolbar.setNavigationOnClickListener(v -> dismiss());
// Programmatically load text from an asset and place it into the
// text view. Note that the text we are loading is ASCII, so we
@ -92,7 +88,7 @@ public class InfoFragment extends AppCompatDialogFragment {
TextView textViewInfo = view.findViewById(Utils.resId(this, "id", "textViewInfo"));
textViewInfo.setMovementMethod(new ScrollingMovementMethod());
textViewInfo.setText(text);
Linkify.addLinks(textViewInfo, Linkify.ALL);
Linkify.addLinks(textViewInfo, Linkify.WEB_URLS);
} catch (IOException ignored) { }
return view;
}

View file

@ -51,7 +51,7 @@ public class Settings extends PreferenceDataStore {
private final SharedPreferences androidSettings;
// Defined the setting keys which are only defined at the application level.
private List<String> applicationSettingKeys = Arrays.asList("settings_kml_default", "settings_kml_folder", "lastDocument", "MRU");
private final List<String> applicationSettingKeys = Arrays.asList("settings_kml_default", "settings_kml_folder", "lastDocument", "MRU");
// The settings only defined at the application level.
private final HashMap<String, Object> applicationSettings = new HashMap<>();
@ -68,7 +68,7 @@ public class Settings extends PreferenceDataStore {
void onOneKeyChanged(String keyChanged);
}
private OnOneKeyChangedListener oneKeyChangedListener;
private static String magic = "MYHP";
private static final String magic = "MYHP";
@ -307,7 +307,7 @@ public class Settings extends PreferenceDataStore {
HashMap<String, Object> settings = fromJSON(json);
embeddedStateSettings.putAll(settings);
}
} catch (IOException e) {
} catch (IOException | SecurityException e) {
e.printStackTrace();
}
}
@ -316,7 +316,7 @@ public class Settings extends PreferenceDataStore {
commonSettings.clear();
Map<String, ?> keyValuePairs = androidSettings.getAll();
for (String key : keyValuePairs.keySet()) {
if (applicationSettingKeys.indexOf(key) != -1)
if (applicationSettingKeys.contains(key))
applicationSettings.put(key, keyValuePairs.get(key));
else
commonSettings.put(key, keyValuePairs.get(key));

View file

@ -24,6 +24,7 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.OpenableColumns;
@ -101,12 +102,26 @@ public class Utils {
public static void makeUriPersistable(Context context, Intent data, Uri uri) {
int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
try {
context.getContentResolver().takePersistableUriPermission(uri, takeFlags);
} catch (SecurityException e) {
Utils.showAlert(context,
context.getString(Utils.resId(context, "string", "message_persisting_security_error"))
+ e.getMessage(),
true);
}
}
public static void makeUriPersistableReadOnly(Context context, Intent data, Uri uri) {
int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
try {
context.getContentResolver().takePersistableUriPermission(uri, takeFlags);
} catch (SecurityException e) {
Utils.showAlert(context,
context.getString(Utils.resId(context, "string", "message_persisting_security_error"))
+ e.getMessage(),
true);
}
}
public static String getFileName(Context context, String url) {
@ -205,7 +220,10 @@ public class Utils {
public static void vibrate(Vibrator vibrator, int durationInMilliSecond) {
if(vibrator != null && durationInMilliSecond > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
if (Build.VERSION.SDK_INT >= 33)
// https://developer.android.com/reference/android/os/Vibrator#vibrate(android.os.VibrationEffect,%20android.os.VibrationAttributes)
vibrator.vibrate(VibrationEffect.createOneShot(durationInMilliSecond, VibrationAttributes.USAGE_TOUCH));
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
// https://developer.android.com/reference/android/os/Vibrator#vibrate(android.os.VibrationEffect,%20android.media.AudioAttributes)
vibrator.vibrate(VibrationEffect.createOneShot(durationInMilliSecond, VibrationEffect.DEFAULT_AMPLITUDE));
else

View file

@ -130,6 +130,7 @@
<string name="message_printer_out_of_paper">Out of paper error for the graphic printer (max line: %d, max pixel line: %d).</string>
<string name="message_change_overlapping_lcd_mode_to_manual">The overlapping LCD mode has been changed to "Manual".</string>
<string name="message_change_overlapping_lcd_mode_to_auto">The overlapping LCD mode has been changed to "Auto".</string>
<string name="message_persisting_security_error">Permission issue: </string>
<string name="serial_fragment_title">USB Devices</string>
<string name="serial_device_list_header">USB Devices</string>

View file

@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.1'
classpath 'com.android.tools.build:gradle:8.0.2'
// NOTE: Do not place your application dependencies here; they belong

View file

@ -6,9 +6,13 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.defaults.buildfeatures.buildconfig=true
android.enableJetifier=true
android.nonFinalResIds=false
android.nonTransitiveRClass=false
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
org.gradle.unsafe.configuration-cache=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects

View file

@ -1,6 +1,6 @@
#Fri Oct 30 22:52:03 CET 2020
#Sat Jan 28 21:16:38 CET 2023
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME