mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-30 08:50:33 +00:00
199 lines
5.9 KiB
C++
199 lines
5.9 KiB
C++
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
#ifdef __MINGW32__
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <ctime>
|
|
|
|
#include "Common/System/System.h"
|
|
#include "Common/System/Request.h"
|
|
#include "Common/Serialize/Serializer.h"
|
|
#include "Common/Serialize/SerializeFuncs.h"
|
|
#include "Core/HLE/HLE.h"
|
|
#include "Core/HLE/FunctionWrappers.h"
|
|
#include "Core/HLE/sceUsbGps.h"
|
|
#include "Core/MemMapHelpers.h"
|
|
|
|
enum GpsStatus {
|
|
GPS_STATE_OFF = 0,
|
|
GPS_STATE_ACTIVATING1 = 1,
|
|
GPS_STATE_ACTIVATING2 = 2,
|
|
GPS_STATE_ON = 3,
|
|
};
|
|
|
|
constexpr int AUTO_UPDATE_GPSTIME = 10;
|
|
|
|
GpsStatus gpsStatus = GPS_STATE_OFF;
|
|
GpsData gpsData;
|
|
SatData satData;
|
|
time_t lastGPSTime;
|
|
|
|
void __UsbGpsInit() {
|
|
gpsStatus = GPS_STATE_OFF;
|
|
}
|
|
|
|
void __UsbGpsDoState(PointerWrap &p) {
|
|
auto s = p.Section("sceUsbGps", 0, 1);
|
|
if (!s)
|
|
return;
|
|
|
|
Do(p, gpsStatus);
|
|
if (gpsStatus == GPS_STATE_ON) {
|
|
GPS::init();
|
|
System_GPSCommand("open");
|
|
}
|
|
}
|
|
|
|
void __UsbGpsShutdown() {
|
|
gpsStatus = GPS_STATE_OFF;
|
|
System_GPSCommand("close");
|
|
};
|
|
|
|
static int sceUsbGpsGetInitDataLocation(u32 addr) {
|
|
return 0;
|
|
}
|
|
|
|
static int sceUsbGpsGetState(u32 stateAddr) {
|
|
if (Memory::IsValidRange(stateAddr, 4)) {
|
|
Memory::WriteUnchecked_U32(gpsStatus, stateAddr);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int sceUsbGpsOpen() {
|
|
GPS::init();
|
|
gpsStatus = GPS_STATE_ON;
|
|
System_GPSCommand("open");
|
|
return 0;
|
|
}
|
|
|
|
static int sceUsbGpsClose() {
|
|
gpsStatus = GPS_STATE_OFF;
|
|
System_GPSCommand("close");
|
|
return 0;
|
|
}
|
|
|
|
static int sceUsbGpsGetData(u32 gpsDataAddr, u32 satDataAddr) {
|
|
time_t currentTime;
|
|
time(¤tTime);
|
|
if (difftime(currentTime, lastGPSTime) > AUTO_UPDATE_GPSTIME)
|
|
{
|
|
/* Simulate fresh updates to satisfy MAPLUS 1/2 apps
|
|
* when real GPS data isn't available */
|
|
GPS::setGpsTime(¤tTime);
|
|
}
|
|
|
|
auto gpsData = PSPPointer<GpsData>::Create(gpsDataAddr);
|
|
if (gpsData.IsValid()) {
|
|
*gpsData = *GPS::getGpsData();
|
|
gpsData.NotifyWrite("UsbGpsGetData");
|
|
}
|
|
auto satData = PSPPointer<SatData>::Create(satDataAddr);
|
|
if (satData.IsValid()) {
|
|
*satData = *GPS::getSatData();
|
|
gpsData.NotifyWrite("UsbGpsGetData");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const HLEFunction sceUsbGps[] =
|
|
{
|
|
{0X268F95CA, nullptr, "sceUsbGpsSetInitDataLocation", '?', "" },
|
|
{0X31F95CDE, nullptr, "sceUsbGpsGetPowerSaveMode", '?', "" },
|
|
{0X54D26AA4, &WrapI_U<sceUsbGpsGetInitDataLocation>, "sceUsbGpsGetInitDataLocation", 'i', "x" },
|
|
{0X5881C826, nullptr, "sceUsbGpsGetStaticNavMode", '?', "" },
|
|
{0X63D1F89D, nullptr, "sceUsbGpsResetInitialPosition", '?', "" },
|
|
{0X69E4AAA8, nullptr, "sceUsbGpsSaveInitData", '?', "" },
|
|
{0X6EED4811, &WrapI_V<sceUsbGpsClose>, "sceUsbGpsClose", 'i', "" },
|
|
{0X7C16AC3A, &WrapI_U<sceUsbGpsGetState>, "sceUsbGpsGetState", 'i', "x" },
|
|
{0X934EC2B2, &WrapI_UU<sceUsbGpsGetData>, "sceUsbGpsGetData", 'i', "xx" },
|
|
{0X9D8F99E8, nullptr, "sceUsbGpsSetPowerSaveMode", '?', "" },
|
|
{0X9F267D34, &WrapI_V<sceUsbGpsOpen>, "sceUsbGpsOpen", 'i', "" },
|
|
{0XA259CD67, nullptr, "sceUsbGpsReset", '?', "" },
|
|
{0XA8ED0BC2, nullptr, "sceUsbGpsSetStaticNavMode", '?', "" },
|
|
};
|
|
|
|
void Register_sceUsbGps()
|
|
{
|
|
RegisterModule("sceUsbGps", ARRAY_SIZE(sceUsbGps), sceUsbGps);
|
|
}
|
|
|
|
void GPS::init() {
|
|
time_t currentTime;
|
|
time(¤tTime);
|
|
setGpsTime(¤tTime);
|
|
|
|
gpsData.hdop = 1.0f;
|
|
gpsData.latitude = 51.510357f;
|
|
gpsData.longitude = -0.116773f;
|
|
gpsData.altitude = 19.0f;
|
|
gpsData.speed = 3.0f;
|
|
gpsData.bearing = 35.0f;
|
|
gpsData.garbage2 = 513;
|
|
|
|
satData.satellites_in_view = 12;
|
|
for (unsigned char i = 0; i < satData.satellites_in_view; i++) {
|
|
satData.satInfo[i].id = i + 1; // 1 .. 32
|
|
satData.satInfo[i].elevation = 20;
|
|
satData.satInfo[i].azimuth = i * (360/satData.satellites_in_view);
|
|
satData.satInfo[i].snr = 45;
|
|
satData.satInfo[i].good = !!(i % 3);
|
|
}
|
|
}
|
|
|
|
void GPS::setGpsTime(time_t *time) {
|
|
struct tm *gpsTime;
|
|
gpsTime = gmtime(time);
|
|
|
|
gpsData.year = (short)(gpsTime->tm_year + 1900);
|
|
gpsData.month = (short)(gpsTime->tm_mon + 1);
|
|
gpsData.date = (short)gpsTime->tm_mday;
|
|
gpsData.hour = (short)gpsTime->tm_hour;
|
|
gpsData.minute = (short)gpsTime->tm_min;
|
|
gpsData.second = (short)gpsTime->tm_sec;
|
|
}
|
|
|
|
void GPS::setGpsData(long long gpsTime, float hdop, float latitude, float longitude, float altitude, float speed, float bearing) {
|
|
lastGPSTime = gpsTime;
|
|
setGpsTime((time_t*)&gpsTime);
|
|
|
|
gpsData.hdop = hdop;
|
|
gpsData.latitude = latitude;
|
|
gpsData.longitude = longitude;
|
|
gpsData.altitude = altitude;
|
|
gpsData.speed = speed;
|
|
gpsData.bearing = bearing;
|
|
}
|
|
|
|
void GPS::setSatInfo(short index, unsigned char id, unsigned char elevation, short azimuth, unsigned char snr, unsigned char good) {
|
|
satData.satInfo[index].id = id;
|
|
satData.satInfo[index].elevation = elevation;
|
|
satData.satInfo[index].azimuth = azimuth;
|
|
satData.satInfo[index].snr = snr;
|
|
satData.satInfo[index].good = good;
|
|
satData.satellites_in_view = index + 1;
|
|
}
|
|
|
|
GpsData* GPS::getGpsData() {
|
|
return &gpsData;
|
|
}
|
|
|
|
SatData* GPS::getSatData() {
|
|
return &satData;
|
|
}
|