wip:cleanup

This commit is contained in:
Lucas 2024-09-22 23:58:01 +02:00 committed by Lucas Peter
parent 612cfb7877
commit 804e5fe911
No known key found for this signature in database
2 changed files with 118 additions and 64 deletions

View file

@ -13,22 +13,6 @@ void USkyPortalSubsystem::Initialize(FSubsystemCollectionBase& Collection)
// Custom initialization logic // Custom initialization logic
UE_LOG(LogTemp, Log, TEXT("SkyPortalSubsystem Initialized")); UE_LOG(LogTemp, Log, TEXT("SkyPortalSubsystem Initialized"));
// Initialize HIDAPI
/*May be not needed
int res = hid_init();
if (res == 0)
{
UE_LOG(LogHIDApi, Log, TEXT("HIDAPI initialized successfully."));
}
else
{
UE_LOG(LogHIDApi, Error, TEXT("Failed to initialize HIDAPI."));
HidError = hid_error(NULL);
UE_LOG(LogHIDApi, Error, TEXT("%s"), *HidError);
}
*/
} }
void USkyPortalSubsystem::Deinitialize() void USkyPortalSubsystem::Deinitialize()
@ -159,30 +143,36 @@ void USkyPortalSubsystem::ChangePortalColor(const FLinearColor& Color)
// no response for this one. // no response for this one.
Write(&req); Write(&req);
} }
void USkyPortalSubsystem::ChangePortalColorside(const FLinearColor& Color, const EPortalSide PortalSide, const float BlendTime ) void USkyPortalSubsystem::ChangePortalColorside(const FLinearColor& Color, const EPortalSide PortalSide, const float BlendTime)
{ {
if (PortalSide == EPortalSide::TRAP) {
UE_LOG(LogSkyportalIO, Error, TEXT("This function should only be called for the left or right side of the portal"));
return;
}
unsigned char r = FMath::Clamp(Color.R * 100, 0.0f, 100.0f);
unsigned char g = FMath::Clamp(Color.G * 100, 0.0f, 100.0f);
unsigned char b = FMath::Clamp(Color.B * 100, 0.0f, 100.0f);
unsigned char r = FMath::Clamp(Color.R * 100, 0, 255);
unsigned char g = FMath::Clamp(Color.G * 100, 0, 255);
unsigned char b = FMath::Clamp(Color.B * 100, 0, 255);
EPortalSide _portalside;
RWBlock req, res; RWBlock req, res;
memset(req.buf, 0, rw_buf_size); memset(req.buf, 0, rw_buf_size);
req.buf[1] = 'J'; if (PortalSide == EPortalSide::BOTH) {
switch (PortalSide) { _portalside = EPortalSide::LEFT;
}
switch (_portalside) {
case EPortalSide::LEFT: case EPortalSide::LEFT:
req.buf[1] = 'J';
req.buf[2] = 0x00; req.buf[2] = 0x00;
case EPortalSide::RIGHT: case EPortalSide::RIGHT:
req.buf[1] = 'J';
req.buf[2] = 0x02; req.buf[2] = 0x02;
case EPortalSide::BOTH: case EPortalSide::TRAP:
req.buf[2] = 0x01; //maybe that doesnt work, will give it a try req.buf[1] = 'L';
req.buf[2] = 0x01;
req.buf[3] = FMath::Max3(r, g, b); // calculate brightness
Write(&req); //since it's a color command for trap, only 3 bytes are needed, no response.
return;
} }
req.buf[3] = r; // R req.buf[3] = r; // R
req.buf[4] = g; // G req.buf[4] = g; // G
req.buf[5] = b; // B req.buf[5] = b; // B
@ -196,6 +186,9 @@ void USkyPortalSubsystem::ChangePortalColorside(const FLinearColor& Color, const
do { Write(&req); } while (CheckResponse(&res, 'J')); do { Write(&req); } while (CheckResponse(&res, 'J'));
if (PortalSide == EPortalSide::BOTH) {
ChangePortalColorside(Color, EPortalSide::RIGHT, BlendTime); // send a second command for the right side
}
} }
//} //}
@ -250,18 +243,18 @@ void USkyPortalSubsystem::Write(RWBlock* pb)
} }
#else #else
void USkyPortalSubsystem::Write(RWBlock *pb) { void USkyPortalSubsystem::Write(RWBlock* pb) {
if (!ensure(PortalDevice)) { if (!ensure(PortalDevice)) {
UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found"));
return; return;
} }
pb->buf[0] = 0; // Use report 0 pb->buf[0] = 0; // Use report 0
ensureMsgf(hid_write(PortalDevice, pb->buf, 0x21) != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice)); ensureMsgf(hid_write(PortalDevice, pb->buf, 0x21) != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice));
UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write to Portal. error:\n %s"), hid_error(PortalDevice)); UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write to Portal. error:\n %s"), hid_error(PortalDevice));
} }
#endif #endif
@ -270,8 +263,11 @@ void USkyPortalSubsystem::Sleep(int sleepMs) {
FPlatformProcess::Sleep(sleepMs * 0.0001); FPlatformProcess::Sleep(sleepMs * 0.0001);
} }
// TODO: Refacto this function to handle better the response/output from the portal /* Verify the command response, when only a character is sended by the portal.
bool USkyPortalSubsystem::CheckResponse(RWBlock *res, char expect) *
*TODO: Refacto this function to handle better the response/output from the portal
*/
bool USkyPortalSubsystem::CheckResponse(RWBlock* res, char expect)
{ {
if (!PortalDevice) { if (!PortalDevice) {
return false; return false;
@ -415,11 +411,26 @@ bool USkyPortalSubsystem::ConnectPortal()
Sleep(500); Sleep(500);
ChangePortalColor(FLinearColor(0xC8, 0xC8, 0xC8)); ChangePortalColor(FLinearColor(0xC8, 0xC8, 0xC8));
UE_LOG(LogSkyportalIO, Log, TEXT("Portal Status: %d\n"), PortalStatus()); UE_LOG(LogSkyportalIO, Log, TEXT("Portal Status: "), PortalStatus());
} }
return bPortalConnected; return bPortalConnected;
} }
bool USkyPortalSubsystem::bIsPortalReady()
{
return false;
}
void USkyPortalSubsystem::SendPortalCommand(EPortalCommand Command)
{
}
void USkyPortalSubsystem::SendPortalSound(USoundWave* Sound)
{
}
unsigned char USkyPortalSubsystem::PortalStatus() unsigned char USkyPortalSubsystem::PortalStatus()

