IT'S COMPILING NOW
This commit is contained in:
parent
b9b3c8ef81
commit
f9d072ea5a
8 changed files with 85 additions and 122 deletions
|
@ -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<USkyPortalSubsystem>();
|
||||
GEngine->GetEngineSubsystem<USkyPortalSubsystem>();
|
||||
TArray<uint8> output = SkySubsystem->QueryBlock(index, i);
|
||||
|
||||
uint8[] blockData = new uint8[0x10];
|
||||
|
@ -75,6 +74,7 @@ void FigureData::ReadData(uint8 index)
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void FigureData::ClearData()
|
||||
{
|
||||
|
|
|
@ -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<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)
|
||||
{
|
||||
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* output = 0;
|
||||
hid_read_timeout(PortalDevice, output, 0x20, TIMEOUT);
|
||||
uint8* output = new byte[0x20];
|
||||
hid_read(PortalDevice, output, 0x20);
|
||||
return output;
|
||||
}
|
||||
|
||||
TArray<uint8> USkyPortalIO::QueryBlock(uint8 characterIndex, uint8 block)
|
||||
{
|
||||
return TArray<uint8>();
|
||||
}
|
||||
|
||||
void USkyPortalIO::Close() {
|
||||
if (PortalDevice) {
|
||||
hid_close(PortalDevice);
|
||||
}
|
||||
bPortalReady = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<USkyPortalSubsystem>(SkyPortalSubsystemRef))
|
||||
{
|
||||
USkyPortalIO* PortalHandleRef = Cast<USkyPortalSubsystem>(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<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:"));
|
||||
}
|
||||
}
|
|
@ -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<EFigureStatus, 16> 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<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()
|
||||
{
|
||||
PortalHandle = NewObject<USkyPortalIO>();
|
||||
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
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -61,6 +61,9 @@ public:
|
|||
UFUNCTION(BlueprintCallable, BlueprintPure, meta = (Category = "SkyPortal|Figure"))
|
||||
uint32 GetFigureIdByIndex(uint32 index);
|
||||
|
||||
UFUNCTION()
|
||||
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
|
||||
|
||||
void ReadData(uint8 index);
|
||||
void ClearData();
|
||||
uint8 GetByte(int block, int offset);
|
||||
|
|
|
@ -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<uint8> 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;
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<uint8> 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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue