wip:reading figure

This commit is contained in:
Lucas 2024-09-23 23:55:43 +02:00
parent 59ea084ff4
commit aed30481ea
3 changed files with 134 additions and 5 deletions

View file

@ -367,7 +367,35 @@ void USkyPortalSubsystem::CheckComplexResponse() {
break;
case S:
CurrentStatusData = ParsePortalStatus(res);
//Send delegate when new informations are received
if (OldStatusData != CurrentStatusData) {
for (int i = 0; i < CurrentStatusData.StatusArray.Num(); i++) {
if (CurrentStatusData.StatusArray[i] != OldStatusData.StatusArray[i]) {
if (!FalsePositive()) {
switch (CurrentStatusData.StatusArray[i])
{
case EFigureStatus::NOT_PRESENT:
break;
case EFigureStatus::PRESENT:
break;
case EFigureStatus::ADDED:
//get SkylandID
//ReadBlock;
OnSkylanderAdded.Broadcast(01, i);
case EFigureStatus::REMOVED:
OnSkylanderRemoved.Broadcast(01, i)
}
}
}
}
OldStatusData = CurrentStatusData;
}
break;
default:
break;
@ -375,6 +403,12 @@ void USkyPortalSubsystem::CheckComplexResponse() {
}
bool USkyPortalSubsystem::FalsePositive()
{
int dif = FMath::Abs(CurrentStatusData.Counter - OldStatusData.Counter);
return (dif <= 2 || dif > 254);
}
/* Verify the command response, when only a character is sended by the portal.
@ -491,7 +525,7 @@ EPortalCommand USkyPortalSubsystem::GetPortalCommandFromChar(unsigned char Char)
}
bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10], int skylander) {
bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10], int skylanderIndex) {
RWBlock req, res; //request and response buffers
unsigned char followup;
@ -513,7 +547,7 @@ bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10]
memset(req.buf, 0, rw_buf_size); // Clear the request buffer (initialize all bytes to zero)
req.buf[1] = 'Q';
followup = 0x10 + skylander;
followup = 0x10 + skylanderIndex;
req.buf[2] = followup;
if (block == 0) {
req.buf[2] = followup + 0x10; // may not be needed
@ -629,3 +663,65 @@ void FPortalStatusChecker::CheckPortalStatus()
}
}
FigureDataBlock USkyPortalSubsystem::ReadFigureBlocks(uint8 FigureIndex)
{
FigureDataBlock FigureData;
FigureData.error = false; // Initialize error flag
RWBlock req, res;
// Loop over all 64 blocks
for (uint8 BlockIndex = 0; BlockIndex < FIGURE_TOTAL_BLOCKS; ++BlockIndex)
{
// Prepare the request buffer
memset(req.buf, 0, rw_buf_size);
req.buf[1] = 'Q'; // Command character
req.buf[2] = FigureIndex; // Figure index (0x00 to 0x0F)
req.buf[3] = BlockIndex; // Block index (0x00 to 0x3F)
// Send the request
Write(&req);
// Read the response
int BuffResponse = hid_read_timeout(PortalDevice, res.buf, rw_buf_size, TIMEOUT);
// Check if the response was received successfully
if (BuffResponse < rw_buf_size)
{
FigureData.error = true; // Mark error flag
UE_LOG(LogSkyportalIO, Warning, TEXT("Error receiving data for block %d of figure %d"), BlockIndex, FigureIndex);
break;
}
// Parse the response status
uint8 StatusByte = res.buf[2];
uint8 ReturnedBlockIndex = res.buf[3];
// Check for errors in the status byte
if (StatusByte == 0x01) // Error in response
{
FigureData.error = true;
UE_LOG(LogSkyportalIO, Warning, TEXT("Error reading block %d for figure %d"), BlockIndex, FigureIndex);
break;
}
else if (StatusByte != (0x10 + 'Q')) // Unexpected status byte
{
FigureData.error = true;
UE_LOG(LogSkyportalIO, Warning, TEXT("Unexpected status byte 0x%02X for block %d"), StatusByte, BlockIndex);
break;
}
// Verify that the block index matches the requested block
if (ReturnedBlockIndex != BlockIndex)
{
FigureData.error = true;
UE_LOG(LogSkyportalIO, Warning, TEXT("Mismatched block index. Expected %d, got %d"), BlockIndex, ReturnedBlockIndex);
break;
}
// Copy block data into FigureData
memcpy(FigureData.blockdata[BlockIndex], &res.buf[4], FIGURE_BLOCK_SIZE);
}
return FigureData; // Return the complete figure data
}

View file

@ -0,0 +1,3 @@
#pragma once
#include "SkyPortalFigure.generated.h"

View file

@ -4,6 +4,7 @@
#include "Subsystems/EngineSubsystem.h"
#include "hidapi.h"
#include "HAL/Runnable.h"
#include "SkyPortalFigure.h"
#include "SkyPortalSubsystem.generated.h"
@ -49,7 +50,7 @@ struct FPortalStatusData
TArray<EFigureStatus> StatusArray;
// timestamp.
//only one byte long. This means that after the value 0xFF, it overflows back to 0x00.
// only one byte long. This means that after the value 0xFF, it overflows back to 0x00.
// Since these are so far apart, it can be assumed that 0x00 is newer than anything in the range 0xF0 - 0xFF.
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
uint8 Counter;
@ -57,17 +58,40 @@ struct FPortalStatusData
// Should always be true
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
bool bIsReady;
// Overload the == operator
bool operator==(const FPortalStatusData& Other) const
{
if (bIsReady == Other.bIsReady && Counter == Other.Counter) {
if (StatusArray == Other.StatusArray) {
return true;
}
}
return false;
}
// Overload the != operator
bool operator!=(const FPortalStatusData& Other) const
{
return !(*this == Other);
}
};
/* Macro constants Definitions */
#define rw_buf_size 0x21
#define TIMEOUT 30000
#define DEBUG true
#define FIGURE_TOTAL_BLOCKS 64
#define FIGURE_BLOCK_SIZE 16
typedef struct {
unsigned char buf[rw_buf_size]; int BytesTransferred;
} RWBlock;
typedef struct {
unsigned char blockdata[FIGURE_TOTAL_BLOCKS][FIGURE_BLOCK_SIZE]; bool error;
} FigureDataBlock;
DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All);
DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All);
@ -148,6 +172,8 @@ public:
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);
@ -173,6 +199,9 @@ public:
UPROPERTY(BlueprintReadOnly)
FPortalStatusData CurrentStatusData;
UPROPERTY(BlueprintReadOnly)
FPortalStatusData OldStatusData;
EPortalCommand GetPortalCommandFromChar(unsigned char Char);
@ -185,7 +214,7 @@ public:
bool WriteBlock(unsigned int, unsigned char[0x10], int);
bool CheckResponse(RWBlock*, char);
void CheckComplexResponse();
@ -207,7 +236,8 @@ private:
// Block/byte related data write/read functions
bool OpenPortalHandle();
void Write(RWBlock*);
FigureDataBlock ReadFigureBlocks(uint8 FigureIndex);
bool FalsePositive();
// Pointer to the status checker thread
FPortalStatusChecker* StatusChecker;