Skip to content

Commit

Permalink
Merge pull request #18684 from Florin9doi/infrared
Browse files Browse the repository at this point in the history
sceSircs/Infrared support on Android
  • Loading branch information
hrydgard committed Jan 12, 2024
2 parents 1d076e2 + cad232e commit 5bb4757
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/sceSfmt19937.h
Core/HLE/sceSha256.cpp
Core/HLE/sceSha256.h
Core/HLE/sceSircs.cpp
Core/HLE/sceSircs.h
Core/HLE/sceSsl.cpp
Core/HLE/sceSsl.h
Core/HLE/sceUmd.cpp
Expand Down
4 changes: 4 additions & 0 deletions Common/System/Request.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ inline void System_GPSCommand(const std::string &command) {
g_requestManager.MakeSystemRequest(SystemRequestType::GPS_COMMAND, nullptr, nullptr, command, "", 0);
}

inline void System_InfraredCommand(const std::string &command) {
g_requestManager.MakeSystemRequest(SystemRequestType::INFRARED_COMMAND, nullptr, nullptr, command, "", 0);
}

inline void System_MicrophoneCommand(const std::string &command) {
g_requestManager.MakeSystemRequest(SystemRequestType::MICROPHONE_COMMAND, nullptr, nullptr, command, "", 0);
}
Expand Down
1 change: 1 addition & 0 deletions Common/System/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ enum class SystemRequestType {
// High-level hardware control
CAMERA_COMMAND,
GPS_COMMAND,
INFRARED_COMMAND,
MICROPHONE_COMMAND,
};

Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@
<ClCompile Include="HLE\sceSas.cpp" />
<ClCompile Include="HLE\sceSfmt19937.cpp" />
<ClCompile Include="HLE\sceSha256.cpp" />
<ClCompile Include="HLE\sceSircs.cpp" />
<ClCompile Include="HLE\sceSsl.cpp" />
<ClCompile Include="HLE\sceUmd.cpp" />
<ClCompile Include="HLE\sceUsb.cpp" />
Expand Down Expand Up @@ -1301,6 +1302,7 @@
<ClInclude Include="HLE\sceSas.h" />
<ClInclude Include="HLE\sceSfmt19937.h" />
<ClInclude Include="HLE\sceSha256.h" />
<ClInclude Include="HLE\sceSircs.h" />
<ClInclude Include="HLE\sceSsl.h" />
<ClInclude Include="HLE\sceUmd.h" />
<ClInclude Include="HLE\sceUsb.h" />
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,9 @@
<ClCompile Include="HLE\sceSha256.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\sceSircs.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="Util\AudioFormat.cpp">
<Filter>Util</Filter>
</ClCompile>
Expand Down Expand Up @@ -1773,6 +1776,9 @@
<ClInclude Include="HLE\sceSha256.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\sceSircs.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="Util\AudioFormat.h">
<Filter>Util</Filter>
</ClInclude>
Expand Down
2 changes: 2 additions & 0 deletions Core/HLE/HLETables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "scePsmf.h"
#include "sceRtc.h"
#include "sceSas.h"
#include "sceSircs.h"
#include "sceSsl.h"
#include "sceUmd.h"
#include "sceUsb.h"
Expand Down Expand Up @@ -307,6 +308,7 @@ void RegisterAllModules() {
Register_sceDdrdb();
Register_mp4msv();
Register_InterruptManagerForKernel();
Register_sceSircs();
// add new modules here.
}

5 changes: 0 additions & 5 deletions Core/HLE/sceHttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,6 @@ static int sceHttpGetContentLength(int requestID, u64 contentLengthPtr) {
return 0;
}

