Skip to content

Commit 5bb4757

Browse files
authored
Merge pull request #18684 from Florin9doi/infrared
sceSircs/Infrared support on Android
2 parents 1d076e2 + cad232e commit 5bb4757

16 files changed

+215
-6
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2160,6 +2160,8 @@ add_library(${CoreLibName} ${CoreLinkType}
21602160
Core/HLE/sceSfmt19937.h
21612161
Core/HLE/sceSha256.cpp
21622162
Core/HLE/sceSha256.h
2163+
Core/HLE/sceSircs.cpp
2164+
Core/HLE/sceSircs.h
21632165
Core/HLE/sceSsl.cpp
21642166
Core/HLE/sceSsl.h
21652167
Core/HLE/sceUmd.cpp

Common/System/Request.h

+4
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ inline void System_GPSCommand(const std::string &command) {
140140
g_requestManager.MakeSystemRequest(SystemRequestType::GPS_COMMAND, nullptr, nullptr, command, "", 0);
141141
}
142142

143+
inline void System_InfraredCommand(const std::string &command) {
144+
g_requestManager.MakeSystemRequest(SystemRequestType::INFRARED_COMMAND, nullptr, nullptr, command, "", 0);
145+
}
146+
143147
inline void System_MicrophoneCommand(const std::string &command) {
144148
g_requestManager.MakeSystemRequest(SystemRequestType::MICROPHONE_COMMAND, nullptr, nullptr, command, "", 0);
145149
}

Common/System/System.h

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum class SystemRequestType {
8383
// High-level hardware control
8484
CAMERA_COMMAND,
8585
GPS_COMMAND,
86+
INFRARED_COMMAND,
8687
MICROPHONE_COMMAND,
8788
};
8889

Core/Core.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@
736736
<ClCompile Include="HLE\sceSas.cpp" />
737737
<ClCompile Include="HLE\sceSfmt19937.cpp" />
738738
<ClCompile Include="HLE\sceSha256.cpp" />
739+
<ClCompile Include="HLE\sceSircs.cpp" />
739740
<ClCompile Include="HLE\sceSsl.cpp" />
740741
<ClCompile Include="HLE\sceUmd.cpp" />
741742
<ClCompile Include="HLE\sceUsb.cpp" />
@@ -1301,6 +1302,7 @@
13011302
<ClInclude Include="HLE\sceSas.h" />
13021303
<ClInclude Include="HLE\sceSfmt19937.h" />
13031304
<ClInclude Include="HLE\sceSha256.h" />
1305+
<ClInclude Include="HLE\sceSircs.h" />
13041306
<ClInclude Include="HLE\sceSsl.h" />
13051307
<ClInclude Include="HLE\sceUmd.h" />
13061308
<ClInclude Include="HLE\sceUsb.h" />

Core/Core.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,9 @@
580580
<ClCompile Include="HLE\sceSha256.cpp">
581581
<Filter>HLE\Libraries</Filter>
582582
</ClCompile>
583+
<ClCompile Include="HLE\sceSircs.cpp">
584+
<Filter>HLE\Libraries</Filter>
585+
</ClCompile>
583586
<ClCompile Include="Util\AudioFormat.cpp">
584587
<Filter>Util</Filter>
585588
</ClCompile>
@@ -1773,6 +1776,9 @@
17731776
<ClInclude Include="HLE\sceSha256.h">
17741777
<Filter>HLE\Libraries</Filter>
17751778
</ClInclude>
1779+
<ClInclude Include="HLE\sceSircs.h">
1780+
<Filter>HLE\Libraries</Filter>
1781+
</ClInclude>
17761782
<ClInclude Include="Util\AudioFormat.h">
17771783
<Filter>Util</Filter>
17781784
</ClInclude>

Core/HLE/HLETables.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#include "scePsmf.h"
6565
#include "sceRtc.h"
6666
#include "sceSas.h"
67+
#include "sceSircs.h"
6768
#include "sceSsl.h"
6869
#include "sceUmd.h"
6970
#include "sceUsb.h"
@@ -307,6 +308,7 @@ void RegisterAllModules() {
307308
Register_sceDdrdb();
308309
Register_mp4msv();
309310
Register_InterruptManagerForKernel();
311+
Register_sceSircs();
310312
// add new modules here.
311313
}
312314

Core/HLE/sceHttp.cpp

-5
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,6 @@ static int sceHttpGetContentLength(int requestID, u64 contentLengthPtr) {
272272
return 0;
273273
}
274274

275-
/*
276-
* 0x62411801 sceSircsInit
277-
0x19155a2f sceSircsEnd
278-
0x71eef62d sceSircsSend
279-
*/
280275
const HLEFunction sceHttp[] = {
281276
{0XAB1ABE07, &WrapI_I<sceHttpInit>, "sceHttpInit", 'i', "i" },
282277
{0XD1C8945E, &WrapI_V<sceHttpEnd>, "sceHttpEnd", 'i', "" },

Core/HLE/sceSircs.cpp

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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/System/Request.h"
25+
#include "Common/Serialize/Serializer.h"
26+
#include "Common/Serialize/SerializeFuncs.h"
27+
#include "Core/HLE/HLE.h"
28+
#include "Core/HLE/sceSircs.h"
29+
#include "Core/HLE/FunctionWrappers.h"
30+
#include "Core/MemMapHelpers.h"
31+
32+
int sceSircsSend(u32 dataAddr, int count) {
33+
auto data = PSPPointer<SircsData>::Create(dataAddr);
34+
if (data.IsValid()) {
35+
INFO_LOG(HLE, "%s (version=0x%x, command=0x%x, address=0x%x, count=%d)",
36+
__FUNCTION__, data->version, data->command, data->address, count);
37+
#if PPSSPP_PLATFORM(ANDROID)
38+
char command[40] = {0};
39+
snprintf(command, sizeof(command), "sircs_%d_%d_%d_%d",
40+
data->version, data->command, data->address, count);
41+
System_InfraredCommand(command);
42+
#endif
43+
data.NotifyRead("sceSircsSend");
44+
}
45+
return 0;
46+
}
47+
48+
const HLEFunction sceSircs[] =
49+
{
50+
{0X62411801, nullptr, "sceSircsInit", '?', "" },
51+
{0X19155A2F, nullptr, "sceSircsEnd", '?', "" },
52+
{0X71EEF62D, &WrapI_UI<sceSircsSend>, "sceSircsSend", 'i', "xi" },
53+
{0x83381633, nullptr, "sceSircsReceive", '?', "" },
54+
};
55+
56+
void Register_sceSircs()
57+
{
58+
RegisterModule("sceSircs", ARRAY_SIZE(sceSircs), sceSircs);
59+
}

Core/HLE/sceSircs.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
#pragma once
19+
20+
#include "Core/HLE/FunctionWrappers.h"
21+
22+
void Register_sceSircs();
23+
24+
typedef struct {
25+
u8 version;
26+
u8 command;
27+
u16 address;
28+
} SircsData;

UWP/CoreUWP/CoreUWP.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@
240240
<ClInclude Include="..\..\Core\HLE\sceSas.h" />
241241
<ClInclude Include="..\..\Core\HLE\sceSfmt19937.h" />
242242
<ClInclude Include="..\..\Core\HLE\sceSha256.h" />
243+
<ClInclude Include="..\..\Core\HLE\sceSircs.h" />
243244
<ClInclude Include="..\..\Core\HLE\sceSsl.h" />
244245
<ClInclude Include="..\..\Core\HLE\sceUmd.h" />
245246
<ClInclude Include="..\..\Core\HLE\sceUsb.h" />
@@ -486,6 +487,7 @@
486487
<ClCompile Include="..\..\Core\HLE\sceSas.cpp" />
487488
<ClCompile Include="..\..\Core\HLE\sceSfmt19937.cpp" />
488489
<ClCompile Include="..\..\Core\HLE\sceSha256.cpp" />
490+
<ClCompile Include="..\..\Core\HLE\sceSircs.cpp" />
489491
<ClCompile Include="..\..\Core\HLE\sceSsl.cpp" />
490492
<ClCompile Include="..\..\Core\HLE\sceUmd.cpp" />
491493
<ClCompile Include="..\..\Core\HLE\sceUsb.cpp" />

android/AndroidManifest.xml

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<uses-permission android:name="archos.permission.FULLSCREEN.FULL" />
2828
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
2929
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
30+
<uses-permission-sdk-23 android:name="android.permission.TRANSMIT_IR" />
3031
<uses-permission-sdk-23 android:name="android.permission.CAMERA" />
3132
<uses-permission-sdk-23 android:name="android.permission.RECORD_AUDIO" />
3233

android/jni/Android.mk

+1
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ EXEC_AND_LIB_FILES := \
652652
$(SRC)/Core/HLE/sceSas.cpp \
653653
$(SRC)/Core/HLE/sceSfmt19937.cpp \
654654
$(SRC)/Core/HLE/sceSha256.cpp \
655+
$(SRC)/Core/HLE/sceSircs.cpp \
655656
$(SRC)/Core/HLE/sceSsl.cpp \
656657
$(SRC)/Core/HLE/sceUmd.cpp \
657658
$(SRC)/Core/HLE/sceUsb.cpp \

android/jni/app-android.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
11281128
case SystemRequestType::GPS_COMMAND:
11291129
PushCommand("gps_command", param1);
11301130
return true;
1131+
case SystemRequestType::INFRARED_COMMAND:
1132+
PushCommand("infrared_command", param1);
1133+
return true;
11311134
case SystemRequestType::MICROPHONE_COMMAND:
11321135
PushCommand("microphone_command", param1);
11331136
return true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.ppsspp.ppsspp;
2+
3+
import android.content.Context;
4+
import android.hardware.ConsumerIrManager;
5+
import android.hardware.ConsumerIrManager.CarrierFrequencyRange;
6+
import android.os.Build;
7+
import android.util.Log;
8+
9+
import androidx.annotation.RequiresApi;
10+
11+
import java.util.ArrayList;
12+
import java.util.Arrays;
13+
import java.util.List;
14+
15+
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
16+
class InfraredHelper {
17+
private static final String TAG = InfraredHelper.class.getSimpleName();
18+
private static final int SIRC_FREQ = 40000;
19+
private ConsumerIrManager mConsumerIrManager;
20+
21+
InfraredHelper(Context context) throws Exception {
22+
mConsumerIrManager = (ConsumerIrManager) context.getSystemService(Context.CONSUMER_IR_SERVICE);
23+
Log.d(TAG, "HasIrEmitter: " + mConsumerIrManager.hasIrEmitter());
24+
if (!mConsumerIrManager.hasIrEmitter()) {
25+
throw new Exception("No Ir Emitter");
26+
}
27+
boolean sirc_freq_supported = false;
28+
CarrierFrequencyRange[] carrierFrequencies = mConsumerIrManager.getCarrierFrequencies();
29+
for (CarrierFrequencyRange freq : carrierFrequencies) {
30+
Log.d(TAG, "CarrierFrequencies: " + freq.getMinFrequency() + " -> " + freq.getMaxFrequency());
31+
if (freq.getMinFrequency() <= SIRC_FREQ && SIRC_FREQ <= freq.getMaxFrequency()) {
32+
sirc_freq_supported = true;
33+
}
34+
}
35+
if (!sirc_freq_supported) {
36+
throw new Exception("Sirc Frequency unsupported");
37+
}
38+
}
39+
40+
void sendSircCommand(int version, int command, int address, int count) {
41+
final List<Integer> start = Arrays.asList(2400, 600);
42+
final List<Integer> one = Arrays.asList(1200, 600);
43+
final List<Integer> zero = Arrays.asList( 600, 600);
44+
45+
List<Integer> iterList = new ArrayList<>();
46+
iterList.addAll(start);
47+
48+
for (int i = 0; i < version; i++) {
49+
List<Integer> val = i < 7
50+
? ((command >> i ) & 1) == 1 ? one : zero
51+
: ((address >> i - 7) & 1) == 1 ? one : zero;
52+
iterList.addAll(val);
53+
}
54+
55+
int iterSum = 0;
56+
for (int i = 0; i < iterList.size() - 1; i++) {
57+
iterSum += iterList.get(i);
58+
}
59+
int lastVal = 52000 - iterSum; // SIRC cicle = 52ms
60+
iterList.set(iterList.size() - 1, lastVal);
61+
62+
List<Integer> patternList = new ArrayList<>();
63+
// Android is limited to 2 seconds => max 38 loops of 52ms each
64+
// Limit even further to 4 loops for now
65+
for (int i = 0; i < count && i < 4; i++) {
66+
patternList.addAll(iterList);
67+
}
68+
69+
int[] pattern = new int[patternList.size()];
70+
for (int i = 0; i < patternList.size(); i++) {
71+
pattern[i] = patternList.get(i);
72+
}
73+
mConsumerIrManager.transmit(SIRC_FREQ, pattern);
74+
}
75+
}

android/src/org/ppsspp/ppsspp/NativeActivity.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public abstract class NativeActivity extends Activity {
111111
private PowerSaveModeReceiver mPowerSaveModeReceiver = null;
112112
private SizeManager sizeManager = null;
113113
private static LocationHelper mLocationHelper;
114+
private static InfraredHelper mInfraredHelper;
114115
private static CameraHelper mCameraHelper;
115116

116117
private static final String[] permissionsForStorage = {
@@ -472,6 +473,14 @@ public void Initialize() {
472473
}
473474

474475
mLocationHelper = new LocationHelper(this);
476+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
477+
try {
478+
mInfraredHelper = new InfraredHelper(this);
479+
} catch (Exception e) {
480+
mInfraredHelper = null;
481+
Log.i(TAG, "InfraredHelper exception: " + e);
482+
}
483+
}
475484
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
476485
// android.graphics.SurfaceTexture is not available before version 11.
477486
mCameraHelper = new CameraHelper(this);
@@ -1560,7 +1569,25 @@ public boolean processCommand(String command, String params) {
15601569
} else if (params.equals("close")) {
15611570
mLocationHelper.stopLocationUpdates();
15621571
}
1572+
} else if (command.equals("infrared_command")) {
1573+
if (mInfraredHelper == null) {
1574+
return false;
1575+
}
1576+
if (params.startsWith("sircs")) {
1577+
Pattern pattern = Pattern.compile("sircs_(\\d+)_(\\d+)_(\\d+)_(\\d+)");
1578+
Matcher matcher = pattern.matcher(params);
1579+
if (!matcher.matches())
1580+
return false;
1581+
int ir_version = Integer.parseInt(matcher.group(1));
1582+
int ir_command = Integer.parseInt(matcher.group(2));
1583+
int ir_address = Integer.parseInt(matcher.group(3));
1584+
int ir_count = Integer.parseInt(matcher.group(4));
1585+
mInfraredHelper.sendSircCommand(ir_version, ir_command, ir_address, ir_count);
1586+
}
15631587
} else if (command.equals("camera_command")) {
1588+
if (mCameraHelper == null) {
1589+
return false;
1590+
}
15641591
if (params.startsWith("startVideo")) {
15651592
Pattern pattern = Pattern.compile("startVideo_(\\d+)x(\\d+)");
15661593
Matcher matcher = pattern.matcher(params);
@@ -1569,7 +1596,7 @@ public boolean processCommand(String command, String params) {
15691596
int width = Integer.parseInt(matcher.group(1));
15701597
int height = Integer.parseInt(matcher.group(2));
15711598
mCameraHelper.setCameraSize(width, height);
1572-
if (mCameraHelper != null && !askForPermissions(permissionsForCamera, REQUEST_CODE_CAMERA_PERMISSION)) {
1599+
if (!askForPermissions(permissionsForCamera, REQUEST_CODE_CAMERA_PERMISSION)) {
15731600
mCameraHelper.startCamera();
15741601
}
15751602
} else if (mCameraHelper != null && params.equals("stopVideo")) {

libretro/Makefile.common

+1
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ SOURCES_CXX += \
617617
$(COREDIR)/HLE/KUBridge.cpp \
618618
$(COREDIR)/HLE/Plugins.cpp \
619619
$(COREDIR)/HLE/sceSha256.cpp \
620+
$(COREDIR)/HLE/sceSircs.cpp \
620621
$(COREDIR)/HLE/sceG729.cpp \
621622
$(COREDIR)/HLE/sceSfmt19937.cpp \
622623
$(COREDIR)/HLE/ReplaceTables.cpp \

0 commit comments

Comments
 (0)