IT'S COMPILING NOW

This commit is contained in:
Lucas Peter 2024-09-25 17:33:25 +02:00
parent b9b3c8ef81
commit f9d072ea5a
No known key found for this signature in database
8 changed files with 85 additions and 122 deletions

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "SkyPortalFigure.h" #include "SkyPortalFigure.h"
#include "SkyPortalSubsystem.h"
uint32 GetFigureID(const FigureDataBlock& DataBlock) uint32 GetFigureID(const FigureDataBlock& DataBlock)
{ {
@ -19,13 +18,13 @@ uint32 GetFigureID(const FigureDataBlock& DataBlock)
return OutFigureID; return OutFigureID;
}; };
/*
void FigureData::ReadData(uint8 index) void FigureData::ReadData(uint8 index)
{ {
ClearData(); ClearData();
for (uint8 i = 0; i < 64; i++) for (uint8 i = 0; i < 64; i++)
{ {
USkyPortalSubsystem* SkySubsystem = GEngine->GetEngineSubsystem<USkyPortalSubsystem>(); GEngine->GetEngineSubsystem<USkyPortalSubsystem>();
TArray<uint8> output = SkySubsystem->QueryBlock(index, i); TArray<uint8> output = SkySubsystem->QueryBlock(index, i);
uint8[] blockData = new uint8[0x10]; uint8[] blockData = new uint8[0x10];
@ -75,6 +74,7 @@ void FigureData::ReadData(uint8 index)
} }
} }
} }
*/
void FigureData::ClearData() void FigureData::ClearData()
{ {

View file

@ -7,7 +7,7 @@ DEFINE_LOG_CATEGORY(LogSkyportalIO);
//Constructor //Constructor
USkyPortalIO::USkyPortalIO() USkyPortalIO::USkyPortalIO()
{ {
OpenPortalHandle(); bPortalReady = OpenPortalHandle();
} }
@ -16,6 +16,7 @@ bool USkyPortalIO::OpenPortalHandle() {
//reset //reset
if (PortalDevice) { if (PortalDevice) {
hid_close(PortalDevice); hid_close(PortalDevice);
bPortalReady = false;
} }
/* /*
Declare two pointers to hold information about HID devices. Declare two pointers to hold information about HID devices.
@ -57,7 +58,6 @@ bool USkyPortalIO::OpenPortalHandle() {
// Free the device list // Free the device list
hid_free_enumeration(list); hid_free_enumeration(list);
//bPortalConnected = true;
return true; return true;
} }
@ -143,10 +143,10 @@ void USkyPortalIO::Write(FWriteBlock* pb) {
} }
#endif #endif
void USkyPortalIO::WriteRaw(const TArray<uint8> block) void USkyPortalIO::WriteRaw(const TArray<uint8>* 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) if (res == -1)
{ {
UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write raw data to Portal. error:\n %s"), hid_error(PortalDevice)); 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<uint8> block)
uint8* USkyPortalIO::Read() uint8* USkyPortalIO::Read()
{ {
uint8* output = 0; uint8* output = new byte[0x20];
hid_read_timeout(PortalDevice, output, 0x20, TIMEOUT); hid_read(PortalDevice, output, 0x20);
return output; return output;
} }
TArray<uint8> USkyPortalIO::QueryBlock(uint8 characterIndex, uint8 block)
{
return TArray<uint8>();
}
void USkyPortalIO::Close() { void USkyPortalIO::Close() {
if (PortalDevice) { if (PortalDevice) {
hid_close(PortalDevice); hid_close(PortalDevice);
} }
bPortalReady = false;
} }

View file

@ -1,7 +1,8 @@
#include "SkyPortalRunner.h" #include "SkyPortalRunner.h"
#include "SkyPortalSubsystem.h"
FPortalStatusChecker::FPortalStatusChecker(USkyPortalSubsystem* InSubsystem, float InCheckInterval) FPortalStatusChecker::FPortalStatusChecker(UEngineSubsystem* InSubsystem, float InCheckInterval)
: SkyPortalSubsystem(InSubsystem), CheckInterval(InCheckInterval), bShouldRun(true) : SkyPortalSubsystemRef(InSubsystem), CheckInterval(InCheckInterval), bShouldRun(true)
{ {
} }
@ -40,15 +41,19 @@ void FPortalStatusChecker::Exit()
void FPortalStatusChecker::CheckPortalStatus() void FPortalStatusChecker::CheckPortalStatus()
{ {
// Ensure the subsystem is valid // Ensure the subsystem is valid
if (SkyPortalSubsystem && SkyPortalSubsystem->bPortalConnected) if (SkyPortalSubsystemRef && Cast<USkyPortalSubsystem>(SkyPortalSubsystemRef))
{ {
USkyPortalIO* PortalHandleRef = Cast<USkyPortalSubsystem>(SkyPortalSubsystemRef)->PortalHandle;
UE_LOG(LogSkyportalIO, Verbose, TEXT("Check portal")); 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<USkyPortalSubsystem>(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:"));
} }
} }

View file

@ -2,6 +2,7 @@
#include "SkyPortalSubsystem.h" #include "SkyPortalSubsystem.h"
#include "Engine/Engine.h" #include "Engine/Engine.h"
#include "SkyPortal.h"
#include "HAL/RunnableThread.h" #include "HAL/RunnableThread.h"
#include "Misc/ScopeLock.h" #include "Misc/ScopeLock.h"
@ -117,6 +118,9 @@ void USkyPortalSubsystem::ChangePortalColorSide(const FLinearColor& Color, const
if (PortalSide == EPortalSide::BOTH) { if (PortalSide == EPortalSide::BOTH) {
_portalside = EPortalSide::LEFT; _portalside = EPortalSide::LEFT;
} }
else {
_portalside = PortalSide;
}
switch (_portalside) { switch (_portalside) {
case EPortalSide::LEFT: case EPortalSide::LEFT:
@ -167,10 +171,10 @@ FPortalStatusData USkyPortalSubsystem::ParsePortalStatus(const FWriteBlock& Resp
// Parse the figure status array (little-endian 32-bit integer) // Parse the figure status array (little-endian 32-bit integer)
uint32 FigureStatusArray = 0; uint32 FigureStatusArray = 0;
// Reading the 32-bit integer (character status array) from the buffer // Reading the 32-bit integer (character status array) from the buffer
FigureStatusArray |= ResponseBlock.buf[1]; // 1st byte FigureStatusArray |= ResponseBlock.data[1]; // 1st byte
FigureStatusArray |= (ResponseBlock.buf[2] << 8); // 2nd byte FigureStatusArray |= (ResponseBlock.data[2] << 8); // 2nd byte
FigureStatusArray |= (ResponseBlock.buf[3] << 16); // 3rd byte FigureStatusArray |= (ResponseBlock.data[3] << 16); // 3rd byte
FigureStatusArray |= (ResponseBlock.buf[4] << 24); // 4th byte FigureStatusArray |= (ResponseBlock.data[4] << 24); // 4th byte
TStaticArray<EFigureStatus, 16> tempArray; TStaticArray<EFigureStatus, 16> tempArray;
// For each of the 16 entries, extract the 2-bit status and map it to EFigureStatus // 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.SetNum(0);
PortalStatusData.StatusArray.Append(tempArray); PortalStatusData.StatusArray.Append(tempArray);
// The next byte is the response counter // 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 // 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; return PortalStatusData;
} }
@ -217,6 +221,7 @@ void USkyPortalSubsystem::Sleep(int sleepMs) {
FPlatformProcess::Sleep(sleepMs * 0.0001); FPlatformProcess::Sleep(sleepMs * 0.0001);
} }
/*
void USkyPortalSubsystem::CheckComplexResponse() { void USkyPortalSubsystem::CheckComplexResponse() {
if (!PortalDevice) { if (!PortalDevice) {
@ -293,24 +298,9 @@ void USkyPortalSubsystem::CheckComplexResponse() {
} }
} }
*/
TArray<uint8> USkyPortalSubsystem::QueryBlock(uint8 characterIndex, uint8 block)
{
TArray<uint8> QueryCommand;
QueryCommand.SetNum(0x21);
QueryCommand[1] = 'Q';
QueryCommand[2] = characterIndex;
QueryCommand[3] = block;
TArray<uint8> 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() bool USkyPortalSubsystem::PortalConnect()
{ {
PortalHandle = NewObject<USkyPortalIO>(); PortalHandle = NewObject<USkyPortalIO>();
if (IsValidLowLevelFast(PortalHandle)) { if (IsValid(PortalHandle)) {
UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: ")); UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: "));
PortalReady(); PortalReady();
PortalActivate(1); PortalActivate(1);
@ -458,8 +398,12 @@ bool USkyPortalSubsystem::PortalConnect()
return false; return false;
} }
bool USkyPortalSubsystem::bIsPortalReady() bool USkyPortalSubsystem::IsPortalReady()
{ {
if (PortalHandle) {
return PortalHandle->bPortalReady;
}
//maybe should send a status request ?
return false; return false;
} }
@ -476,13 +420,13 @@ void USkyPortalSubsystem::SendPortalSound(USoundWave* Sound)
/*
FigureDataBlock USkyPortalSubsystem::ReadFigureBlocks(uint8 FigureIndex) FigureDataBlock USkyPortalSubsystem::ReadFigureBlocks(uint8 FigureIndex)
{ {
FigureDataBlock FigureData; FigureDataBlock FigureData;
FigureData.error = false; // Initialize error flag FigureData.error = false; // Initialize error flag
RWBlock req, res; FWriteBlock req, res;
// Loop over all 64 blocks // Loop over all 64 blocks
for (uint8 BlockIndex = 0; BlockIndex < FIGURE_TOTAL_BLOCKS; ++BlockIndex) 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 return FigureData; // Return the complete figure data
} }
*/

View file

@ -61,6 +61,9 @@ public:
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure")) UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
uint32 GetFigureIdByIndex(uint32 index); uint32 GetFigureIdByIndex(uint32 index);
UFUNCTION()
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
void ReadData(uint8 index); void ReadData(uint8 index);
void ClearData(); void ClearData();
uint8 GetByte(int block, int offset); uint8 GetByte(int block, int offset);

View file

@ -10,7 +10,7 @@
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);
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 constexpr auto TIMEOUT = 30000; //milliseconds
/* Portal physicial device IDs */ /* Portal physicial device IDs */
@ -39,13 +39,16 @@ class USkyPortalIO : public UObject
GENERATED_BODY() GENERATED_BODY()
public: public:
// Constructor
USkyPortalIO();
/* hidapi will write error message in here*/ /* hidapi will write error message in here*/
UPROPERTY(BlueprintReadOnly) UPROPERTY(BlueprintReadOnly)
FString HidError; FString HidError;
/*Portal ready to be listened or to receive commands*/ /*Portal ready to be listened or to receive commands*/
UPROPERTY(BlueprintReadOnly) UPROPERTY(BlueprintReadOnly)
bool bPortalReady; bool bPortalReady = false;
/* Connect to Portal - will write the PortalDevice var if success */ /* Connect to Portal - will write the PortalDevice var if success */
bool OpenPortalHandle(); bool OpenPortalHandle();
@ -61,6 +64,10 @@ public:
*/ */
uint8* Read(); uint8* Read();
UFUNCTION()
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
/* Close connection to Portal*/
void Close(); void Close();
private: private:
@ -69,7 +76,7 @@ private:
*/ */
/* Portal ref used in the subsystem */ /* Portal device ref, useful for hidapi commands */
hid_device* PortalDevice; hid_device* PortalDevice;
}; };

View file

@ -1,13 +1,15 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "Core.h"
#include "HAL/Runnable.h" #include "HAL/Runnable.h"
#include "SkyPortalFigure.h" #include "SkyPortalFigure.h"
#include "SkyPortalRunner.generated.h"
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FPortalStatusData struct FPortalStatusData
{ {
GENERATED_USTRUCT_BODY() GENERATED_BODY()
// Array of statuses // Array of statuses
UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder)) UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder))
@ -52,8 +54,11 @@ struct FPortalStatusData
class FPortalStatusChecker : public FRunnable { class FPortalStatusChecker : public FRunnable {
public: public:
// Constructor: pass the subsystem and desired check interval (in seconds) /* Constructor : pass the subsystem and desired check interval(in seconds)
FPortalStatusChecker(USkyPortalSubsystem* InSubsystem, float InCheckInterval); *
* @param InSubsystem Should always be the SkyPortalSubsystem
*/
FPortalStatusChecker(UEngineSubsystem* InSubsystem, float InCheckInterval);
// FRunnable interface // FRunnable interface
virtual bool Init() override; virtual bool Init() override;
@ -65,7 +70,7 @@ public:
private: private:
// Pointer to the subsystem that contains PortalStatus() // Pointer to the subsystem that contains PortalStatus()
USkyPortalSubsystem* SkyPortalSubsystem; UEngineSubsystem* SkyPortalSubsystemRef;
// Time interval (in seconds) for status checking // Time interval (in seconds) for status checking
float CheckInterval; float CheckInterval;

View file

@ -104,7 +104,7 @@ public:
/*Send a **Status** command, to see if the portal is ready to receive new commands*/ /*Send a **Status** command, to see if the portal is ready to receive new commands*/
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|NOT FUNCTIONING")) UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|NOT FUNCTIONING"))
SKYPORTAL_API bool bIsPortalReady(); SKYPORTAL_API bool IsPortalReady();
UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|NOT FUNCTIONING")) UFUNCTION(BlueprintCallable, meta = (Category = "SkyPortal|NOT FUNCTIONING"))
SKYPORTAL_API void SendPortalCommand(EPortalCommand Command); SKYPORTAL_API void SendPortalCommand(EPortalCommand Command);
@ -152,22 +152,23 @@ public:
UPROPERTY(BlueprintReadOnly) UPROPERTY(BlueprintReadOnly)
int PortalId; int PortalId;
EPortalCommand GetPortalCommandFromChar(unsigned char Char);
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
bool bPortalConnected = false;
UFUNCTION()
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
UPROPERTY(BlueprintReadOnly)
USkyPortalIO* PortalHandle; USkyPortalIO* PortalHandle;
/**/
UPROPERTY()
bool bPortalConnected_DEPRECATED = PortalHandle ? PortalHandle->bPortalReady : false;
private: private:
FPortalStatusData ParsePortalStatus(const FWriteBlock& ResponseBlock); FPortalStatusData ParsePortalStatus(const FWriteBlock& ResponseBlock);
EPortalCommand GetPortalCommandFromChar(unsigned char Char); // deprecated
/* Sleep the system /* Sleep the system
@ -177,15 +178,6 @@ private:
static void Sleep(int sleepMs); static void Sleep(int sleepMs);
// Block/byte related data write/read functions
FigureDataBlock ReadFigureBlocks(uint8 FigureIndex); FigureDataBlock ReadFigureBlocks(uint8 FigureIndex);
bool FalsePositive() const; bool FalsePositive() const;