From f9d072ea5ab027a17a30eaef5c9b1b200327fde3 Mon Sep 17 00:00:00 2001 From: Lucas Peter Date: Wed, 25 Sep 2024 17:33:25 +0200 Subject: [PATCH] IT'S COMPILING NOW --- Source/SkyPortal/Private/SkyPortalFigure.cpp | 6 +- Source/SkyPortal/Private/SkyPortalIO.cpp | 20 ++-- Source/SkyPortal/Private/SkyPortalRunner.cpp | 19 ++-- .../SkyPortal/Private/SkyPortalSubsystem.cpp | 99 +++++-------------- Source/SkyPortal/Public/SkyPortalFigure.h | 3 + Source/SkyPortal/Public/SkyPortalIO.h | 13 ++- Source/SkyPortal/Public/SkyPortalRunner.h | 15 ++- Source/SkyPortal/Public/SkyPortalSubsystem.h | 32 +++--- 8 files changed, 85 insertions(+), 122 deletions(-) diff --git a/Source/SkyPortal/Private/SkyPortalFigure.cpp b/Source/SkyPortal/Private/SkyPortalFigure.cpp index 3da3c04..04945ff 100644 --- a/Source/SkyPortal/Private/SkyPortalFigure.cpp +++ b/Source/SkyPortal/Private/SkyPortalFigure.cpp @@ -1,7 +1,6 @@ #pragma once #include "SkyPortalFigure.h" -#include "SkyPortalSubsystem.h" uint32 GetFigureID(const FigureDataBlock& DataBlock) { @@ -19,13 +18,13 @@ uint32 GetFigureID(const FigureDataBlock& DataBlock) return OutFigureID; }; - +/* void FigureData::ReadData(uint8 index) { ClearData(); for (uint8 i = 0; i < 64; i++) { - USkyPortalSubsystem* SkySubsystem = GEngine->GetEngineSubsystem(); + GEngine->GetEngineSubsystem(); TArray output = SkySubsystem->QueryBlock(index, i); uint8[] blockData = new uint8[0x10]; @@ -75,6 +74,7 @@ void FigureData::ReadData(uint8 index) } } } +*/ void FigureData::ClearData() { diff --git a/Source/SkyPortal/Private/SkyPortalIO.cpp b/Source/SkyPortal/Private/SkyPortalIO.cpp index dbce435..c198fe9 100644 --- a/Source/SkyPortal/Private/SkyPortalIO.cpp +++ b/Source/SkyPortal/Private/SkyPortalIO.cpp @@ -7,7 +7,7 @@ DEFINE_LOG_CATEGORY(LogSkyportalIO); //Constructor USkyPortalIO::USkyPortalIO() { - OpenPortalHandle(); + bPortalReady = OpenPortalHandle(); } @@ -16,6 +16,7 @@ bool USkyPortalIO::OpenPortalHandle() { //reset if (PortalDevice) { hid_close(PortalDevice); + bPortalReady = false; } /* Declare two pointers to hold information about HID devices. @@ -57,7 +58,6 @@ bool USkyPortalIO::OpenPortalHandle() { // Free the device list hid_free_enumeration(list); - //bPortalConnected = true; return true; } @@ -143,10 +143,10 @@ void USkyPortalIO::Write(FWriteBlock* pb) { } #endif -void USkyPortalIO::WriteRaw(const TArray block) +void USkyPortalIO::WriteRaw(const TArray* block) { - block.GetData; - int res = hid_write(PortalDevice, block, block.GetAllocatedSize()); //return the number of byte written + ; + int res = hid_write(PortalDevice, block->GetData(), block->GetAllocatedSize()); //return the number of byte written if (res == -1) { UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write raw data to Portal. error:\n %s"), hid_error(PortalDevice)); @@ -156,15 +156,21 @@ void USkyPortalIO::WriteRaw(const TArray block) uint8* USkyPortalIO::Read() { - uint8* output = 0; - hid_read_timeout(PortalDevice, output, 0x20, TIMEOUT); + uint8* output = new byte[0x20]; + hid_read(PortalDevice, output, 0x20); return output; } +TArray USkyPortalIO::QueryBlock(uint8 characterIndex, uint8 block) +{ + return TArray(); +} + void USkyPortalIO::Close() { if (PortalDevice) { hid_close(PortalDevice); } + bPortalReady = false; } diff --git a/Source/SkyPortal/Private/SkyPortalRunner.cpp b/Source/SkyPortal/Private/SkyPortalRunner.cpp index b59265c..355ae06 100644 --- a/Source/SkyPortal/Private/SkyPortalRunner.cpp +++ b/Source/SkyPortal/Private/SkyPortalRunner.cpp @@ -1,7 +1,8 @@ #include "SkyPortalRunner.h" +#include "SkyPortalSubsystem.h" -FPortalStatusChecker::FPortalStatusChecker(USkyPortalSubsystem* InSubsystem, float InCheckInterval) - : SkyPortalSubsystem(InSubsystem), CheckInterval(InCheckInterval), bShouldRun(true) +FPortalStatusChecker::FPortalStatusChecker(UEngineSubsystem* InSubsystem, float InCheckInterval) + : SkyPortalSubsystemRef(InSubsystem), CheckInterval(InCheckInterval), bShouldRun(true) { } @@ -40,15 +41,19 @@ void FPortalStatusChecker::Exit() void FPortalStatusChecker::CheckPortalStatus() { // Ensure the subsystem is valid - if (SkyPortalSubsystem && SkyPortalSubsystem->bPortalConnected) + if (SkyPortalSubsystemRef && Cast(SkyPortalSubsystemRef)) { + USkyPortalIO* PortalHandleRef = Cast(SkyPortalSubsystemRef)->PortalHandle; UE_LOG(LogSkyportalIO, Verbose, TEXT("Check portal")); + if (PortalHandleRef && PortalHandleRef->bPortalReady) + { + // Call the subsystem function to get portal status - // Call the subsystem function to get portal status + Cast(SkyPortalSubsystemRef); - SkyPortalSubsystem->CheckComplexResponse(); + // Do something with the status (log, notify, etc.) + UE_LOG(LogSkyportalIO, Verbose, TEXT("Portal Status:")); + } - // Do something with the status (log, notify, etc.) - UE_LOG(LogSkyportalIO, Verbose, TEXT("Portal Status:")); } } \ No newline at end of file diff --git a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp index 95b3946..6c5f525 100644 --- a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp +++ b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp @@ -2,6 +2,7 @@ #include "SkyPortalSubsystem.h" #include "Engine/Engine.h" +#include "SkyPortal.h" #include "HAL/RunnableThread.h" #include "Misc/ScopeLock.h" @@ -117,6 +118,9 @@ void USkyPortalSubsystem::ChangePortalColorSide(const FLinearColor& Color, const if (PortalSide == EPortalSide::BOTH) { _portalside = EPortalSide::LEFT; } + else { + _portalside = PortalSide; + } switch (_portalside) { case EPortalSide::LEFT: @@ -167,10 +171,10 @@ FPortalStatusData USkyPortalSubsystem::ParsePortalStatus(const FWriteBlock& Resp // Parse the figure status array (little-endian 32-bit integer) uint32 FigureStatusArray = 0; // Reading the 32-bit integer (character status array) from the buffer - FigureStatusArray |= ResponseBlock.buf[1]; // 1st byte - FigureStatusArray |= (ResponseBlock.buf[2] << 8); // 2nd byte - FigureStatusArray |= (ResponseBlock.buf[3] << 16); // 3rd byte - FigureStatusArray |= (ResponseBlock.buf[4] << 24); // 4th byte + FigureStatusArray |= ResponseBlock.data[1]; // 1st byte + FigureStatusArray |= (ResponseBlock.data[2] << 8); // 2nd byte + FigureStatusArray |= (ResponseBlock.data[3] << 16); // 3rd byte + FigureStatusArray |= (ResponseBlock.data[4] << 24); // 4th byte TStaticArray tempArray; // For each of the 16 entries, extract the 2-bit status and map it to EFigureStatus @@ -205,10 +209,10 @@ FPortalStatusData USkyPortalSubsystem::ParsePortalStatus(const FWriteBlock& Resp PortalStatusData.StatusArray.SetNum(0); PortalStatusData.StatusArray.Append(tempArray); // The next byte is the response counter - PortalStatusData.Counter = ResponseBlock.buf[5]; + PortalStatusData.Counter = ResponseBlock.data[5]; // The last byte is the boolean indicating whether the portal is ready - PortalStatusData.bIsReady = ResponseBlock.buf[6] != 0; // 0 means not ready, non-zero means ready + PortalStatusData.bIsReady = ResponseBlock.data[6] != 0; // 0 means not ready, non-zero means ready return PortalStatusData; } @@ -217,6 +221,7 @@ void USkyPortalSubsystem::Sleep(int sleepMs) { FPlatformProcess::Sleep(sleepMs * 0.0001); } +/* void USkyPortalSubsystem::CheckComplexResponse() { if (!PortalDevice) { @@ -293,24 +298,9 @@ void USkyPortalSubsystem::CheckComplexResponse() { } } +*/ -TArray USkyPortalSubsystem::QueryBlock(uint8 characterIndex, uint8 block) -{ - TArray QueryCommand; - QueryCommand.SetNum(0x21); - QueryCommand[1] = 'Q'; - QueryCommand[2] = characterIndex; - QueryCommand[3] = block; - TArray Output; - - do { - portalConnection->Write(QueryCommand); - output = portalConnection->Read(); - } while (output[0] != 'Q' || (output[1] % 0x10 != characterIndex && output[1] != 0x01) || output[2] != block); - - return output; -} @@ -391,62 +381,12 @@ EPortalCommand USkyPortalSubsystem::GetPortalCommandFromChar(unsigned char Char) } -bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10], int skylanderIndex) { - RWBlock req, res; //request and response buffers - unsigned char followup; - UE_LOG(LogSkyportalIO, Verbose, TEXT("PortalIO:ReadBlock :%X"), block); - - - // Checking if the block is not out of range - if (!ensure(block < 0x40)) { - UE_LOG(LogSkyportalIO, Error, TEXT("PortalIO:ReadBlock failed, block out of range")); - return false; // Early return instead of throwing an exception - } - - // Send query request - - // Trying to read data 15x - for (int attempt = 0; attempt < 15; attempt++) - { - int i = 0; - - memset(command.data, 0, rw_buf_size); // Clear the request buffer (initialize all bytes to zero) - command.data[1] = 'Q'; - followup = 0x10 + skylanderIndex; - command.data[2] = followup; - if (block == 0) { - command.data[2] = followup + 0x10; // may not be needed - } - command.data[3] = (unsigned char)block; - - memset(&(res.buf), 0, rw_buf_size); // Clear the response buffer to prepare for incoming data - - - do { Write(&req); } while (CheckResponse(&res, 'Q')); - - if (res.buf[0] == 'Q' && res.buf[2] == (unsigned char)block) { - // Got our query back - if (res.buf[1] == followup) { - // got the query back with no error - memcpy(data, res.buf + 3, 0x10); - UE_LOG(LogSkyportalIO, Verbose, TEXT("PortalIO:ReadBlock success")); - return true; - } - } - - - } // retries - - UE_LOG(LogSkyportalIO, Fatal, TEXT("PortalIO:ReadBlock failed after retries")); - ensureMsgf(false, TEXT("PortalIO: Failed to read block after multiple retries")); - return false; -} bool USkyPortalSubsystem::PortalConnect() { PortalHandle = NewObject(); - if (IsValidLowLevelFast(PortalHandle)) { + if (IsValid(PortalHandle)) { UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: ")); PortalReady(); PortalActivate(1); @@ -458,8 +398,12 @@ bool USkyPortalSubsystem::PortalConnect() return false; } -bool USkyPortalSubsystem::bIsPortalReady() +bool USkyPortalSubsystem::IsPortalReady() { + if (PortalHandle) { + return PortalHandle->bPortalReady; + } + //maybe should send a status request ? return false; } @@ -476,13 +420,13 @@ void USkyPortalSubsystem::SendPortalSound(USoundWave* Sound) - +/* FigureDataBlock USkyPortalSubsystem::ReadFigureBlocks(uint8 FigureIndex) { FigureDataBlock FigureData; FigureData.error = false; // Initialize error flag - RWBlock req, res; + FWriteBlock req, res; // Loop over all 64 blocks for (uint8 BlockIndex = 0; BlockIndex < FIGURE_TOTAL_BLOCKS; ++BlockIndex) @@ -538,4 +482,5 @@ FigureDataBlock USkyPortalSubsystem::ReadFigureBlocks(uint8 FigureIndex) } return FigureData; // Return the complete figure data -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/Source/SkyPortal/Public/SkyPortalFigure.h b/Source/SkyPortal/Public/SkyPortalFigure.h index c8813d1..5d6909e 100644 --- a/Source/SkyPortal/Public/SkyPortalFigure.h +++ b/Source/SkyPortal/Public/SkyPortalFigure.h @@ -61,6 +61,9 @@ public: UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure")) uint32 GetFigureIdByIndex(uint32 index); + UFUNCTION() + TArray QueryBlock(uint8 characterIndex, uint8 block = 0x00); + void ReadData(uint8 index); void ClearData(); uint8 GetByte(int block, int offset); diff --git a/Source/SkyPortal/Public/SkyPortalIO.h b/Source/SkyPortal/Public/SkyPortalIO.h index 371486f..5455148 100644 --- a/Source/SkyPortal/Public/SkyPortalIO.h +++ b/Source/SkyPortal/Public/SkyPortalIO.h @@ -10,7 +10,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All); -constexpr auto write_buf_size = 0x21; +constexpr auto write_buf_size = 0x21; //buffer size for all the write command on portal. Should always be 0x21 - 33 constexpr auto TIMEOUT = 30000; //milliseconds /* Portal physicial device IDs */ @@ -39,13 +39,16 @@ class USkyPortalIO : public UObject GENERATED_BODY() public: + // Constructor + USkyPortalIO(); + /* hidapi will write error message in here*/ UPROPERTY(BlueprintReadOnly) FString HidError; /*Portal ready to be listened or to receive commands*/ UPROPERTY(BlueprintReadOnly) - bool bPortalReady; + bool bPortalReady = false; /* Connect to Portal - will write the PortalDevice var if success */ bool OpenPortalHandle(); @@ -61,6 +64,10 @@ public: */ uint8* Read(); + UFUNCTION() + TArray QueryBlock(uint8 characterIndex, uint8 block = 0x00); + + /* Close connection to Portal*/ void Close(); private: @@ -69,7 +76,7 @@ private: */ - /* Portal ref used in the subsystem */ + /* Portal device ref, useful for hidapi commands */ hid_device* PortalDevice; }; diff --git a/Source/SkyPortal/Public/SkyPortalRunner.h b/Source/SkyPortal/Public/SkyPortalRunner.h index 33c9f69..2c6e9da 100644 --- a/Source/SkyPortal/Public/SkyPortalRunner.h +++ b/Source/SkyPortal/Public/SkyPortalRunner.h @@ -1,13 +1,15 @@ #pragma once -#include "CoreMinimal.h" +#include "Core.h" #include "HAL/Runnable.h" #include "SkyPortalFigure.h" +#include "SkyPortalRunner.generated.h" + USTRUCT(BlueprintType) struct FPortalStatusData { - GENERATED_USTRUCT_BODY() + GENERATED_BODY() // Array of statuses UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder)) @@ -52,8 +54,11 @@ struct FPortalStatusData class FPortalStatusChecker : public FRunnable { public: - // Constructor: pass the subsystem and desired check interval (in seconds) - FPortalStatusChecker(USkyPortalSubsystem* InSubsystem, float InCheckInterval); + /* Constructor : pass the subsystem and desired check interval(in seconds) + * + * @param InSubsystem Should always be the SkyPortalSubsystem + */ + FPortalStatusChecker(UEngineSubsystem* InSubsystem, float InCheckInterval); // FRunnable interface virtual bool Init() override; @@ -65,7 +70,7 @@ public: private: // Pointer to the subsystem that contains PortalStatus() - USkyPortalSubsystem* SkyPortalSubsystem; + UEngineSubsystem* SkyPortalSubsystemRef; // Time interval (in seconds) for status checking float CheckInterval; diff --git a/Source/SkyPortal/Public/SkyPortalSubsystem.h b/Source/SkyPortal/Public/SkyPortalSubsystem.h index b1d04e1..022bd8c 100644 --- a/Source/SkyPortal/Public/SkyPortalSubsystem.h +++ b/Source/SkyPortal/Public/SkyPortalSubsystem.h @@ -104,7 +104,7 @@ public: /*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(); + SKYPORTAL_API bool IsPortalReady(); UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|NOT FUNCTIONING")) SKYPORTAL_API void SendPortalCommand(EPortalCommand Command); @@ -152,22 +152,23 @@ public: UPROPERTY(BlueprintReadOnly) int PortalId; - EPortalCommand GetPortalCommandFromChar(unsigned char Char); - - - UPROPERTY(VisibleAnywhere, BlueprintReadOnly) - bool bPortalConnected = false; - - - - UFUNCTION() - TArray QueryBlock(uint8 characterIndex, uint8 block = 0x00); + UPROPERTY(BlueprintReadOnly) USkyPortalIO* PortalHandle; + /**/ + UPROPERTY() + bool bPortalConnected_DEPRECATED = PortalHandle ? PortalHandle->bPortalReady : false; + + + + + + private: FPortalStatusData ParsePortalStatus(const FWriteBlock& ResponseBlock); + EPortalCommand GetPortalCommandFromChar(unsigned char Char); // deprecated /* Sleep the system @@ -177,15 +178,6 @@ private: static void Sleep(int sleepMs); - - - - - - - // Block/byte related data write/read functions - - FigureDataBlock ReadFigureBlocks(uint8 FigureIndex); bool FalsePositive() const;