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(¤tTime);
121 setGpsTime(¤tTime);
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