1 // Copyright (c) 2012- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 #ifdef __MINGW32__
19 #include <unistd.h>
20 #endif
21 #include <ctime>
22 
23 #include "Common/System/System.h"
24 #include "Common/Serialize/Serializer.h"
25 #include "Common/Serialize/SerializeFuncs.h"
26 #include "Core/HLE/HLE.h"
27 #include "Core/HLE/FunctionWrappers.h"
28 #include "Core/HLE/sceUsbGps.h"
29 #include "Core/MemMapHelpers.h"
30 
31 enum GpsStatus {
32 	GPS_STATE_OFF = 0,
33 	GPS_STATE_ACTIVATING1 = 1,
34 	GPS_STATE_ACTIVATING2 = 2,
35 	GPS_STATE_ON = 3,
36 };
37 
38 GpsStatus gpsStatus = GPS_STATE_OFF;
39 
__UsbGpsInit()40 void __UsbGpsInit() {
41 	gpsStatus = GPS_STATE_OFF;
42 }
43 
__UsbGpsDoState(PointerWrap & p)44 void __UsbGpsDoState(PointerWrap &p) {
45 	auto s = p.Section("sceUsbGps", 0, 1);
46 	if (!s)
47 		return;
48 
49 	Do(p, gpsStatus);
50 }
51 
__UsbGpsShutdown()52 void __UsbGpsShutdown() {
53     gpsStatus = GPS_STATE_OFF;
54     System_SendMessage("gps_command", "close");
55 };
56 
sceUsbGpsGetInitDataLocation(u32 addr)57 static int sceUsbGpsGetInitDataLocation(u32 addr) {
58     return 0;
59 }
60 
sceUsbGpsGetState(u32 stateAddr)61 static int sceUsbGpsGetState(u32 stateAddr) {
62 	if (Memory::IsValidAddress(stateAddr)) {
63 		Memory::Write_U32(gpsStatus, stateAddr);
64 	}
65 	return 0;
66 }
67 
sceUsbGpsOpen()68 static int sceUsbGpsOpen() {
69 	ERROR_LOG(HLE, "UNIMPL sceUsbGpsOpen");
70 	GPS::init();
71 	gpsStatus = GPS_STATE_ON;
72 	System_SendMessage("gps_command", "open");
73 	return 0;
74 }
75 
sceUsbGpsClose()76 static int sceUsbGpsClose() {
77 	ERROR_LOG(HLE, "UNIMPL sceUsbGpsClose");
78 	gpsStatus = GPS_STATE_OFF;
79 	System_SendMessage("gps_command", "close");
80 	return 0;
81 }
82 
sceUsbGpsGetData(u32 gpsDataAddr,u32 satDataAddr)83 static int sceUsbGpsGetData(u32 gpsDataAddr, u32 satDataAddr) {
84 	if (Memory::IsValidRange(gpsDataAddr, sizeof(GpsData))) {
85 		Memory::WriteStruct(gpsDataAddr, GPS::getGpsData());
86 	}
87 	if (Memory::IsValidRange(satDataAddr, sizeof(SatData))) {
88 		Memory::WriteStruct(satDataAddr, GPS::getSatData());
89 	}
90 	return 0;
91 }
92 
93 const HLEFunction sceUsbGps[] =
94 {
95 	{0X268F95CA, nullptr,                                 "sceUsbGpsSetInitDataLocation",  '?', "" },
96 	{0X31F95CDE, nullptr,                                 "sceUsbGpsGetPowerSaveMode",     '?', "" },
97 	{0X54D26AA4, &WrapI_U<sceUsbGpsGetInitDataLocation>,  "sceUsbGpsGetInitDataLocation",  'i', "x" },
98 	{0X5881C826, nullptr,                                 "sceUsbGpsGetStaticNavMode",     '?', "" },
99 	{0X63D1F89D, nullptr,                                 "sceUsbGpsResetInitialPosition", '?', "" },
100 	{0X69E4AAA8, nullptr,                                 "sceUsbGpsSaveInitData",         '?', "" },
101 	{0X6EED4811, &WrapI_V<sceUsbGpsClose>,                "sceUsbGpsClose",                'i', "" },
102 	{0X7C16AC3A, &WrapI_U<sceUsbGpsGetState>,             "sceUsbGpsGetState",             'i', "x" },
103 	{0X934EC2B2, &WrapI_UU<sceUsbGpsGetData>,             "sceUsbGpsGetData",              'i', "xx" },
104 	{0X9D8F99E8, nullptr,                                 "sceUsbGpsSetPowerSaveMode",     '?', "" },
105 	{0X9F267D34, &WrapI_V<sceUsbGpsOpen>,                 "sceUsbGpsOpen",                 'i', "" },
106 	{0XA259CD67, nullptr,                                 "sceUsbGpsReset",                '?', "" },
107 	{0XA8ED0BC2, nullptr,                                 "sceUsbGpsSetStaticNavMode",     '?', "" },
108 };
109 
Register_sceUsbGps()110 void Register_sceUsbGps()
111 {
112 	RegisterModule("sceUsbGps", ARRAY_SIZE(sceUsbGps), sceUsbGps);
113 }
114 
115 GpsData gpsData;
116 SatData satData;
117 
init()118 void GPS::init() {
119 	time_t currentTime;
120 	time(&currentTime);
121 	setGpsTime(&currentTime);
122 
123 	gpsData.hdop      = 1.0f;
124 	gpsData.latitude  = 51.510357f;
125 	gpsData.longitude = -0.116773f;
126 	gpsData.altitude  = 19.0f;
127 	gpsData.speed     = 3.0f;
128 	gpsData.bearing   = 35.0f;
129 
130 	satData.satellites_in_view = 6;
131 	for (unsigned char i = 0; i < satData.satellites_in_view; i++) {
132 		satData.satInfo[i].id = i + 1; // 1 .. 32
133 		satData.satInfo[i].elevation = i * 10;
134 		satData.satInfo[i].azimuth = i * 50;
135 		satData.satInfo[i].snr = 0;
136 		satData.satInfo[i].good = 1;
137 	}
138 }
139 
setGpsTime(time_t * time)140 void GPS::setGpsTime(time_t *time) {
141 	struct tm *gpsTime;
142 	gpsTime = gmtime(time);
143 
144 	gpsData.year   = (short)(gpsTime->tm_year + 1900);
145 	gpsData.month  = (short)(gpsTime->tm_mon + 1);
146 	gpsData.date   = (short)gpsTime->tm_mday;
147 	gpsData.hour   = (short)gpsTime->tm_hour;
148 	gpsData.minute = (short)gpsTime->tm_min;
149 	gpsData.second = (short)gpsTime->tm_sec;
150 }
151 
setGpsData(long long gpsTime,float hdop,float latitude,float longitude,float altitude,float speed,float bearing)152 void GPS::setGpsData(long long gpsTime, float hdop, float latitude, float longitude, float altitude, float speed, float bearing) {
153 	setGpsTime((time_t*)&gpsTime);
154 
155 	gpsData.hdop      = hdop;
156 	gpsData.latitude  = latitude;
157 	gpsData.longitude = longitude;
158 	gpsData.altitude  = altitude;
159 	gpsData.speed     = speed;
160 	gpsData.bearing   = bearing;
161 }
162 
setSatInfo(short index,unsigned char id,unsigned char elevation,short azimuth,unsigned char snr,unsigned char good)163 void GPS::setSatInfo(short index, unsigned char id, unsigned char elevation, short azimuth, unsigned char snr, unsigned char good) {
164 	satData.satInfo[index].id = id;
165 	satData.satInfo[index].elevation = elevation;
166 	satData.satInfo[index].azimuth = azimuth;
167 	satData.satInfo[index].snr = snr;
168 	satData.satInfo[index].good = good;
169 	satData.satellites_in_view = index + 1;
170 }
171 
getGpsData()172 GpsData* GPS::getGpsData() {
173 	return &gpsData;
174 }
175 
getSatData()176 SatData* GPS::getSatData() {
177 	return &satData;
178 }
179