1
0
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:
cathery 2024-11-06 20:00:07 +01:00
parent 670968ac65
commit e79be83161
18 changed files with 326 additions and 179 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "source/libstratosphere"]
path = source/libstratosphere
url = https://github.com/Atmosphere-NX/Atmosphere-libs.git

View File

@ -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)

View File

@ -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;
};

View File

@ -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);
}

View 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

View File

@ -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
*/
}

View File

@ -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; }
};

View File

@ -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

View File

@ -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
#---------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------

View File

@ -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
}
}]
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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();

View File

@ -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:

View File

@ -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