diff --git a/internal/ui/ui_android.go b/internal/ui/ui_android.go index 6ce7dd827..b134044ed 100644 --- a/internal/ui/ui_android.go +++ b/internal/ui/ui_android.go @@ -14,6 +14,61 @@ package ui -func deviceScale() float64 { - return 1 +/* + +#include +#include + +// Basically same as `getResources().getDisplayMetrics().density`; +static float deviceScale(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx) { + JavaVM* vm = (JavaVM*)java_vm; + JNIEnv* env = (JNIEnv*)jni_env; + jobject context = (jobject)ctx; + + const jclass android_content_ContextWrapper = + (*env)->FindClass(env, "android/content/ContextWrapper"); + const jclass android_content_res_Resources = + (*env)->FindClass(env, "android/content/res/Resources"); + const jclass android_util_DisplayMetrics = + (*env)->FindClass(env, "android/util/DisplayMetrics"); + + const jobject resources = + (*env)->CallObjectMethod( + env, context, + (*env)->GetMethodID(env, android_content_ContextWrapper, "getResources", "()Landroid/content/res/Resources;")); + const jobject displayMetrics = + (*env)->CallObjectMethod( + env, resources, + (*env)->GetMethodID(env, android_content_res_Resources, "getDisplayMetrics", "()Landroid/util/DisplayMetrics;")); + const float density = + (*env)->GetFloatField( + env, displayMetrics, + (*env)->GetFieldID(env, android_util_DisplayMetrics, "density", "F")); + return density; +} + +*/ +import "C" + +import ( + "fmt" + + "github.com/hajimehoshi/ebiten/internal/jni" +) + +var ( + androidDeviceScale = 0.0 +) + +func deviceScale() float64 { + if 0 < androidDeviceScale { + return androidDeviceScale + } + if err := jni.RunOnJVM(func(vm, env, ctx uintptr) error { + androidDeviceScale = float64(C.deviceScale(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx))) + return nil + }); err != nil { + panic(fmt.Sprintf("ui: error %v", err)) + } + return androidDeviceScale } diff --git a/mobile/mobile.go b/mobile/mobile.go index 040b06bda..7177d6601 100644 --- a/mobile/mobile.go +++ b/mobile/mobile.go @@ -22,9 +22,7 @@ import ( // // Different from ebiten.Run, this invokes only the game loop and not the main (UI) loop. // -// On Android, width/height is in pixels (px). -// -// On iOS, width/height is in points. +// The unit of width/height is device-independent pixel (dp on Android and pointer on iOS). func Start(f func(*ebiten.Image) error, width, height int, scale float64, title string) error { return start(f, width, height, scale, title) } @@ -54,6 +52,8 @@ func Update() error { // } // return true; // } +// +// The coodinate x/y is in dp. func UpdateTouchesOnAndroid(action int, id int, x, y int) { updateTouchesOnAndroid(action, id, x, y) }