mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-03 12:12:06 +00:00
sceSircs/Infrared support on Android
This commit is contained in:
parent
83999b854b
commit
cad232e60e
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ enum class SystemRequestType {
|
||||
// High-level hardware control
|
||||
CAMERA_COMMAND,
|
||||
GPS_COMMAND,
|
||||
INFRARED_COMMAND,
|
||||
MICROPHONE_COMMAND,
|
||||
};
|
||||
|
||||
|
@ -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" />
|
||||
@ -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" />
|
||||
|
@ -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>
|
||||
@ -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>
|
||||
|
@ -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"
|
||||
@ -307,6 +308,7 @@ void RegisterAllModules() {
|
||||
Register_sceDdrdb();
|
||||
Register_mp4msv();
|
||||
Register_InterruptManagerForKernel();
|
||||
Register_sceSircs();
|
||||
// add new modules here.
|
||||
}
|
||||
|
||||
|
@ -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', "" },
|
||||
|
59
Core/HLE/sceSircs.cpp
Normal file
59
Core/HLE/sceSircs.cpp
Normal file
@ -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
Core/HLE/sceSircs.h
Normal file
28
Core/HLE/sceSircs.h
Normal file
@ -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;
|
@ -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" />
|
||||
@ -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" />
|
||||
|
@ -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" />
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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;
|
||||
|
75
android/src/org/ppsspp/ppsspp/InfraredHelper.java
Normal file
75
android/src/org/ppsspp/ppsspp/InfraredHelper.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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 = {
|
||||
@ -472,6 +473,14 @@ public abstract class NativeActivity extends Activity {
|
||||
}
|
||||
|
||||
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);
|
||||
@ -1560,7 +1569,25 @@ public abstract class NativeActivity extends Activity {
|
||||
} 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);
|
||||
@ -1569,7 +1596,7 @@ public abstract class NativeActivity extends Activity {
|
||||
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")) {
|
||||
|
@ -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 \
|
||||
|
Loading…
x
Reference in New Issue
Block a user