diff --git a/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java b/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java index 24b66c34cd..392149fe6c 100644 --- a/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java +++ b/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java @@ -32,7 +32,11 @@ LocationListener // Define an object that holds accuracy and frequency parameters LocationRequest mLocationRequest = null; boolean mUpdatesRequested = false; + boolean locationChanged = false; boolean location_service_running = false; + double current_latitude = 0.0; + double current_longitude = 0.0; + double current_accuracy = 0.0; /* * Called by Location Services when the request to connect the @@ -126,7 +130,7 @@ LocationListener /** * Initializing methods for location based functionality. */ - public void onLocationInit(int update_interval_in_ms, int distance_interval) + public void onLocationInit() { /* * Create a new location client, using the enclosing class to @@ -141,7 +145,7 @@ LocationListener if (mLocationRequest == null) mLocationRequest = LocationRequest.create(); - onLocationSetInterval(update_interval_in_ms, distance_interval); + onLocationSetInterval(0, 0); } @@ -209,11 +213,35 @@ LocationListener { return mCurrentLocation.getLongitude(); } + + /* + * Gets the accuracy of the current location in meters. + * + * @return the accuracy of the current position. + */ + public float onLocationGetAccuracy() + { + return mCurrentLocation.getAccuracy(); + } + + /* + * Tells us whether the location listener callback has + * updated the current location since the last time + * we polled. + */ + public boolean onLocationHasChanged() + { + boolean ret = locationChanged; + if (ret) + locationChanged = false; + return ret; + } // Define the callback method that receives location updates @Override public void onLocationChanged(Location location) { + locationChanged = true; mCurrentLocation = location; // Report to the UI that the location was updated diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m index 83a167a6bb..e665cad219 100644 --- a/apple/common/RAGameView.m +++ b/apple/common/RAGameView.m @@ -23,6 +23,7 @@ #include static CLLocationManager *locationManager; +static bool locationChanged; static CLLocationDegrees currentLatitude; static CLLocationDegrees currentLongitude; @@ -314,7 +315,7 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer } #endif -- (void)onLocationSetInterval:(int)interval_update_ms interval_update_distance:(int)interval_distance +- (void)onLocationSetInterval:(unsigned)interval_update_ms interval_update_distance:(unsigned)interval_distance { (void)interval_update_ms; @@ -325,7 +326,7 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer locationManager.distanceFilter = interval_distance; } -- (void)onLocationInit:(int)interval_update_ms interval_update_distance:(int)interval_distance +- (void)onLocationInit { // Create the location manager if this object does not // already have one. @@ -335,7 +336,7 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest; - [[RAGameView get] onLocationSetInterval:interval_update_ms interval_update_distance:interval_distance]; + [[RAGameView get] onLocationSetInterval:0 interval_update_distance:0]; } - (void)onLocationStart @@ -363,8 +364,23 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer return currentLongitude; } +- (double)onLocationGetAccuracy +{ + /* TODO/FIXME - implement */ + return 0.0; +} + +- (bool)onLocationHasChanged +{ + bool ret = locationChanged; + if (ret) + locationChanged = false; + return ret; +} + - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { + locationChanged = true; currentLatitude = newLocation.coordinate.latitude; currentLongitude = newLocation.coordinate.longitude; RARCH_LOG("didUpdateToLocation - latitude %f, longitude %f\n", (float)currentLatitude, (float)currentLongitude); @@ -372,7 +388,7 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { - + locationChanged = true; currentLatitude = [[locations objectAtIndex:([locations count]-1)] coordinate].latitude; currentLongitude = [[locations objectAtIndex:([locations count]-1)] coordinate].longitude; RARCH_LOG("didUpdateLocations - latitude %f, longitude %f\n", (float)currentLatitude, (float)currentLongitude); @@ -711,7 +727,7 @@ static void *apple_location_init(int interval_update_ms, int interval_distance) return applelocation; } -static void apple_location_set_interval(void *data, int interval_update_ms, int interval_distance) +static void apple_location_set_interval(void *data, unsigned interval_update_ms, unsigned interval_distance) { (void)data; @@ -745,18 +761,25 @@ static void apple_location_stop(void *data) [[RAGameView get] onLocationStop]; } -static double apple_location_get_latitude(void *data) +static bool apple_location_get_position(void *data, double *lat, double *lon, double *accuracy) { (void)data; - - return [[RAGameView get] onLocationGetLatitude]; -} -static double apple_location_get_longitude(void *data) -{ - (void)data; + bool ret = [[RAGameView get] onLocationHasChanged]; + + if (!ret) + goto fail; - return [[RAGameView get] onLocationGetLongitude]; + *lat = [[RAGameView get] onLocationGetLatitude]; + *lon = [[RAGameView get] onLocationGetLongitude]; + *accuracy = [[RAGameView get] onLocationGetAccuracy]; + return true; + +fail: + *lat = 0.0; + *lon = 0.0; + *accuracy = 0.0; + return false; } const location_driver_t location_apple = { @@ -764,8 +787,7 @@ const location_driver_t location_apple = { apple_location_free, apple_location_start, apple_location_stop, - apple_location_get_longitude, - apple_location_get_latitude, + apple_location_get_position, apple_location_set_interval, "apple", }; diff --git a/driver.c b/driver.c index 81771b1c93..7fc799a028 100644 --- a/driver.c +++ b/driver.c @@ -648,20 +648,15 @@ void driver_location_set_interval(unsigned interval_msecs, unsigned interval_dis driver.location->set_interval(driver.location_data, interval_msecs, interval_distance); } -double driver_location_get_latitude(void) +bool driver_location_get_position(double *lat, double *lon, double *accuracy) { if (driver.location && driver.location_data) - return driver.location->get_latitude(driver.location_data); - else - return 0.0; -} + return driver.location->get_position(driver.location_data, lat, lon, accuracy); -double driver_location_get_longitude(void) -{ - if (driver.location && driver.location_data) - return driver.location->get_longitude(driver.location_data); - else - return 0.0; + *lat = 0.0; + *lon = 0.0; + *accuracy = 0.0; + return false; } #endif diff --git a/driver.h b/driver.h index f5f5914b21..2fe22eb68b 100644 --- a/driver.h +++ b/driver.h @@ -375,8 +375,7 @@ typedef struct location_driver bool (*start)(void *data); void (*stop)(void *data); - double (*get_longitude)(void *data); - double (*get_latitude)(void *data); + bool (*get_position)(void *data, double *lat, double *lon, double *accuracy); void (*set_interval)(void *data, unsigned interval_msecs, unsigned interval_distance); const char *ident; } location_driver_t; @@ -604,8 +603,7 @@ void driver_camera_poll(void); #ifdef HAVE_LOCATION bool driver_location_start(void); void driver_location_stop(void); -double driver_location_get_latitude(void); -double driver_location_get_longitude(void); +bool driver_location_get_position(double *lat, double *lon, double *accuracy); void driver_location_set_interval(unsigned interval_msecs, unsigned interval_distance); #endif diff --git a/dynamic.c b/dynamic.c index f2b473c78d..d27927d272 100644 --- a/dynamic.c +++ b/dynamic.c @@ -849,8 +849,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) struct retro_location_callback *cb = (struct retro_location_callback*)data; cb->start = driver_location_start; cb->stop = driver_location_stop; - cb->get_latitude = driver_location_get_latitude; - cb->get_longitude = driver_location_get_longitude; + cb->get_position = driver_location_get_position; cb->set_interval = driver_location_set_interval; g_extern.system.location_callback = *cb; g_extern.location_active = true; diff --git a/libretro.h b/libretro.h index 1ea8bfae06..5b97dde590 100755 --- a/libretro.h +++ b/libretro.h @@ -764,18 +764,15 @@ typedef bool (*retro_location_start_t)(void); // location. typedef void (*retro_location_stop_t)(void); -// Get the latitude of the current location. -typedef double (*retro_location_get_latitude_t)(void); - -// Get the longitude of the current location. -typedef double (*retro_location_get_longitude_t)(void); +// Get the position of the current location. Will set parameters to 0 if no new +// location update has happened since the last time. +typedef bool (*retro_location_get_position_t)(double *lat, double *lon, double *accuracy); struct retro_location_callback { retro_location_start_t start; retro_location_stop_t stop; - retro_location_get_latitude_t get_latitude; - retro_location_get_longitude_t get_longitude; + retro_location_get_position_t get_position; retro_location_set_interval_t set_interval; }; diff --git a/location/android.c b/location/android.c index d167778931..55965b98c3 100644 --- a/location/android.c +++ b/location/android.c @@ -26,6 +26,8 @@ typedef struct android_location jmethodID onLocationSetInterval; jmethodID onLocationGetLongitude; jmethodID onLocationGetLatitude; + jmethodID onLocationGetAccuracy; + jmethodID onLocationHasChanged; } androidlocation_t; static void *android_location_init(void) @@ -46,7 +48,7 @@ static void *android_location_init(void) if (class == NULL) goto dealloc; - GET_METHOD_ID(env, androidlocation->onLocationInit, class, "onLocationInit", "(II)V"); + GET_METHOD_ID(env, androidlocation->onLocationInit, class, "onLocationInit", "()V"); if (!androidlocation->onLocationInit) goto dealloc; @@ -70,14 +72,21 @@ static void *android_location_init(void) if (!androidlocation->onLocationGetLongitude) goto dealloc; + GET_METHOD_ID(env, androidlocation->onLocationGetAccuracy, class, "onLocationGetAccuracy", "()F"); + if (!androidlocation->onLocationGetAccuracy) + goto dealloc; + GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class, "onLocationSetInterval", "(II)V"); if (!androidlocation->onLocationSetInterval) goto dealloc; + GET_METHOD_ID(env, androidlocation->onLocationHasChanged, class, "onLocationHasChanged", "()Z"); + if (!androidlocation->onLocationHasChanged) + goto dealloc; + CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationInit); return androidlocation; - dealloc: free(androidlocation); return NULL; @@ -120,30 +129,40 @@ static void android_location_stop(void *data) CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStop); } -static double android_location_get_latitude(void *data) +static bool android_location_get_position(void *data, double *latitude, double *longitude, double *accuracy) { struct android_app *android_app = (struct android_app*)g_android; androidlocation_t *androidlocation = (androidlocation_t*)data; JNIEnv *env = jni_thread_getenv(); if (!env) - return 0.0; + goto fail; - jdouble latitude; - CALL_BOOLEAN_METHOD(env, latitude, android_app->activity->clazz, androidlocation->onLocationGetLatitude); - return latitude; -} + jdouble lat, lon, accuhurtz; + jboolean newLocation; -static double android_location_get_longitude(void *data) -{ - struct android_app *android_app = (struct android_app*)g_android; - androidlocation_t *androidlocation = (androidlocation_t*)data; - JNIEnv *env = jni_thread_getenv(); - if (!env) - return 0.0; + CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz, androidlocation->onLocationHasChanged); - jdouble longitude; - CALL_BOOLEAN_METHOD(env, longitude, android_app->activity->clazz, androidlocation->onLocationGetLongitude); - return longitude; + if (!newLocation) + goto fail; + + CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz, androidlocation->onLocationGetLatitude); + CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz, androidlocation->onLocationGetLongitude); + CALL_DOUBLE_METHOD(env, accuhurtz, android_app->activity->clazz, androidlocation->onLocationGetAccuracy); + + if (lat != 0.0) + *latitude = lat; + if (lon != 0.0) + *longitude = lon; + if (accuhurtz != 0.0) + *accuracy = accuhurtz; + + return true; + +fail: + *latitude = 0.0; + *longitude = 0.0; + *accuracy = 0.0; + return false; } static void android_location_set_interval(void *data, unsigned interval_ms, unsigned interval_distance) @@ -154,7 +173,7 @@ static void android_location_set_interval(void *data, unsigned interval_ms, unsi if (!env) return; - CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz, androidlocation->onLocationSetInterval, interval_ms, interval_distance); + CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz, androidlocation->onLocationSetInterval, (int)interval_ms, (int)interval_distance); } const location_driver_t location_android = { @@ -162,8 +181,7 @@ const location_driver_t location_android = { android_location_free, android_location_start, android_location_stop, - android_location_get_longitude, - android_location_get_latitude, + android_location_get_position, android_location_set_interval, "android", };