View file

@ -7,6 +7,7 @@
#include "SkyPortalSubsystem.generated.h" #include "SkyPortalSubsystem.generated.h"
#pragma region Definitions
UENUM(BlueprintType) UENUM(BlueprintType)
enum EPortalSide { enum EPortalSide {
@ -16,9 +17,21 @@ enum EPortalSide {
TRAP UMETA(DisplayName = "Trap") TRAP UMETA(DisplayName = "Trap")
}; };
UENUM(BlueprintType)
enum EPortalCommand {
A UMETA(DisplayName = "Activate"),
C UMETA(DisplayName = "Color"),
J UMETA(DisplayName = "Advanced color"),
L UMETA(DisplayName = "Trap color"),
M UMETA(DisplayName = "Music"),
Q UMETA(DisplayName = "Query"),
R UMETA(DisplayName = "Ready"),
S UMETA(DisplayName = "Status")
};
/* Macro Definitions */
/* Macro constants Definitions */
#define rw_buf_size 0x21 #define rw_buf_size 0x21
#define TIMEOUT 30000 #define TIMEOUT 30000
#define DEBUG true #define DEBUG true
@ -26,7 +39,18 @@ enum EPortalSide {
DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All);
DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All);
/* Subsystem */ //// Delegates
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderAddedDelegate, int32, SkylanderID, int32, Index);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderRemovedDelegate, int32, SkylanderID, int32, Index);
#pragma endregion
/* Handle all the portal I/O
*
*
*
*/
UCLASS(MinimalAPI) UCLASS(MinimalAPI)
class USkyPortalSubsystem : public UEngineSubsystem class USkyPortalSubsystem : public UEngineSubsystem
{ {
@ -40,13 +64,48 @@ public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override; virtual void Deinitialize() override;
/********* Portal Actions *************/
// Connect to Portal, return false if portal is not found /* The first function to run, before anything else.
* It will re-init and prepare the portal for receiving/sending inputs
*
* return false if portal is not found
*/
UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal")) UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal"))
SKYPORTAL_API bool ConnectPortal(); SKYPORTAL_API bool ConnectPortal();
/*Send a **Status** command, to see if the portal is ready to receive new commands*/
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|NOT FUNCTIONING"))
SKYPORTAL_API bool bIsPortalReady();
UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|NOT FUNCTIONING"))
SKYPORTAL_API void SendPortalCommand(EPortalCommand Command);
UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|NOT FUNCTIONING"))
SKYPORTAL_API void SendPortalSound(USoundWave* Sound);
/* Change portal color, ideally should be called just at the start.For gameplay usage, use ChangePortalColorside()*/
UFUNCTION(BlueprintCallable, CallInEditor, meta = (AutoCreateRefTerm = "Color", Category = "SkyPortal|Cosmetic"))
SKYPORTAL_API void ChangePortalColor(const FLinearColor& Color = FLinearColor::Green);
/**
* Change the color of the portal, can separate side and even trap ligth
* @param NextColor New color
* @param PortalSide The actors to record
* @param BlendTime Blend between current color and NextColor, in milliseconds
*/
UFUNCTION(BlueprintCallable, CallInEditor, meta = (AutoCreateRefTerm = "NextColor", Category = "SkyPortal|Cosmetic"))
SKYPORTAL_API void ChangePortalColorside(const FLinearColor& NextColor = FLinearColor::Green, const EPortalSide PortalSide = EPortalSide::BOTH, const float BlendTime = 500.0f);
// Blueprint-assignable event property
UPROPERTY(BlueprintAssignable, Category = "SkyPortal|Skylander")
FOnSkylanderAddedDelegate OnSkylanderAdded;
// Blueprint-assignable event property
UPROPERTY(BlueprintAssignable, Category = "SkyPortal|Skylander")
FOnSkylanderRemovedDelegate OnSkylanderRemoved;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly) UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
bool bPortalConnected = false; bool bPortalConnected = false;
@ -54,22 +113,6 @@ public:
FString HidError; FString HidError;
/* Portal Actions*/
// Change portal color, ideally should be called just at the start. For gameplay usage, use ChangePortalColorside()
UFUNCTION(BlueprintCallable, CallInEditor, meta = (AutoCreateRefTerm = "Color", Category = "SkyPortal|Cosmetic"))
SKYPORTAL_API void ChangePortalColor(const FLinearColor& Color = FLinearColor::Green);
/**
* Change the color of the portal, can separate side and even trap ligth
* @param PortalSide The actors to record
* @param BlendTime Blend between current color and NextColor
*/
UFUNCTION(BlueprintCallable, CallInEditor, meta = (AutoCreateRefTerm = "NextColor", Category = "SkyPortal|Cosmetic"))
SKYPORTAL_API void ChangePortalColorside(const FLinearColor& NextColor = FLinearColor::Green,const EPortalSide PortalSide = EPortalSide::BOTH,const float BlendTime=100.0f);
unsigned char PortalStatus(); unsigned char PortalStatus();
@ -95,8 +138,8 @@ private:
bool OpenPortalHandle(); bool OpenPortalHandle();
bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander); bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander);
bool WriteBlock(unsigned int, unsigned char[0x10], int); bool WriteBlock(unsigned int, unsigned char[0x10], int);
bool CheckResponse(RWBlock *, char); bool CheckResponse(RWBlock*, char);
void Write(RWBlock *); void Write(RWBlock*);
protected: protected:
@ -104,7 +147,7 @@ protected:
//Constants //Constants
const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 }; const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 };
const int ProductIds[4] = { 0x150, 0x967, 0x1f17 }; const int ProductIds[4] = { 0x150, 0x967, 0x1f17 };
/////Defaults values, should not be used /////Defaults values, should not be used