#pragma once #include "CoreMinimal.h" #include "Subsystems/EngineSubsystem.h" #include "hidapi.h" #include "SkyPortalSubsystem.generated.h" UENUM(BlueprintType) enum EPortalSide { LEFT UMETA(DisplayName = "Left side"), RIGHT UMETA(DisplayName = "Right side"), BOTH UMETA(DisplayName = "Both left and right"), TRAP UMETA(DisplayName = "Trap") }; /* Macro Definitions */ #define rw_buf_size 0x21 #define TIMEOUT 30000 #define DEBUG true DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All); /* Subsystem */ UCLASS(MinimalAPI) class USkyPortalSubsystem : public UEngineSubsystem { GENERATED_BODY() //Portal ref used in the subsystem hid_device* PortalDevice; public: // Override initialization and deinitialization methods virtual void Initialize(FSubsystemCollectionBase& Collection) override; virtual void Deinitialize() override; // Connect to Portal, return false if portal is not found UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal")) SKYPORTAL_API bool ConnectPortal(); UPROPERTY(VisibleAnywhere, BlueprintReadOnly) bool bPortalConnected = false; 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(); private: typedef struct { unsigned char buf[rw_buf_size]; int BytesTransferred; } RWBlock; static void Sleep(int sleepMs); void ActivatePortal(int active); void RestartPortal(); // Block/byte related data write/read functions bool OpenPortalHandle(); bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander); bool WriteBlock(unsigned int, unsigned char[0x10], int); bool CheckResponse(RWBlock *, char); void Write(RWBlock *); protected: //Constants const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 }; const int ProductIds[4] = { 0x150, 0x967, 0x1f17 }; /////Defaults values, should not be used //const int VendorId = 5168; //const int ProductId = 336; };