mirror of
https://github.com/cathery/sys-con.git
synced 2025-01-27 12:35:44 +00:00
Fix building for latest libnx, remove Atmosphere-libs dependency
This commit is contained in:
parent
670968ac65
commit
e79be83161
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "source/libstratosphere"]
|
||||
path = source/libstratosphere
|
||||
url = https://github.com/Atmosphere-NX/Atmosphere-libs.git
|
7
Makefile
7
Makefile
@ -1,4 +1,4 @@
|
||||
.PHONY: all build clean mrproper
|
||||
.PHONY: all build clean
|
||||
|
||||
SOURCE_DIR := source
|
||||
OUT_DIR := out
|
||||
@ -21,8 +21,3 @@ build:
|
||||
clean:
|
||||
$(MAKE) -C $(SOURCE_DIR) clean
|
||||
rm -rf $(OUT_DIR)
|
||||
|
||||
mrproper:
|
||||
$(MAKE) -C $(SOURCE_DIR) mrproper
|
||||
rm -rf $(OUT_DIR)
|
||||
|
@ -24,11 +24,11 @@ public:
|
||||
virtual Result Open() = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual Result ControlTransfer(uint8_t bmRequestType, uint8_t bmRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void *buffer) = 0;
|
||||
virtual Result ControlTransfer(uint8_t bmRequestType, uint8_t bmRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, const void *buffer) = 0;
|
||||
virtual Result ControlTransfer(uint8_t bmRequestType, uint8_t bmRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void* buffer) = 0;
|
||||
virtual Result ControlTransfer(uint8_t bmRequestType, uint8_t bmRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, const void* buffer) = 0;
|
||||
|
||||
virtual IUSBEndpoint *GetEndpoint(IUSBEndpoint::Direction direction, uint8_t index) = 0;
|
||||
virtual InterfaceDescriptor *GetDescriptor() = 0;
|
||||
virtual IUSBEndpoint* GetEndpoint(IUSBEndpoint::Direction direction, uint8_t index) = 0;
|
||||
virtual InterfaceDescriptor* GetDescriptor() = 0;
|
||||
|
||||
virtual Result Reset() = 0;
|
||||
};
|
@ -2,8 +2,9 @@
|
||||
#include "ControllerHelpers.h"
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
SwitchAbstractedPadHandler::SwitchAbstractedPadHandler(std::unique_ptr<IController> &&controller)
|
||||
SwitchAbstractedPadHandler::SwitchAbstractedPadHandler(std::unique_ptr<IController>&& controller)
|
||||
: SwitchVirtualGamepadHandler(std::move(controller))
|
||||
{
|
||||
}
|
||||
@ -46,7 +47,7 @@ void SwitchAbstractedPadHandler::Exit()
|
||||
ExitAbstractedPadState();
|
||||
}
|
||||
|
||||
//Used to give out unique ids to abstracted pads
|
||||
// Used to give out unique ids to abstracted pads
|
||||
static std::array<bool, 8> uniqueIDs{};
|
||||
|
||||
static s8 getUniqueId()
|
||||
@ -76,7 +77,7 @@ Result SwitchAbstractedPadHandler::InitAbstractedPadState()
|
||||
m_state.npadInterfaceType = HidNpadInterfaceType_USB;
|
||||
m_state.flags = 0xff;
|
||||
m_state.state.battery_level = 4;
|
||||
ControllerConfig *config = GetController()->GetConfig();
|
||||
ControllerConfig* config = GetController()->GetConfig();
|
||||
m_state.singleColorBody = config->bodyColor.rgbaValue;
|
||||
m_state.singleColorButtons = config->buttonsColor.rgbaValue;
|
||||
|
||||
@ -93,7 +94,7 @@ Result SwitchAbstractedPadHandler::ExitAbstractedPadState()
|
||||
return hiddbgUnsetAutoPilotVirtualPadState(m_abstractedPadID);
|
||||
}
|
||||
|
||||
void SwitchAbstractedPadHandler::FillAbstractedState(const NormalizedButtonData &data)
|
||||
void SwitchAbstractedPadHandler::FillAbstractedState(const NormalizedButtonData& data)
|
||||
{
|
||||
m_state.state.buttons = 0;
|
||||
m_state.state.buttons |= (data.buttons[0] ? HidNpadButton_X : 0);
|
||||
@ -113,7 +114,7 @@ void SwitchAbstractedPadHandler::FillAbstractedState(const NormalizedButtonData
|
||||
m_state.state.buttons |= (data.buttons[10] ? HidNpadButton_Minus : 0);
|
||||
m_state.state.buttons |= (data.buttons[11] ? HidNpadButton_Plus : 0);
|
||||
|
||||
ControllerConfig *config = GetController()->GetConfig();
|
||||
ControllerConfig* config = GetController()->GetConfig();
|
||||
|
||||
if (config && config->swapDPADandLSTICK)
|
||||
{
|
||||
@ -124,10 +125,10 @@ void SwitchAbstractedPadHandler::FillAbstractedState(const NormalizedButtonData
|
||||
|
||||
float daxis_x{}, daxis_y{};
|
||||
|
||||
daxis_y += data.buttons[12] ? 1.0f : 0.0f; //DUP
|
||||
daxis_x += data.buttons[13] ? 1.0f : 0.0f; //DRIGHT
|
||||
daxis_y += data.buttons[14] ? -1.0f : 0.0f; //DDOWN
|
||||
daxis_x += data.buttons[15] ? -1.0f : 0.0f; //DLEFT
|
||||
daxis_y += data.buttons[12] ? 1.0f : 0.0f; // DUP
|
||||
daxis_x += data.buttons[13] ? 1.0f : 0.0f; // DRIGHT
|
||||
daxis_y += data.buttons[14] ? -1.0f : 0.0f; // DDOWN
|
||||
daxis_x += data.buttons[15] ? -1.0f : 0.0f; // DLEFT
|
||||
|
||||
ConvertAxisToSwitchAxis(daxis_x, daxis_y, 0, &m_state.state.analog_stick_l.x, &m_state.state.analog_stick_l.y);
|
||||
}
|
||||
|
50
source/ControllerSwitch/SwitchUtils.h
Normal file
50
source/ControllerSwitch/SwitchUtils.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include "switch.h"
|
||||
|
||||
namespace SwitchUtils
|
||||
{
|
||||
constexpr size_t ThreadStackAlignment = 0x1000;
|
||||
constexpr size_t MemoryPageSize = 0x1000;
|
||||
|
||||
class ScopedLock
|
||||
{
|
||||
public:
|
||||
[[nodiscard]]
|
||||
explicit ScopedLock(Mutex& In) : mutex(In)
|
||||
{
|
||||
mutexLock(&mutex);
|
||||
}
|
||||
|
||||
~ScopedLock()
|
||||
{
|
||||
mutexUnlock(&mutex);
|
||||
}
|
||||
|
||||
ScopedLock(const ScopedLock&) = delete;
|
||||
ScopedLock& operator=(const ScopedLock&) = delete;
|
||||
|
||||
private:
|
||||
Mutex& mutex;
|
||||
};
|
||||
|
||||
#ifndef R_ABORT_UNLESS
|
||||
#define R_ABORT_UNLESS(rc) \
|
||||
{ \
|
||||
if (R_FAILED(rc)) [[unlikely]] \
|
||||
{ \
|
||||
diagAbortWithResult(rc); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef R_TRY
|
||||
#define R_TRY(rc) \
|
||||
{ \
|
||||
if (R_FAILED(rc)) \
|
||||
{ \
|
||||
return rc; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace SwitchUtils
|
@ -1,6 +1,6 @@
|
||||
#include "SwitchVirtualGamepadHandler.h"
|
||||
|
||||
SwitchVirtualGamepadHandler::SwitchVirtualGamepadHandler(std::unique_ptr<IController> &&controller)
|
||||
SwitchVirtualGamepadHandler::SwitchVirtualGamepadHandler(std::unique_ptr<IController>&& controller)
|
||||
: m_controller(std::move(controller))
|
||||
{
|
||||
}
|
||||
@ -19,20 +19,20 @@ void SwitchVirtualGamepadHandler::Exit()
|
||||
m_controller->Exit();
|
||||
}
|
||||
|
||||
void SwitchVirtualGamepadHandler::InputThreadLoop(void *handler)
|
||||
void SwitchVirtualGamepadHandler::InputThreadLoop(void* handler)
|
||||
{
|
||||
do
|
||||
{
|
||||
static_cast<SwitchVirtualGamepadHandler *>(handler)->UpdateInput();
|
||||
} while (static_cast<SwitchVirtualGamepadHandler *>(handler)->m_inputThreadIsRunning);
|
||||
static_cast<SwitchVirtualGamepadHandler*>(handler)->UpdateInput();
|
||||
} while (static_cast<SwitchVirtualGamepadHandler*>(handler)->m_inputThreadIsRunning);
|
||||
}
|
||||
|
||||
void SwitchVirtualGamepadHandler::OutputThreadLoop(void *handler)
|
||||
void SwitchVirtualGamepadHandler::OutputThreadLoop(void* handler)
|
||||
{
|
||||
do
|
||||
{
|
||||
static_cast<SwitchVirtualGamepadHandler *>(handler)->UpdateOutput();
|
||||
} while (static_cast<SwitchVirtualGamepadHandler *>(handler)->m_outputThreadIsRunning);
|
||||
static_cast<SwitchVirtualGamepadHandler*>(handler)->UpdateOutput();
|
||||
} while (static_cast<SwitchVirtualGamepadHandler*>(handler)->m_outputThreadIsRunning);
|
||||
}
|
||||
|
||||
Result SwitchVirtualGamepadHandler::InitInputThread()
|
||||
@ -70,17 +70,17 @@ void SwitchVirtualGamepadHandler::ExitOutputThread()
|
||||
static_assert(JOYSTICK_MAX == 32767 && JOYSTICK_MIN == -32767,
|
||||
"JOYSTICK_MAX and/or JOYSTICK_MIN has incorrect values. Update libnx");
|
||||
|
||||
void SwitchVirtualGamepadHandler::ConvertAxisToSwitchAxis(float x, float y, float deadzone, s32 *x_out, s32 *y_out)
|
||||
void SwitchVirtualGamepadHandler::ConvertAxisToSwitchAxis(float x, float y, float deadzone, s32* x_out, s32* y_out)
|
||||
{
|
||||
float floatRange = 2.0f;
|
||||
//JOYSTICK_MAX is 1 above and JOYSTICK_MIN is 1 below acceptable joystick values, causing crashes on various games including Xenoblade Chronicles 2 and Resident Evil 4
|
||||
// JOYSTICK_MAX is 1 above and JOYSTICK_MIN is 1 below acceptable joystick values, causing crashes on various games including Xenoblade Chronicles 2 and Resident Evil 4
|
||||
float newRange = (JOYSTICK_MAX - JOYSTICK_MIN);
|
||||
|
||||
*x_out = (((x + 1.0f) * newRange) / floatRange) + JOYSTICK_MIN;
|
||||
*y_out = (((y + 1.0f) * newRange) / floatRange) + JOYSTICK_MIN;
|
||||
/*
|
||||
OldRange = (OldMax - OldMin)
|
||||
NewRange = (NewMax - NewMin)
|
||||
OldRange = (OldMax - OldMin)
|
||||
NewRange = (NewMax - NewMin)
|
||||
NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
|
||||
*/
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
#pragma once
|
||||
#include "switch.h"
|
||||
#include "IController.h"
|
||||
#include <stratosphere.hpp>
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
//This class is a base class for SwitchHDLHandler and SwitchAbstractedPaadHandler.
|
||||
// This class is a base class for SwitchHDLHandler and SwitchAbstractedPaadHandler.
|
||||
class SwitchVirtualGamepadHandler
|
||||
{
|
||||
protected:
|
||||
HidVibrationDeviceHandle m_vibrationDeviceHandle;
|
||||
std::unique_ptr<IController> m_controller;
|
||||
|
||||
alignas(ams::os::ThreadStackAlignment) u8 input_thread_stack[0x1000];
|
||||
alignas(ams::os::ThreadStackAlignment) u8 output_thread_stack[0x1000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 input_thread_stack[0x1000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 output_thread_stack[0x1000];
|
||||
|
||||
Thread m_inputThread;
|
||||
Thread m_outputThread;
|
||||
@ -19,38 +19,38 @@ protected:
|
||||
bool m_inputThreadIsRunning = false;
|
||||
bool m_outputThreadIsRunning = false;
|
||||
|
||||
static void InputThreadLoop(void *argument);
|
||||
static void OutputThreadLoop(void *argument);
|
||||
static void InputThreadLoop(void* argument);
|
||||
static void OutputThreadLoop(void* argument);
|
||||
|
||||
public:
|
||||
SwitchVirtualGamepadHandler(std::unique_ptr<IController> &&controller);
|
||||
SwitchVirtualGamepadHandler(std::unique_ptr<IController>&& controller);
|
||||
virtual ~SwitchVirtualGamepadHandler();
|
||||
|
||||
//Override this if you want a custom init procedure
|
||||
// Override this if you want a custom init procedure
|
||||
virtual Result Initialize();
|
||||
//Override this if you want a custom exit procedure
|
||||
// Override this if you want a custom exit procedure
|
||||
virtual void Exit();
|
||||
|
||||
//Separately init the input-reading thread
|
||||
// Separately init the input-reading thread
|
||||
Result InitInputThread();
|
||||
//Separately close the input-reading thread
|
||||
// Separately close the input-reading thread
|
||||
void ExitInputThread();
|
||||
|
||||
//Separately init the rumble sending thread
|
||||
// Separately init the rumble sending thread
|
||||
Result InitOutputThread();
|
||||
//Separately close the rumble sending thread
|
||||
// Separately close the rumble sending thread
|
||||
void ExitOutputThread();
|
||||
|
||||
//The function to call indefinitely by the input thread
|
||||
// The function to call indefinitely by the input thread
|
||||
virtual void UpdateInput() = 0;
|
||||
//The function to call indefinitely by the output thread
|
||||
// The function to call indefinitely by the output thread
|
||||
virtual void UpdateOutput() = 0;
|
||||
|
||||
void ConvertAxisToSwitchAxis(float x, float y, float deadzone, s32 *x_out, s32 *y_out);
|
||||
void ConvertAxisToSwitchAxis(float x, float y, float deadzone, s32* x_out, s32* y_out);
|
||||
|
||||
Result SetControllerVibration(float strong_mag, float weak_mag);
|
||||
|
||||
//Get the raw controller pointer
|
||||
inline IController *GetController() { return m_controller.get(); }
|
||||
inline HidVibrationDeviceHandle *GetVibrationHandle() { return &m_vibrationDeviceHandle; }
|
||||
// Get the raw controller pointer
|
||||
inline IController* GetController() { return m_controller.get(); }
|
||||
inline HidVibrationDeviceHandle* GetVibrationHandle() { return &m_vibrationDeviceHandle; }
|
||||
};
|
@ -1,22 +1,16 @@
|
||||
COMPONENTS := libstratosphere AppletCompanion Sysmodule
|
||||
TOPTARGETS := all clean mrproper
|
||||
COMPONENTS := AppletCompanion Sysmodule
|
||||
TOPTARGETS := all clean
|
||||
|
||||
.PHONY: $(TOPTARGETS) $(COMPONENTS)
|
||||
|
||||
all: $(COMPONENTS)
|
||||
|
||||
libstratosphere:
|
||||
$(MAKE) -C $@
|
||||
|
||||
AppletCompanion:
|
||||
$(MAKE) -C $@
|
||||
|
||||
Sysmodule: libstratosphere
|
||||
Sysmodule:
|
||||
$(MAKE) -C $@
|
||||
|
||||
clean:
|
||||
$(MAKE) -C AppletCompanion clean
|
||||
$(MAKE) -C Sysmodule clean
|
||||
|
||||
mrproper: clean
|
||||
$(MAKE) -C libstratosphere clean
|
||||
$(MAKE) -C Sysmodule clean
|
@ -1,11 +1,72 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../libstratosphere/config/templates/stratosphere.mk
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||
#
|
||||
# NO_ICON: if set to anything, do not use icon.
|
||||
# NO_NACP: if set to anything, no .nacp file is generated.
|
||||
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
|
||||
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
|
||||
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
|
||||
# ICON is the filename of the icon (.jpg), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.jpg
|
||||
# - icon.jpg
|
||||
# - <libnx folder>/default_icon.jpg
|
||||
#
|
||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.json
|
||||
# - config.json
|
||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := sys-con
|
||||
SOURCES += ../ControllerSwitch ../ControllerLib ../ControllerLib/Controllers ../inih
|
||||
INCLUDES += ../ControllerSwitch ../ControllerLib ../inih
|
||||
BUILD := build
|
||||
SOURCES := source ../ControllerSwitch ../ControllerLib ../ControllerLib/Controllers ../inih
|
||||
DATA := data
|
||||
INCLUDES := include ../ControllerSwitch ../ControllerLib ../inih
|
||||
#ROMFS := romfs
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++23
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
@ -22,10 +83,9 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
|
||||
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
|
||||
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@ -42,8 +102,10 @@ else
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
@ -51,8 +113,6 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
@ -66,6 +126,35 @@ else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ICON)),)
|
||||
icons := $(wildcard *.jpg)
|
||||
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
|
||||
else
|
||||
ifneq (,$(findstring icon.jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/icon.jpg
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_ICON := $(TOPDIR)/$(ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_ICON)),)
|
||||
export NROFLAGS += --icon=$(APP_ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
|
||||
endif
|
||||
|
||||
ifneq ($(APP_TITLEID),)
|
||||
export NACPFLAGS += --titleid=$(APP_TITLEID)
|
||||
endif
|
||||
|
||||
ifneq ($(ROMFS),)
|
||||
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@ -78,7 +167,11 @@ $(BUILD):
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).npdm $(TARGET).nso $(TARGET).elf
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
||||
else
|
||||
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@ -90,22 +183,34 @@ DEPENDS := $(OFILES:.o=.d)
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
|
||||
all : $(OUTPUT).nro
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
|
||||
else
|
||||
$(OUTPUT).nro : $(OUTPUT).elf
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
all : $(OUTPUT).nsp
|
||||
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
$(OUTPUT).nsp : $(OUTPUT).nso
|
||||
else
|
||||
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
|
||||
endif
|
||||
|
||||
$(OUTPUT).nso : $(OUTPUT).elf
|
||||
|
||||
endif
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
@ -114,4 +219,4 @@ $(OUTPUT).elf : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "sys-con",
|
||||
"title_id": "0x690000000000000D",
|
||||
"title_id_range_min": "0x690000000000000D",
|
||||
"title_id_range_max": "0x690000000000000D",
|
||||
"version": "0.6.5",
|
||||
"program_id": "0x690000000000000D",
|
||||
"program_id_range_min": "0x690000000000000D",
|
||||
"program_id_range_max": "0x690000000000000D",
|
||||
"main_thread_stack_size": "0x4000",
|
||||
"main_thread_priority": 44,
|
||||
"default_cpu_id": 3,
|
||||
@ -10,9 +11,13 @@
|
||||
"is_retail": true,
|
||||
"pool_partition": 2,
|
||||
"is_64_bit": true,
|
||||
"signature_key_generation": 0,
|
||||
"address_space_type": 1,
|
||||
"system_resource_size": "0",
|
||||
"disable_device_address_space_merge": true,
|
||||
"optimize_memory_allocation": false,
|
||||
"disable_device_address_space_merge": true,
|
||||
"enable_alias_region_extra_size": false,
|
||||
"prevent_code_reads": false,
|
||||
"system_resource_size": "0",
|
||||
"filesystem_access": {
|
||||
"permissions": "0xffffffffffffffff"
|
||||
},
|
||||
@ -168,7 +173,8 @@
|
||||
"type": "debug_flags",
|
||||
"value": {
|
||||
"allow_debug": false,
|
||||
"force_debug": true
|
||||
"force_debug": true,
|
||||
"force_debug_prod": false
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "log.h"
|
||||
#include "ini.h"
|
||||
#include <cstring>
|
||||
#include <stratosphere.hpp>
|
||||
#include "usb_module.h"
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
namespace syscon::config
|
||||
{
|
||||
@ -23,7 +23,7 @@ namespace syscon::config
|
||||
// Thread to check for any config changes
|
||||
void ConfigChangedCheckThreadFunc(void *arg);
|
||||
|
||||
alignas(ams::os::ThreadStackAlignment) u8 config_thread_stack[0x2000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 config_thread_stack[0x2000];
|
||||
Thread g_config_changed_check_thread;
|
||||
|
||||
bool is_config_changed_check_thread_running = false;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "SwitchAbstractedPadHandler.h"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
@ -14,7 +15,7 @@ namespace syscon::controllers
|
||||
constexpr size_t MaxControllerHandlersSize = 10;
|
||||
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>> controllerHandlers;
|
||||
bool UseAbstractedPad;
|
||||
ams::os::Mutex controllerMutex(false);
|
||||
Mutex controllerMutex = 0;
|
||||
} // namespace
|
||||
|
||||
bool IsAtControllerLimit()
|
||||
@ -22,7 +23,7 @@ namespace syscon::controllers
|
||||
return controllerHandlers.size() >= MaxControllerHandlersSize;
|
||||
}
|
||||
|
||||
Result Insert(std::unique_ptr<IController> &&controllerPtr)
|
||||
Result Insert(std::unique_ptr<IController>&& controllerPtr)
|
||||
{
|
||||
std::unique_ptr<SwitchVirtualGamepadHandler> switchHandler;
|
||||
if (UseAbstractedPad)
|
||||
@ -39,19 +40,19 @@ namespace syscon::controllers
|
||||
Result rc = switchHandler->Initialize();
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
std::scoped_lock scoped_lock(controllerMutex);
|
||||
SwitchUtils::ScopedLock scoped_lock(controllerMutex);
|
||||
controllerHandlers.push_back(std::move(switchHandler));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>> &Get()
|
||||
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>>& Get()
|
||||
{
|
||||
return controllerHandlers;
|
||||
}
|
||||
|
||||
ams::os::Mutex &GetScopedLock()
|
||||
Mutex& GetScopedLock()
|
||||
{
|
||||
return controllerMutex;
|
||||
}
|
||||
@ -70,7 +71,7 @@ namespace syscon::controllers
|
||||
|
||||
void Reset()
|
||||
{
|
||||
std::scoped_lock scoped_lock(controllerMutex);
|
||||
SwitchUtils::ScopedLock scoped_lock(controllerMutex);
|
||||
controllerHandlers.clear();
|
||||
}
|
||||
|
||||
|
@ -2,17 +2,16 @@
|
||||
|
||||
#include "ControllerHelpers.h"
|
||||
#include "SwitchVirtualGamepadHandler.h"
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace syscon::controllers
|
||||
{
|
||||
bool IsAtControllerLimit();
|
||||
|
||||
Result Insert(std::unique_ptr<IController> &&controllerPtr);
|
||||
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>> &Get();
|
||||
ams::os::Mutex &GetScopedLock();
|
||||
Result Insert(std::unique_ptr<IController>&& controllerPtr);
|
||||
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>>& Get();
|
||||
Mutex& GetScopedLock();
|
||||
|
||||
//void Remove(void Remove(bool (*func)(std::unique_ptr<SwitchVirtualGamepadHandler> a)));;
|
||||
// void Remove(void Remove(bool (*func)(std::unique_ptr<SwitchVirtualGamepadHandler> a)));;
|
||||
|
||||
void Initialize();
|
||||
void Reset();
|
||||
|
@ -1,15 +1,17 @@
|
||||
#include "switch.h"
|
||||
#include "log.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stratosphere.hpp>
|
||||
#include <cstdarg>
|
||||
#include "SwitchUtils.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static ams::os::Mutex printMutex(false);
|
||||
static Mutex printMutex = 0;
|
||||
|
||||
void DiscardOldLogs()
|
||||
{
|
||||
std::scoped_lock printLock(printMutex);
|
||||
SwitchUtils::ScopedLock printLock(printMutex);
|
||||
|
||||
FsFileSystem *fs = fsdevGetDeviceFileSystem("sdmc");
|
||||
FsFileSystem* fs = fsdevGetDeviceFileSystem("sdmc");
|
||||
FsFile file;
|
||||
s64 fileSize;
|
||||
|
||||
@ -29,20 +31,25 @@ void DiscardOldLogs()
|
||||
}
|
||||
}
|
||||
|
||||
void WriteToLog(const char *fmt, ...)
|
||||
void WriteToLog(const char* fmt, ...)
|
||||
{
|
||||
std::scoped_lock printLock(printMutex);
|
||||
SwitchUtils::ScopedLock printLock(printMutex);
|
||||
|
||||
ams::TimeSpan ts = ams::os::ConvertToTimeSpan(ams::os::GetSystemTick());
|
||||
// ams::TimeSpan ts = ams::os::ConvertToTimeSpan(ams::os::GetSystemTick());
|
||||
|
||||
time_t unixTime = time(NULL);
|
||||
struct tm tStruct;
|
||||
localtime_r(&unixTime, &tStruct);
|
||||
|
||||
mkdir(CONFIG_PATH, 777);
|
||||
|
||||
FILE *fp = fopen(LOG_PATH, "a");
|
||||
FILE* fp = fopen(LOG_PATH, "a");
|
||||
|
||||
//Print time
|
||||
fprintf(fp, "%02lid %02li:%02li:%02li: ", ts.GetDays(), ts.GetHours() % 24, ts.GetMinutes() % 60, ts.GetSeconds() % 60);
|
||||
// Print time
|
||||
fprintf(fp, "%02i %02i:%02i:%02i: ", tStruct.tm_mday, tStruct.tm_hour, tStruct.tm_min, tStruct.tm_sec);
|
||||
// fprintf(fp, "%02lid %02li:%02li:%02li: ", ts.GetDays(), ts.GetHours() % 24, ts.GetMinutes() % 60, ts.GetSeconds() % 60);
|
||||
|
||||
//Print the actual text
|
||||
// Print the actual text
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vfprintf(fp, fmt, va);
|
||||
@ -54,6 +61,6 @@ void WriteToLog(const char *fmt, ...)
|
||||
|
||||
void LockedUpdateConsole()
|
||||
{
|
||||
std::scoped_lock printLock(printMutex);
|
||||
SwitchUtils::ScopedLock printLock(printMutex);
|
||||
consoleUpdate(NULL);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#include "switch.h"
|
||||
#include "log.h"
|
||||
#include <stratosphere.hpp>
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
#include "usb_module.h"
|
||||
#include "controller_handler.h"
|
||||
@ -8,57 +8,41 @@
|
||||
#include "psc_module.h"
|
||||
#include "SwitchHDLHandler.h"
|
||||
|
||||
#define APP_VERSION "0.6.4"
|
||||
#define APP_VERSION "0.6.5"
|
||||
|
||||
// Size of the inner heap (adjust as necessary).
|
||||
#define INNER_HEAP_SIZE 0x40'000
|
||||
|
||||
// libnx fake heap initialization
|
||||
extern "C"
|
||||
{
|
||||
// We aren't an applet, so disable applet functionality.
|
||||
// Sysmodules should not use applet*.
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
// We are a sysmodule, so don't use more FS sessions than needed.
|
||||
|
||||
// Sysmodules will normally only want to use one FS session.
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
// We don't need to reserve memory for fsdev, so don't use it.
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x40'000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
char nx_inner_heap[INNER_HEAP_SIZE];
|
||||
|
||||
// Newlib heap configuration function (makes malloc/free work).
|
||||
void __libnx_initheap(void)
|
||||
{
|
||||
// Newlib
|
||||
extern char *fake_heap_start;
|
||||
extern char *fake_heap_end;
|
||||
static u8 inner_heap[INNER_HEAP_SIZE];
|
||||
extern void* fake_heap_start;
|
||||
extern void* fake_heap_end;
|
||||
|
||||
fake_heap_start = nx_inner_heap;
|
||||
fake_heap_end = nx_inner_heap + nx_inner_heap_size;
|
||||
}
|
||||
|
||||
// Exception handling
|
||||
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
|
||||
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||
void __libnx_exception_handler(ThreadExceptionDump *ctx)
|
||||
{
|
||||
ams::CrashHandler(ctx);
|
||||
// Configure the newlib heap.
|
||||
fake_heap_start = inner_heap;
|
||||
fake_heap_end = inner_heap + sizeof(inner_heap);
|
||||
}
|
||||
}
|
||||
|
||||
// libstratosphere variables
|
||||
namespace ams
|
||||
{
|
||||
ncm::ProgramId CurrentProgramId = {0x690000000000000D};
|
||||
namespace result
|
||||
{
|
||||
bool CallFatalOnResultAssertion = true;
|
||||
}
|
||||
} // namespace ams
|
||||
void* workmem = nullptr;
|
||||
size_t workmem_size = 0x1000;
|
||||
|
||||
extern "C" void __appInit(void)
|
||||
{
|
||||
R_ABORT_UNLESS(smInitialize());
|
||||
// ams::sm::DoWithSession([]
|
||||
{
|
||||
//Initialize system firmware version
|
||||
// Initialize system firmware version
|
||||
R_ABORT_UNLESS(setsysInitialize());
|
||||
SetSysFirmwareVersion fw;
|
||||
R_ABORT_UNLESS(setsysGetFirmwareVersion(&fw));
|
||||
@ -67,7 +51,16 @@ extern "C" void __appInit(void)
|
||||
|
||||
R_ABORT_UNLESS(hiddbgInitialize());
|
||||
if (hosversionAtLeast(7, 0, 0))
|
||||
R_ABORT_UNLESS(hiddbgAttachHdlsWorkBuffer(&SwitchHDLHandler::GetHdlsSessionId()));
|
||||
{
|
||||
workmem = aligned_alloc(0x1000, workmem_size);
|
||||
|
||||
if (!workmem)
|
||||
{
|
||||
diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_InitFail_HID));
|
||||
}
|
||||
|
||||
R_ABORT_UNLESS(hiddbgAttachHdlsWorkBuffer(&SwitchHDLHandler::GetHdlsSessionId(), workmem, workmem_size));
|
||||
}
|
||||
R_ABORT_UNLESS(usbHsInitialize());
|
||||
R_ABORT_UNLESS(pscmInitialize());
|
||||
R_ABORT_UNLESS(fsInitialize());
|
||||
@ -86,11 +79,12 @@ extern "C" void __appExit(void)
|
||||
hiddbgExit();
|
||||
fsdevUnmountAll();
|
||||
fsExit();
|
||||
free(workmem);
|
||||
}
|
||||
|
||||
using namespace syscon;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
WriteToLog("\n\nNew sysmodule session started on version " APP_VERSION);
|
||||
config::Initialize();
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "psc_module.h"
|
||||
#include <stratosphere.hpp>
|
||||
#include "usb_module.h"
|
||||
#include "config_handler.h"
|
||||
#include "controller_handler.h"
|
||||
#include "log.h"
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
namespace syscon::psc
|
||||
{
|
||||
@ -13,15 +13,15 @@ namespace syscon::psc
|
||||
Waiter pscModuleWaiter;
|
||||
const uint32_t dependencies[] = {PscPmModuleId_Fs};
|
||||
|
||||
//Thread to check for psc:pm state change (console waking up/going to sleep)
|
||||
void PscThreadFunc(void *arg);
|
||||
// Thread to check for psc:pm state change (console waking up/going to sleep)
|
||||
void PscThreadFunc(void* arg);
|
||||
|
||||
alignas(ams::os::ThreadStackAlignment) u8 psc_thread_stack[0x1000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 psc_thread_stack[0x1000];
|
||||
Thread g_psc_thread;
|
||||
|
||||
bool is_psc_thread_running = false;
|
||||
|
||||
void PscThreadFunc(void *arg)
|
||||
void PscThreadFunc(void* arg)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -35,11 +35,11 @@ namespace syscon::psc
|
||||
{
|
||||
case PscPmState_Awake:
|
||||
case PscPmState_ReadyAwaken:
|
||||
//usb::CreateUsbEvents();
|
||||
// usb::CreateUsbEvents();
|
||||
break;
|
||||
case PscPmState_ReadySleep:
|
||||
case PscPmState_ReadyShutdown:
|
||||
//usb::DestroyUsbEvents();
|
||||
// usb::DestroyUsbEvents();
|
||||
controllers::Reset();
|
||||
break;
|
||||
default:
|
||||
|
@ -3,12 +3,11 @@
|
||||
#include "controller_handler.h"
|
||||
#include "config_handler.h"
|
||||
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "SwitchUSBDevice.h"
|
||||
#include "ControllerHelpers.h"
|
||||
#include "log.h"
|
||||
#include <string.h>
|
||||
#include "SwitchUtils.h"
|
||||
|
||||
namespace syscon::usb
|
||||
{
|
||||
@ -19,18 +18,18 @@ namespace syscon::usb
|
||||
|
||||
constexpr size_t MaxUsbHsInterfacesSize = 16;
|
||||
|
||||
ams::os::Mutex usbMutex(false);
|
||||
Mutex usbMutex = 0;
|
||||
|
||||
//Thread that waits on generic usb event
|
||||
void UsbEventThreadFunc(void *arg);
|
||||
//Thread that waits on sony vendor usb event
|
||||
void UsbSonyEventThreadFunc(void *arg);
|
||||
//Thread that waits on any disconnected usb devices
|
||||
void UsbInterfaceChangeThreadFunc(void *arg);
|
||||
// Thread that waits on generic usb event
|
||||
void UsbEventThreadFunc(void* arg);
|
||||
// Thread that waits on sony vendor usb event
|
||||
void UsbSonyEventThreadFunc(void* arg);
|
||||
// Thread that waits on any disconnected usb devices
|
||||
void UsbInterfaceChangeThreadFunc(void* arg);
|
||||
|
||||
alignas(ams::os::ThreadStackAlignment) u8 usb_event_thread_stack[0x2000];
|
||||
alignas(ams::os::ThreadStackAlignment) u8 sony_event_thread_stack[0x2000];
|
||||
alignas(ams::os::ThreadStackAlignment) u8 usb_interface_change_thread_stack[0x2000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 usb_event_thread_stack[0x2000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 sony_event_thread_stack[0x2000];
|
||||
alignas(SwitchUtils::ThreadStackAlignment) u8 usb_interface_change_thread_stack[0x2000];
|
||||
|
||||
Thread g_usb_event_thread;
|
||||
Thread g_sony_event_thread;
|
||||
@ -46,7 +45,7 @@ namespace syscon::usb
|
||||
s32 QueryInterfaces(u8 iclass, u8 isubclass, u8 iprotocol);
|
||||
s32 QueryVendorProduct(uint16_t vendor_id, uint16_t product_id);
|
||||
|
||||
void UsbEventThreadFunc(void *arg)
|
||||
void UsbEventThreadFunc(void* arg)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -54,7 +53,7 @@ namespace syscon::usb
|
||||
{
|
||||
WriteToLog("Catch-all event went off");
|
||||
|
||||
std::scoped_lock usbLock(usbMutex);
|
||||
SwitchUtils::ScopedLock usbLock(usbMutex);
|
||||
if (!controllers::IsAtControllerLimit())
|
||||
{
|
||||
s32 total_entries;
|
||||
@ -75,7 +74,7 @@ namespace syscon::usb
|
||||
} while (is_usb_event_thread_running);
|
||||
}
|
||||
|
||||
void UsbSonyEventThreadFunc(void *arg)
|
||||
void UsbSonyEventThreadFunc(void* arg)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -83,7 +82,7 @@ namespace syscon::usb
|
||||
{
|
||||
WriteToLog("Sony event went off");
|
||||
|
||||
std::scoped_lock usbLock(usbMutex);
|
||||
SwitchUtils::ScopedLock usbLock(usbMutex);
|
||||
if (!controllers::IsAtControllerLimit())
|
||||
{
|
||||
s32 total_entries;
|
||||
@ -97,7 +96,7 @@ namespace syscon::usb
|
||||
} while (is_usb_event_thread_running);
|
||||
}
|
||||
|
||||
void UsbInterfaceChangeThreadFunc(void *arg)
|
||||
void UsbInterfaceChangeThreadFunc(void* arg)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -106,8 +105,8 @@ namespace syscon::usb
|
||||
s32 total_entries;
|
||||
WriteToLog("Interface state was changed");
|
||||
|
||||
std::scoped_lock usbLock(usbMutex);
|
||||
std::scoped_lock controllersLock(controllers::GetScopedLock());
|
||||
SwitchUtils::ScopedLock usbLock(usbMutex);
|
||||
SwitchUtils::ScopedLock controllersLock(controllers::GetScopedLock());
|
||||
|
||||
eventClear(usbHsGetInterfaceStateChangeEvent());
|
||||
memset(interfaces, 0, sizeof(interfaces));
|
||||
@ -117,13 +116,13 @@ namespace syscon::usb
|
||||
{
|
||||
bool found_flag = false;
|
||||
|
||||
for (auto &&ptr : (*it)->GetController()->GetDevice()->GetInterfaces())
|
||||
for (auto&& ptr : (*it)->GetController()->GetDevice()->GetInterfaces())
|
||||
{
|
||||
//We check if a device was removed by comparing the controller's interfaces and the currently acquired interfaces
|
||||
//If we didn't find a single matching interface ID, we consider a controller removed
|
||||
// We check if a device was removed by comparing the controller's interfaces and the currently acquired interfaces
|
||||
// If we didn't find a single matching interface ID, we consider a controller removed
|
||||
for (int i = 0; i != total_entries; ++i)
|
||||
{
|
||||
if (interfaces[i].inf.ID == static_cast<SwitchUSBInterface *>(ptr.get())->GetID())
|
||||
if (interfaces[i].inf.ID == static_cast<SwitchUSBInterface*>(ptr.get())->GetID())
|
||||
{
|
||||
found_flag = true;
|
||||
break;
|
||||
|
@ -1 +0,0 @@
|
||||
Subproject commit dc52a32285c62fbb68e701393ec3b4efdc452343
|
Loading…
x
Reference in New Issue
Block a user