Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sceSircs/Infrared support on Android #18684

Merged
merged 1 commit into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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