/*
* 0x62411801 sceSircsInit
0x19155a2f sceSircsEnd
0x71eef62d sceSircsSend
*/
const HLEFunction sceHttp[] = {
{0XAB1ABE07, &WrapI_I<sceHttpInit>, "sceHttpInit", 'i', "i" },
{0XD1C8945E, &WrapI_V<sceHttpEnd>, "sceHttpEnd", 'i', "" },
Expand Down
59 changes: 59 additions & 0 deletions Core/HLE/sceSircs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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/sceSircs.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/MemMapHelpers.h"

int sceSircsSend(u32 dataAddr, int count) {
auto data = PSPPointer<SircsData>::Create(dataAddr);
if (data.IsValid()) {
INFO_LOG(HLE, "%s (version=0x%x, command=0x%x, address=0x%x, count=%d)",
__FUNCTION__, data->version, data->command, data->address, count);
#if PPSSPP_PLATFORM(ANDROID)
char command[40] = {0};
snprintf(command, sizeof(command), "sircs_%d_%d_%d_%d",
data->version, data->command, data->address, count);
System_InfraredCommand(command);
#endif
data.NotifyRead("sceSircsSend");
}
return 0;
}

const HLEFunction sceSircs[] =
{
{0X62411801, nullptr, "sceSircsInit", '?', "" },
{0X19155A2F, nullptr, "sceSircsEnd", '?', "" },
{0X71EEF62D, &WrapI_UI<sceSircsSend>, "sceSircsSend", 'i', "xi" },
{0x83381633, nullptr, "sceSircsReceive", '?', "" },
};

void Register_sceSircs()
{
RegisterModule("sceSircs", ARRAY_SIZE(sceSircs), sceSircs);
}
28 changes: 28 additions & 0 deletions Core/HLE/sceSircs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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/.

#pragma once

#include "Core/HLE/FunctionWrappers.h"

void Register_sceSircs();

typedef struct {
u8 version;
u8 command;
u16 address;
} SircsData;
2 changes: 2 additions & 0 deletions UWP/CoreUWP/CoreUWP.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
<ClInclude Include="..\..\Core\HLE\sceSas.h" />
<ClInclude Include="..\..\Core\HLE\sceSfmt19937.h" />
<ClInclude Include="..\..\Core\HLE\sceSha256.h" />
<ClInclude Include="..\..\Core\HLE\sceSircs.h" />
<ClInclude Include="..\..\Core\HLE\sceSsl.h" />
<ClInclude Include="..\..\Core\HLE\sceUmd.h" />
<ClInclude Include="..\..\Core\HLE\sceUsb.h" />
Expand Down Expand Up @@ -486,6 +487,7 @@
<ClCompile Include="..\..\Core\HLE\sceSas.cpp" />
<ClCompile Include="..\..\Core\HLE\sceSfmt19937.cpp" />
<ClCompile Include="..\..\Core\HLE\sceSha256.cpp" />
<ClCompile Include="..\..\Core\HLE\sceSircs.cpp" />
<ClCompile Include="..\..\Core\HLE\sceSsl.cpp" />
<ClCompile Include="..\..\Core\HLE\sceUmd.cpp" />
<ClCompile Include="..\..\Core\HLE\sceUsb.cpp" />
Expand Down
1 change: 1 addition & 0 deletions android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<uses-permission android:name="archos.permission.FULLSCREEN.FULL" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.TRANSMIT_IR" />
<uses-permission-sdk-23 android:name="android.permission.CAMERA" />
<uses-permission-sdk-23 android:name="android.permission.RECORD_AUDIO" />

Expand Down
1 change: 1 addition & 0 deletions android/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Core/HLE/sceSas.cpp \
$(SRC)/Core/HLE/sceSfmt19937.cpp \
$(SRC)/Core/HLE/sceSha256.cpp \
$(SRC)/Core/HLE/sceSircs.cpp \
$(SRC)/Core/HLE/sceSsl.cpp \
$(SRC)/Core/HLE/sceUmd.cpp \
$(SRC)/Core/HLE/sceUsb.cpp \
Expand Down
3 changes: 3 additions & 0 deletions android/jni/app-android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
case SystemRequestType::GPS_COMMAND:
PushCommand("gps_command", param1);
return true;
case SystemRequestType::INFRARED_COMMAND:
PushCommand("infrared_command", param1);
return true;
case SystemRequestType::MICROPHONE_COMMAND:
PushCommand("microphone_command", param1);
return true;
Expand Down
75 changes: 75 additions & 0 deletions android/src/org/ppsspp/ppsspp/InfraredHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.ppsspp.ppsspp;

import android.content.Context;
import android.hardware.ConsumerIrManager;
import android.hardware.ConsumerIrManager.CarrierFrequencyRange;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
class InfraredHelper {
private static final String TAG = InfraredHelper.class.getSimpleName();
private static final int SIRC_FREQ = 40000;
private ConsumerIrManager mConsumerIrManager;

InfraredHelper(Context context) throws Exception {
mConsumerIrManager = (ConsumerIrManager) context.getSystemService(Context.CONSUMER_IR_SERVICE);
Log.d(TAG, "HasIrEmitter: " + mConsumerIrManager.hasIrEmitter());
if (!mConsumerIrManager.hasIrEmitter()) {
throw new Exception("No Ir Emitter");
}
boolean sirc_freq_supported = false;
CarrierFrequencyRange[] carrierFrequencies = mConsumerIrManager.getCarrierFrequencies();
for (CarrierFrequencyRange freq : carrierFrequencies) {
Log.d(TAG, "CarrierFrequencies: " + freq.getMinFrequency() + " -> " + freq.getMaxFrequency());
if (freq.getMinFrequency() <= SIRC_FREQ && SIRC_FREQ <= freq.getMaxFrequency()) {
sirc_freq_supported = true;
}
}
if (!sirc_freq_supported) {
throw new Exception("Sirc Frequency unsupported");
}
}

void sendSircCommand(int version, int command, int address, int count) {
final List<Integer> start = Arrays.asList(2400, 600);
final List<Integer> one = Arrays.asList(1200, 600);
final List<Integer> zero = Arrays.asList( 600, 600);

List<Integer> iterList = new ArrayList<>();
iterList.addAll(start);

for (int i = 0; i < version; i++) {
List<Integer> val = i < 7
? ((command >> i ) & 1) == 1 ? one : zero
: ((address >> i - 7) & 1) == 1 ? one : zero;
iterList.addAll(val);
}

int iterSum = 0;
for (int i = 0; i < iterList.size() - 1; i++) {
iterSum += iterList.get(i);
}
int lastVal = 52000 - iterSum; // SIRC cicle = 52ms
iterList.set(iterList.size() - 1, lastVal);

List<Integer> patternList = new ArrayList<>();
// Android is limited to 2 seconds => max 38 loops of 52ms each
// Limit even further to 4 loops for now
for (int i = 0; i < count && i < 4; i++) {
patternList.addAll(iterList);
}

int[] pattern = new int[patternList.size()];
for (int i = 0; i < patternList.size(); i++) {
pattern[i] = patternList.get(i);
}
mConsumerIrManager.transmit(SIRC_FREQ, pattern);
}
}
29 changes: 28 additions & 1 deletion android/src/org/ppsspp/ppsspp/NativeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public abstract class NativeActivity extends Activity {
private PowerSaveModeReceiver mPowerSaveModeReceiver = null;
private SizeManager sizeManager = null;
private static LocationHelper mLocationHelper;
private static InfraredHelper mInfraredHelper;
private static CameraHelper mCameraHelper;

private static final String[] permissionsForStorage = {
Expand Down Expand Up @@ -472,6 +473,14 @@ public void Initialize() {
}

mLocationHelper = new LocationHelper(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
mInfraredHelper = new InfraredHelper(this);
} catch (Exception e) {
mInfraredHelper = null;
Log.i(TAG, "InfraredHelper exception: " + e);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// android.graphics.SurfaceTexture is not available before version 11.
mCameraHelper = new CameraHelper(this);
Expand Down Expand Up @@ -1560,7 +1569,25 @@ public boolean processCommand(String command, String params) {
} else if (params.equals("close")) {
mLocationHelper.stopLocationUpdates();
}
} else if (command.equals("infrared_command")) {
if (mInfraredHelper == null) {
return false;
}
if (params.startsWith("sircs")) {
Pattern pattern = Pattern.compile("sircs_(\\d+)_(\\d+)_(\\d+)_(\\d+)");
Matcher matcher = pattern.matcher(params);
if (!matcher.matches())
return false;
int ir_version = Integer.parseInt(matcher.group(1));
int ir_command = Integer.parseInt(matcher.group(2));
int ir_address = Integer.parseInt(matcher.group(3));
int ir_count = Integer.parseInt(matcher.group(4));
mInfraredHelper.sendSircCommand(ir_version, ir_command, ir_address, ir_count);
}
} else if (command.equals("camera_command")) {
if (mCameraHelper == null) {
return false;
}
if (params.startsWith("startVideo")) {
Pattern pattern = Pattern.compile("startVideo_(\\d+)x(\\d+)");
Matcher matcher = pattern.matcher(params);
Expand All @@ -1569,7 +1596,7 @@ public boolean processCommand(String command, String params) {
int width = Integer.parseInt(matcher.group(1));
int height = Integer.parseInt(matcher.group(2));
mCameraHelper.setCameraSize(width, height);
if (mCameraHelper != null && !askForPermissions(permissionsForCamera, REQUEST_CODE_CAMERA_PERMISSION)) {
if (!askForPermissions(permissionsForCamera, REQUEST_CODE_CAMERA_PERMISSION)) {
mCameraHelper.startCamera();
}
} else if (mCameraHelper != null && params.equals("stopVideo")) {
Expand Down
1 change: 1 addition & 0 deletions libretro/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ SOURCES_CXX += \
$(COREDIR)/HLE/KUBridge.cpp \
$(COREDIR)/HLE/Plugins.cpp \
$(COREDIR)/HLE/sceSha256.cpp \
$(COREDIR)/HLE/sceSircs.cpp \
$(COREDIR)/HLE/sceG729.cpp \
$(COREDIR)/HLE/sceSfmt19937.cpp \
$(COREDIR)/HLE/ReplaceTables.cpp \
Expand Down

0 comments on commit 5bb4757

Please sign in to comment.