mirror of
https://github.com/dgis/emu48android
synced 2024-12-26 09:58:49 +01:00
This commit is contained in:
parent
f19dc4e0a9
commit
5edce2f915
9 changed files with 177 additions and 104 deletions
|
@ -60,28 +60,12 @@ add_library( # Sets the name of the library.
|
|||
src/main/cpp/emu48-jni.c
|
||||
)
|
||||
|
||||
# Searches for a specified prebuilt library and stores the path as a
|
||||
# variable. Because CMake includes system libraries in the search path by
|
||||
# default, you only need to specify the name of the public NDK library
|
||||
# you want to add. CMake verifies that the library exists before
|
||||
# completing its build.
|
||||
|
||||
find_library( # Sets the name of the path variable.
|
||||
log-lib
|
||||
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
log)
|
||||
|
||||
# Specifies libraries CMake should link to your target library. You
|
||||
# can link multiple libraries, such as libraries you define in this
|
||||
# build script, prebuilt third-party libraries, or system libraries.
|
||||
|
||||
target_link_libraries( # Specifies the target library.
|
||||
native-lib
|
||||
|
||||
android
|
||||
|
||||
# Links the target library to the log library
|
||||
# included in the NDK.
|
||||
${log-lib})
|
||||
jnigraphics
|
||||
log)
|
||||
|
|
|
@ -9,33 +9,52 @@
|
|||
|
||||
#include "pch.h"
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_regis_cosnier_emu48_MainActivity_stringFromJNI(
|
||||
JNIEnv *env,
|
||||
jobject thisz) {
|
||||
// std::string hello = "Hello from C++";
|
||||
// return env->NewStringUTF(hello.c_str());
|
||||
return (*env)->NewStringUTF(env, "Hello from JNI !");
|
||||
JavaVM *java_machine;
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
java_machine = vm;
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
extern void emu48Start();
|
||||
extern AAssetManager * assetManager;
|
||||
static jobject viewToUpdate = NULL;
|
||||
jobject bitmapMainScreen;
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_MainActivity_emu48Start(JNIEnv *env, jobject thisz, jobject assetMgr, jobject bitmapMainScreen) {
|
||||
|
||||
AndroidBitmapInfo androidBitmapInfo;
|
||||
void * pixels;
|
||||
int ret;
|
||||
if ((ret = AndroidBitmap_getInfo(env, bitmapMainScreen, &androidBitmapInfo)) < 0) {
|
||||
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
|
||||
return;
|
||||
// https://stackoverflow.com/questions/9630134/jni-how-to-callback-from-c-or-c-to-java
|
||||
void mainViewUpdateCallback() {
|
||||
if (viewToUpdate) {
|
||||
JNIEnv *jni;
|
||||
jint result = (*java_machine)->AttachCurrentThread(java_machine, &jni, NULL);
|
||||
jclass viewToUpdateClass = (*jni)->GetObjectClass(jni, viewToUpdate);
|
||||
jmethodID midStr = (*jni)->GetMethodID(jni, viewToUpdateClass, "updateCallback", "()V");
|
||||
(*jni)->CallVoidMethod(jni, viewToUpdate, midStr);
|
||||
result = (*java_machine)->DetachCurrentThread(java_machine);
|
||||
}
|
||||
// if ((ret = AndroidBitmap_lockPixels(env, bitmapMainScreen, &pixels)) < 0) {
|
||||
// LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
|
||||
// }
|
||||
//
|
||||
// AndroidBitmap_unlockPixels(env, bitmapMainScreen);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_start(JNIEnv *env, jobject thisz, jobject assetMgr, jobject bitmapMainScreen0, jobject view) {
|
||||
|
||||
viewToUpdate = (*env)->NewGlobalRef(env, view);
|
||||
bitmapMainScreen = (*env)->NewGlobalRef(env, bitmapMainScreen0);
|
||||
|
||||
assetManager = AAssetManager_fromJava(env, assetMgr);
|
||||
emu48Start();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_stop(JNIEnv *env, jobject thisz) {
|
||||
|
||||
if (viewToUpdate) {
|
||||
(*env)->DeleteGlobalRef(env, viewToUpdate);
|
||||
viewToUpdate = NULL;
|
||||
}
|
||||
if(bitmapMainScreen) {
|
||||
(*env)->DeleteGlobalRef(env, bitmapMainScreen);
|
||||
bitmapMainScreen = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_resize(JNIEnv *env, jobject thisz, jint width, jint height) {
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
#define LOG_TAG "NDK_NativeEmu48"
|
||||
#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__))
|
||||
extern void mainViewUpdateCallback();
|
||||
|
||||
#include "win32-layer.h"
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <sys/mman.h>
|
||||
#include <pthread.h>
|
||||
#include "resource.h"
|
||||
#include "win32-layer.h"
|
||||
|
||||
extern JavaVM *java_machine;
|
||||
extern jobject bitmapMainScreen;
|
||||
|
||||
HANDLE hWnd;
|
||||
LPTSTR szTitle;
|
||||
|
@ -730,7 +734,7 @@ BOOL PatBlt(HDC hdc, int x, int y, int w, int h, DWORD rop) {
|
|||
return 0;
|
||||
}
|
||||
BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
|
||||
//TODO
|
||||
mainViewUpdateCallback();
|
||||
return 0;
|
||||
}
|
||||
int SetStretchBltMode(HDC hdc, int mode) {
|
||||
|
@ -738,18 +742,74 @@ int SetStretchBltMode(HDC hdc, int mode) {
|
|||
return 0;
|
||||
}
|
||||
BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop) {
|
||||
//TODO
|
||||
|
||||
if(hdcDest->hdcCompatible == NULL && hdcSrc->selectedBitmap) {
|
||||
// We update the main window
|
||||
JNIEnv * jniEnv;
|
||||
jint ret = (*java_machine)->AttachCurrentThread(java_machine, &jniEnv, NULL);
|
||||
|
||||
AndroidBitmapInfo androidBitmapInfo;
|
||||
if ((ret = AndroidBitmap_getInfo(jniEnv, bitmapMainScreen, &androidBitmapInfo)) < 0) {
|
||||
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
|
||||
}
|
||||
|
||||
void * pixelsDestination;
|
||||
if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) < 0) {
|
||||
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
|
||||
}
|
||||
|
||||
HBITMAP hBitmap = hdcSrc->selectedBitmap;
|
||||
|
||||
//void * pixelsSource = hBitmap->bitmapInfo->bmiColors;
|
||||
void * pixelsSource = hBitmap->bitmapBits;
|
||||
|
||||
int sourceWidth = hBitmap->bitmapInfoHeader->biWidth;
|
||||
int sourceHeight = abs(hBitmap->bitmapInfoHeader->biHeight);
|
||||
int destinationWidth = androidBitmapInfo.width;
|
||||
int destinationHeight = androidBitmapInfo.height;
|
||||
|
||||
//https://softwareengineering.stackexchange.com/questions/148123/what-is-the-algorithm-to-copy-a-region-of-one-bitmap-into-a-region-in-another
|
||||
float src_dx = wDest / wSrc;
|
||||
float src_dy = hDest / hSrc;
|
||||
float src_maxx = xSrc + wSrc;
|
||||
float src_maxy = ySrc + hSrc;
|
||||
float dst_maxx = xDest + wDest;
|
||||
float dst_maxy = yDest + hDest;
|
||||
float src_cury = ySrc;
|
||||
|
||||
float sourceStride = sourceWidth * 4;
|
||||
float destinationStride = androidBitmapInfo.stride;
|
||||
|
||||
for (float y = yDest; y < dst_maxy; y++)
|
||||
{
|
||||
float src_curx = xSrc;
|
||||
for (float x = xDest; x < dst_maxx; x++)
|
||||
{
|
||||
// Point sampling - you can also impl as bilinear or other
|
||||
//dst.bmp[x,y] = src.bmp[src_curx, src_cury];
|
||||
|
||||
BYTE * destinationPixel = pixelsDestination + (int)(4.0 * x + destinationStride * y);
|
||||
BYTE * sourcePixel = pixelsSource + (int)(4.0 * src_curx + sourceStride * src_cury);
|
||||
memcpy(destinationPixel, sourcePixel, 4);
|
||||
|
||||
src_curx += src_dx;
|
||||
}
|
||||
|
||||
src_cury += src_dy;
|
||||
}
|
||||
|
||||
AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen);
|
||||
|
||||
ret = (*java_machine)->DetachCurrentThread(java_machine);
|
||||
|
||||
mainViewUpdateCallback();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
/* constants for CreateDIBitmap */
|
||||
#define CBM_INIT 0x04L /* initialize bitmap */
|
||||
/* DIB color table identifiers */
|
||||
#define DIB_RGB_COLORS 0 /* color table in RGBs */
|
||||
#define DIB_PAL_COLORS 1 /* color table in palette indices */
|
||||
HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage) {
|
||||
HGDIOBJ newHDC = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
|
||||
newHDC->handleType = HGDIOBJ_TYPE_BITMAP;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <jni.h>
|
||||
#include <android/bitmap.h>
|
||||
#include <android/asset_manager.h>
|
||||
|
||||
#ifndef __OBJC__
|
||||
|
@ -31,7 +35,7 @@ typedef WORD *LPWORD;
|
|||
typedef uint32_t DWORD;
|
||||
typedef DWORD *LPDWORD;
|
||||
typedef BYTE *LPBYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint32_t UINT;
|
||||
typedef int32_t INT;
|
||||
typedef int INT_PTR, *PINT_PTR;
|
||||
|
@ -39,10 +43,12 @@ typedef char CHAR;
|
|||
typedef void VOID;
|
||||
typedef void *LPVOID;
|
||||
typedef void *PVOID;
|
||||
typedef long LONG;
|
||||
//typedef long LONG;
|
||||
typedef int32_t LONG;
|
||||
typedef LONG *PLONG;
|
||||
typedef unsigned int UINT_PTR, *PUINT_PTR;
|
||||
typedef long LONG_PTR, *PLONG_PTR;
|
||||
//typedef long LONG_PTR, *PLONG_PTR;
|
||||
typedef LONG LONG_PTR, *PLONG_PTR;
|
||||
typedef size_t SIZE_T;
|
||||
typedef /*_W64*/ unsigned long ULONG_PTR, *PULONG_PTR;
|
||||
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
||||
|
|
|
@ -2,10 +2,9 @@ package com.regis.cosnier.emu48;
|
|||
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.widget.TextView;
|
||||
import android.view.ViewGroup;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
@ -16,13 +15,7 @@ import android.view.MenuItem;
|
|||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private Bitmap bitmapMainScreen;
|
||||
MainScreenView mainScreenView;
|
||||
|
||||
// Used to load the 'native-lib' library on application startup.
|
||||
static {
|
||||
System.loadLibrary("native-lib");
|
||||
}
|
||||
private MainScreenView mainScreenView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -40,18 +33,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
});
|
||||
|
||||
// Example of a call to a native method
|
||||
TextView tv = (TextView) findViewById(R.id.sample_text);
|
||||
tv.setText(stringFromJNI());
|
||||
|
||||
AssetManager mgr = getResources().getAssets();
|
||||
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
bitmapMainScreen = Bitmap.createBitmap(displayMetrics.widthPixels, displayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
|
||||
emu48Start(mgr, bitmapMainScreen);
|
||||
|
||||
mainScreenView = new MainScreenView(this); //, currentProject);
|
||||
ViewGroup mainScreenContainer = (ViewGroup)findViewById(R.id.main_screen_container);
|
||||
mainScreenContainer.addView(mainScreenView, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,11 +60,11 @@ public class MainActivity extends AppCompatActivity {
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* A native method that is implemented by the 'native-lib' native library,
|
||||
* which is packaged with this application.
|
||||
*/
|
||||
public native String stringFromJNI();
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
|
||||
public native void emu48Start(AssetManager mgr, Bitmap bitmapMainScreen);
|
||||
NativeLib.stop();
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package com.regis.cosnier.emu48;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
|
@ -16,26 +20,29 @@ import android.view.View;
|
|||
import android.widget.OverScroller;
|
||||
|
||||
public class MainScreenView extends SurfaceView {
|
||||
|
||||
protected static final String TAG = "MainScreenView";
|
||||
private Bitmap bitmapMainScreen;
|
||||
|
||||
public MainScreenView(Context context) {
|
||||
super(context);
|
||||
|
||||
//commonInitialize(context, new Project());
|
||||
AssetManager mgr = getResources().getAssets();
|
||||
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
bitmapMainScreen = Bitmap.createBitmap(displayMetrics.widthPixels, displayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
|
||||
NativeLib.start(mgr, bitmapMainScreen, this);
|
||||
|
||||
commonInitialize(context);
|
||||
}
|
||||
|
||||
// public MainScreenView(Context context, final Project currentProject) {
|
||||
// super(context);
|
||||
//
|
||||
// commonInitialize(context, currentProject);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Common initialize method.
|
||||
// * @param context The activity context.
|
||||
// * @param currentProject The current project.
|
||||
// */
|
||||
// private void commonInitialize(Context context, final Project currentProject) {
|
||||
/**
|
||||
* Common initialize method.
|
||||
* @param context The activity context.
|
||||
* @param currentProject The current project.
|
||||
*/
|
||||
private void commonInitialize(Context context) {
|
||||
// //this.mContext = context;
|
||||
// this.currentProject = currentProject;
|
||||
//
|
||||
|
@ -86,10 +93,10 @@ public class MainScreenView extends SurfaceView {
|
|||
// this.setFocusable(true);
|
||||
// this.setFocusableInTouchMode(true);
|
||||
//
|
||||
// // This call is necessary, or else the
|
||||
// // draw method will not be called.
|
||||
// setWillNotDraw(false);
|
||||
// }
|
||||
// This call is necessary, or else the
|
||||
// draw method will not be called.
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
//
|
||||
// @SuppressLint("ClickableViewAccessibility")
|
||||
|
@ -189,8 +196,7 @@ public class MainScreenView extends SurfaceView {
|
|||
protected void onSizeChanged(int viewWidth, int viewHeight, int oldViewWidth, int oldViewHeight) {
|
||||
super.onSizeChanged(viewWidth, viewHeight, oldViewWidth, oldViewHeight);
|
||||
|
||||
// mViewBounds.set(0.0f, 0.0f, viewWidth, viewHeight);
|
||||
// resetViewport((float)viewWidth, (float)viewHeight);
|
||||
NativeLib.resize(viewWidth, viewHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -198,7 +204,7 @@ public class MainScreenView extends SurfaceView {
|
|||
//Log.d(TAG, "onDraw() mIsScaling: " + mIsScaling + ", mIsPanning: " + mIsPanning + ", mIsFlinging: " + mIsFlinging);
|
||||
|
||||
// //renderPlasma(mBitmap, System.currentTimeMillis() - mStartTime);
|
||||
// canvas.drawBitmap(bitmapMainScreen, 0, 0, null);
|
||||
canvas.drawBitmap(bitmapMainScreen, 0, 0, null);
|
||||
|
||||
// Paint paint = mVectorsCanvasRenderer.getPaint();
|
||||
//
|
||||
|
@ -254,6 +260,11 @@ public class MainScreenView extends SurfaceView {
|
|||
// mRectScaleImage.top + scale * (mViewBounds.height() - currentProject.viewPanOffsetY) / currentProject.viewScaleFactor
|
||||
// );
|
||||
// canvas.drawRect(mRectScaleView, paint);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
void updateCallback() {
|
||||
//invalidate();
|
||||
postInvalidate();
|
||||
}
|
||||
}
|
||||
|
|
16
app/src/main/java/com/regis/cosnier/emu48/NativeLib.java
Normal file
16
app/src/main/java/com/regis/cosnier/emu48/NativeLib.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package com.regis.cosnier.emu48;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.view.View;
|
||||
|
||||
public class NativeLib {
|
||||
|
||||
static {
|
||||
System.loadLibrary("native-lib");
|
||||
}
|
||||
|
||||
public static native void start(AssetManager mgr, Bitmap bitmapMainScreen, MainScreenView view);
|
||||
public static native void stop();
|
||||
public static native void resize(int width, int height);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_screen_container"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -8,14 +9,5 @@
|
|||
tools:context=".MainActivity"
|
||||
tools:showIn="@layout/activity_main">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sample_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
Loading…
Reference in a new issue