diff --git a/ReadMe.txt b/ReadMe.txt
index a3c1ecf..c4394a1 100644
--- a/ReadMe.txt
+++ b/ReadMe.txt
@@ -54,6 +54,13 @@ NOT WORKING YET
CHANGES
+Version 1.7 (2019-08-XX)
+
+- Allow to take a screenshot of the fullscreen including the skin.
+- Add the KML Icon if present in the navigation menu header (only support PNG or 32bits BMP in the ICO file).
+- Allow an optional overlapping LCD part stuck to the screen when swiping the 2 calc parts.
+
+
Version 1.6 (2019-07-15)
- Add option to prevent the pinch zoom.
@@ -159,7 +166,6 @@ The Eric's Real scripts ("real*.kml" and "real*.bmp/png") are embedded in this a
TODO
- Retain a key by right clicking if it is from a mouse.
-- Allow screenshot of the fullscreen including the skin.
- Add the name of the file in the toast "State saved".
- Add the KML icon in the navigation menu header.
- Add the possibility to load and save the flash in another file.
diff --git a/app/src/main/cpp/android-layer.c b/app/src/main/cpp/android-layer.c
index 1b8ce5c..f9c10ef 100644
--- a/app/src/main/cpp/android-layer.c
+++ b/app/src/main/cpp/android-layer.c
@@ -15,24 +15,6 @@
#include "core/pch.h"
#include "emu.h"
-// Serial.c
-//BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort) {
-// return 0;
-//}
-//VOID CommClose(VOID) {
-//}
-//VOID CommSetBaud(VOID) {
-//}
-//BOOL UpdateUSRQ(VOID) {
-// return 0;
-//}
-//VOID CommTxBRK(VOID) {
-//}
-//VOID CommTransmit(VOID) {
-//}
-//VOID CommReceive(VOID) {
-//}
-
// udp.c
TCHAR szUdpServer[1024] = _T("localhost");
WORD wUdpPort = 5025; // scpi-raw
diff --git a/app/src/main/cpp/emu-jni.c b/app/src/main/cpp/emu-jni.c
index 14ae503..74c89cd 100644
--- a/app/src/main/cpp/emu-jni.c
+++ b/app/src/main/cpp/emu-jni.c
@@ -439,51 +439,63 @@ JNIEXPORT jboolean JNICALL Java_org_emulator_calculator_NativeLib_copyLCD(JNIEnv
// INT nxSize, nySize;
// GetSizeLcdBitmap(&nxSize,&nySize); // get LCD size
- HDC hSrcDC = hLcdDC; // use display HDC as source
- if(!hSrcDC)
+
+ void *pixelsDestination;
+ if ((ret = AndroidBitmap_lockPixels(env, bitmapLCD, &pixelsDestination)) < 0) {
+ LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return JNI_FALSE;
+ }
+
+ if(hLcdDC && hLcdDC->selectedBitmap) {
+ HBITMAP hBitmapSource = hLcdDC->selectedBitmap;
+ void * pixelsSource = (void *) hBitmapSource->bitmapBits;
+ BOOL reverseHeight = hBitmapSource->bitmapInfoHeader->biHeight < 0;
+
+ int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
+ int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight); // Can be < 0
+
+ UINT sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount;
+ int sourceStride = 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32);
+
+ HPALETTE palette = hLcdDC->realizedPalette;
+ if(!palette)
+ palette = hLcdDC->selectedPalette;
+ PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
+ palette->paletteLog->palPalEntry : NULL;
+ if(!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0)
+ palPalEntry = (PALETTEENTRY *)hBitmapSource->bitmapInfo->bmiColors;
+ int destinationWidth = bitmapLCDInfo.width;
+ int destinationHeight = bitmapLCDInfo.height;
+ int destinationBitCount = 32;
+ int destinationStride = bitmapLCDInfo.stride;
- HBITMAP hBmp = hSrcDC->selectedBitmap;
- if (hBmp && hBmp->bitmapInfoHeader && hBmp->bitmapInfoHeader->biWidth == bitmapLCDInfo.width &&
- abs(hBmp->bitmapInfoHeader->biHeight) == bitmapLCDInfo.height) {
- INT nxO = 0, nyO = 0; // origin in HDC
- void *pixelsDestination;
- if ((ret = AndroidBitmap_lockPixels(env, bitmapLCD, &pixelsDestination)) < 0) {
- LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
- return JNI_FALSE;
- }
-
- // if (nCurrentHardware == HDW_SACA)
- // {
- // TCHAR cBuffer[32]; // temp. buffer for text
- // MSG msg;
- //
- // // calculate bitmap origins from hWindowDC
- // nxO = nLcdX; if (nxO > 1) { nxO -= 2; nxSize += 4; };
- // nyO = nLcdY; if (nyO > 1) { nyO -= 2; nySize += 4; };
- //
- // hSrcDC = hWindowDC; // use output HDC as source
- // }
EnterCriticalSection(&csGDILock); // solving NT GDI problems
+ UINT nLines = MAINSCREENHEIGHT;
- // copy display area
- //BitBlt(hBmpDC,0,0,nxSize,nySize,hSrcDC,nxO,nyO,SRCCOPY);
+ // copy header display area
+ StretchBltInternal(0, 0, 131*nLcdZoom*nGdiXZoom, Chipset.d0size*nLcdZoom*nGdiYZoom, pixelsDestination, destinationBitCount,
+ destinationStride, destinationWidth, destinationHeight,
+ Chipset.d0offset, 0, 131, Chipset.d0size, pixelsSource, sourceBitCount,
+ sourceStride, sourceWidth, sourceHeight,
+ SRCCOPY, reverseHeight, palPalEntry, 0, 0);
+
+
+ // copy main display area
+ StretchBltInternal(0, Chipset.d0size*nLcdZoom*nGdiYZoom, 131*nLcdZoom*nGdiXZoom, nLines*nLcdZoom*nGdiYZoom, pixelsDestination, destinationBitCount,
+ destinationStride, destinationWidth, destinationHeight,
+ Chipset.boffset, Chipset.d0size, 131, nLines, pixelsSource, sourceBitCount,
+ sourceStride, sourceWidth, sourceHeight,
+ SRCCOPY, reverseHeight, palPalEntry, 0, 0);
+ // copy menu display area
+ StretchBltInternal(0, (nLines+Chipset.d0size)*nLcdZoom*nGdiYZoom, 131*nLcdZoom*nGdiXZoom, MENUHEIGHT*nLcdZoom*nGdiYZoom, pixelsDestination, destinationBitCount,
+ destinationStride, destinationWidth, destinationHeight,
+ 0, (nLines+Chipset.d0size), 131, MENUHEIGHT, pixelsSource, sourceBitCount,
+ sourceStride, sourceWidth, sourceHeight,
+ SRCCOPY, reverseHeight, palPalEntry, 0, 0);
- size_t strideSource = ((unsigned int) (4 * ((hBmp->bitmapInfoHeader->biWidth *
- hBmp->bitmapInfoHeader->biBitCount + 31) /
- 32)));
- size_t strideDestination = bitmapLCDInfo.stride;
- VOID *bitmapBitsSource = (VOID *) hBmp->bitmapBits;
- VOID *bitmapBitsDestination = pixelsDestination;
- int biHeight = abs(hBmp->bitmapInfoHeader->biHeight);
- for (int y = 0; y < biHeight; y++) {
- memcpy(bitmapBitsDestination, bitmapBitsSource, strideSource);
- bitmapBitsSource += strideSource;
- bitmapBitsDestination += strideDestination;
- }
LeaveCriticalSection(&csGDILock);
AndroidBitmap_unlockPixels(env, bitmapLCD);
return JNI_TRUE;
diff --git a/app/src/main/cpp/win32-layer.c b/app/src/main/cpp/win32-layer.c
index 84f0959..ba295a1 100644
--- a/app/src/main/cpp/win32-layer.c
+++ b/app/src/main/cpp/win32-layer.c
@@ -1592,6 +1592,15 @@ BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl) {
}
BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl) { return 0; }
extern void draw();
+
+void StretchBltInternal(int xDest, int yDest, int wDest, int hDest, const void *pixelsDestination,
+ int destinationBitCount, int destinationStride, int destinationWidth,
+ int destinationHeight, int xSrc, int ySrc, int hSrc, int wSrc,
+ const void *pixelsSource, UINT sourceBitCount, int sourceStride,
+ int sourceWidth, int sourceHeight, DWORD rop, BOOL reverseHeight,
+ const PALETTEENTRY *palPalEntry, COLORREF brushColor,
+ COLORREF backgroundColor);
+
BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase) {
// Update when switch the screen off
draw(); //TODO Need a true WM_PAINT event!
@@ -1996,23 +2005,44 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
backgroundColor = hdcDest->backgroundColor;
}
- int dst_maxx = xDest + wDest;
- int dst_maxy = yDest + hDest;
+ StretchBltInternal(xDest, yDest, wDest, hDest, pixelsDestination, destinationBitCount,
+ destinationStride, destinationWidth, destinationHeight,
+ xSrc, ySrc, wSrc, hSrc, pixelsSource, sourceBitCount,
+ sourceStride, sourceWidth, sourceHeight,
+ rop, reverseHeight, palPalEntry, brushColor, backgroundColor);
- if(xDest < 0) {
+ if(jniEnv && hdcDest->hdcCompatible == NULL && (ret = AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen)) < 0) {
+ LOGD("AndroidBitmap_unlockPixels() failed ! error=%d", ret);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void StretchBltInternal(int xDest, int yDest, int wDest, int hDest,
+ const void *pixelsDestination, int destinationBitCount, int destinationStride, int destinationWidth, int destinationHeight,
+ int xSrc, int ySrc, int wSrc, int hSrc,
+ const void *pixelsSource, UINT sourceBitCount, int sourceStride, int sourceWidth, int sourceHeight,
+ DWORD rop, BOOL reverseHeight, const PALETTEENTRY *palPalEntry, COLORREF brushColor, COLORREF backgroundColor) {
+ int dst_maxx = xDest + wDest;
+ int dst_maxy = yDest + hDest;
+
+ if(xDest < 0) {
wDest += xDest;
xDest = 0;
}
- if(yDest < 0) {
+ if(yDest < 0) {
hDest += yDest;
yDest = 0;
}
- if(dst_maxx > destinationWidth)
+ if(dst_maxx > destinationWidth)
dst_maxx = destinationWidth;
- if(dst_maxy > destinationHeight)
+ if(dst_maxy > destinationHeight)
dst_maxy = destinationHeight;
- for (int y = yDest; y < dst_maxy; y++) {
+ for (int y = yDest; y < dst_maxy; y++) {
int src_cury = ySrc + (y - yDest) * hSrc / hDest;
if(!reverseHeight)
src_cury = sourceHeight - 1 - src_cury;
@@ -2154,16 +2184,8 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
}
}
}
-
- if(jniEnv && hdcDest->hdcCompatible == NULL && (ret = AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen)) < 0) {
- LOGD("AndroidBitmap_unlockPixels() failed ! error=%d", ret);
- return FALSE;
- }
-
- return TRUE;
- }
- return FALSE;
}
+
UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq) {
if(prgbq
&& hdc && hdc->realizedPalette && hdc->realizedPalette->paletteLog && hdc->realizedPalette->paletteLog->palPalEntry
diff --git a/app/src/main/cpp/win32-layer.h b/app/src/main/cpp/win32-layer.h
index 370f9bd..6a9b557 100644
--- a/app/src/main/cpp/win32-layer.h
+++ b/app/src/main/cpp/win32-layer.h
@@ -720,6 +720,13 @@ extern BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, in
#define HALFTONE 4
extern int SetStretchBltMode(HDC hdc, int mode);
extern BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop);
+extern void StretchBltInternal(int xDest, int yDest, int wDest, int hDest, const void *pixelsDestination,
+ int destinationBitCount, int destinationStride, int destinationWidth,
+ int destinationHeight, int xSrc, int ySrc, int hSrc, int wSrc,
+ const void *pixelsSource, UINT sourceBitCount, int sourceStride,
+ int sourceWidth, int sourceHeight, DWORD rop, BOOL reverseHeight,
+ const PALETTEENTRY *palPalEntry, COLORREF brushColor,
+ COLORREF backgroundColor);
extern UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq);
/* constants for CreateDIBitmap */
#define CBM_INIT 0x04L /* initialize bitmap */
diff --git a/app/src/main/java/org/emulator/calculator/LCDOverlappingView.java b/app/src/main/java/org/emulator/calculator/LCDOverlappingView.java
index a8dfe51..3393e24 100644
--- a/app/src/main/java/org/emulator/calculator/LCDOverlappingView.java
+++ b/app/src/main/java/org/emulator/calculator/LCDOverlappingView.java
@@ -7,6 +7,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Rect;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -21,6 +22,8 @@ public class LCDOverlappingView extends View {
private SharedPreferences sharedPreferences;
private Paint paint = new Paint();
+ private Rect srcBitmapCopy = new Rect();
+ private Rect dstBitmapCopy = new Rect();
private Bitmap bitmapLCD;
private float bitmapRatio = -1;
private float minViewSize = 200.0f;
@@ -35,8 +38,8 @@ public class LCDOverlappingView extends View {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
- paint.setFilterBitmap(true);
- paint.setAntiAlias(true);
+ //paint.setFilterBitmap(true);
+ //paint.setAntiAlias(true);
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
@@ -168,7 +171,7 @@ public class LCDOverlappingView extends View {
protected void onDraw(Canvas canvas) {
//if(debug) Log.d(TAG, "onDraw()");
- canvas.drawColor(Color.RED);
+ canvas.drawColor(Color.RED); //TODO to remove
if(this.overlappingLCDMode > 0 && bitmapLCD != null) {
canvas.save();
@@ -176,6 +179,11 @@ public class LCDOverlappingView extends View {
canvas.scale((float) getWidth() / (float) bitmapLCD.getWidth(), (float) getHeight() / (float) bitmapLCD.getHeight());
canvas.drawBitmap(bitmapLCD, 0, 0, paint);
canvas.restore();
+// int x = NativeLib.getScreenPositionX();
+// int y = NativeLib.getScreenPositionY();
+// srcBitmapCopy.set(x, y, x + NativeLib.getScreenWidth(), y + NativeLib.getScreenHeight());
+// dstBitmapCopy.set(0, 0, getWidth(), getHeight());
+// canvas.drawBitmap(mainScreenView.getBitmap(), srcBitmapCopy, dstBitmapCopy, paint);
}
}
@@ -186,8 +194,10 @@ public class LCDOverlappingView extends View {
case NativeLib.CALLBACK_TYPE_INVALIDATE:
//if(debug) Log.d(TAG, "PAINT updateCallback() postInvalidate()");
if(debug) Log.d(TAG, "updateCallback() CALLBACK_TYPE_INVALIDATE");
- NativeLib.copyLCD(bitmapLCD);
- postInvalidate();
+ if(bitmapLCD.getWidth() > 1) {
+ NativeLib.copyLCD(bitmapLCD);
+ postInvalidate();
+ }
break;
case NativeLib.CALLBACK_TYPE_WINDOW_RESIZE:
// New Bitmap size
diff --git a/app/src/main/java/org/emulator/calculator/MainScreenView.java b/app/src/main/java/org/emulator/calculator/MainScreenView.java
index 4491c54..090cd7a 100644
--- a/app/src/main/java/org/emulator/calculator/MainScreenView.java
+++ b/app/src/main/java/org/emulator/calculator/MainScreenView.java
@@ -387,4 +387,8 @@ public class MainScreenView extends PanAndScaleView {
}
return 0;
}
+
+ public Bitmap getBitmap() {
+ return bitmapMainScreen;
+ }
}
diff --git a/app/src/main/java/org/emulator/forty/eight/MainActivity.java b/app/src/main/java/org/emulator/forty/eight/MainActivity.java
index 2f44482..3a52a11 100644
--- a/app/src/main/java/org/emulator/forty/eight/MainActivity.java
+++ b/app/src/main/java/org/emulator/forty/eight/MainActivity.java
@@ -349,6 +349,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
OnObjectLoad();
} else if (id == R.id.nav_save_object) {
OnObjectSave();
+ } else if (id == R.id.nav_copy_fullscreen) {
+ OnViewCopyFullscreen();
} else if (id == R.id.nav_copy_screen) {
OnViewCopy();
} else if (id == R.id.nav_copy_stack) {
@@ -749,6 +751,30 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.filename) + "-object.hp");
startActivityForResult(intent, INTENT_OBJECT_SAVE);
}
+ private void OnViewCopyFullscreen() {
+ Bitmap bitmapScreen = mainScreenView.getBitmap();
+ if(bitmapScreen == null)
+ return;
+ String imageFilename = getString(R.string.filename) + "-" + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US).format(new Date());
+ try {
+ File storagePath = new File(this.getExternalCacheDir(), "");
+ File imageFile = File.createTempFile(imageFilename, ".png", storagePath);
+ FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
+ bitmapScreen.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
+ fileOutputStream.close();
+ String mimeType = "application/png";
+ Intent intent = new Intent(android.content.Intent.ACTION_SEND);
+ intent.setType(mimeType);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(Intent.EXTRA_SUBJECT, R.string.message_screenshot);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,this.getPackageName() + ".provider", imageFile));
+ startActivity(Intent.createChooser(intent, getString(R.string.message_share_screenshot)));
+ } catch (Exception e) {
+ e.printStackTrace();
+ showAlert(e.getMessage());
+ }
+ }
private void OnViewCopy() {
int width = NativeLib.getScreenWidth();
int height = NativeLib.getScreenHeight();
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index f3a1d44..f09a8ea 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -52,6 +52,10 @@
android:id="@+id/nav_save_object"
android:icon="@drawable/ic_save_alt_black_24dp"
android:title="@string/nav_save_object" />
+
- Load Object...
Save Object...
Copy Screen
+ Copy Fullscreen
Copy Stack
Recent
Edit