diff --git a/Source/SkyPortal/Private/SkyPortalIO.cpp b/Source/SkyPortal/Private/SkyPortalIO.cpp index 3ab0643..df1b749 100644 --- a/Source/SkyPortal/Private/SkyPortalIO.cpp +++ b/Source/SkyPortal/Private/SkyPortalIO.cpp @@ -1,10 +1,18 @@ #include "SkyPortalIO.h" -#include "Engine/Engine.h" DEFINE_LOG_CATEGORY(LogHIDApi); DEFINE_LOG_CATEGORY(LogSkyportalIO); -bool OpenPortalHandle() { + +//Constructor +USkyPortalIO::USkyPortalIO() +{ + OpenPortalHandle(); + + +} + +bool USkyPortalIO::OpenPortalHandle() { //reset if (PortalDevice) { hid_close(PortalDevice); @@ -67,3 +75,92 @@ bool OpenPortalHandle() { UE_LOG(LogHIDApi, Error, TEXT("No Portals found")); return false; } + +// write function need to be different on windows, as hid_write doesn't work with the way windows handle I/O +#if PLATFORM_WINDOWS + +#include + +#define HID_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS) +#define HID_IN_CTL_CODE(id) \ + CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101) + +struct hid_device_ { + HANDLE device_handle; + BOOL blocking; + USHORT output_report_length; + unsigned char* write_buf; + size_t input_report_length; + USHORT feature_report_length; + unsigned char* feature_buf; + wchar_t* last_error_str; + BOOL read_pending; + char* read_buf; + OVERLAPPED ol; + OVERLAPPED write_ol; + struct hid_device_info* device_info; +}; + + +void USkyPortalIO::Write(FWriteBlock* pb) +{ + if (!ensure(PortalDevice)) { + UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); + return; + } + BOOL res; + + OVERLAPPED ol; + memset(&ol, 0, sizeof(ol)); + + DWORD bytes_returned; + + res = DeviceIoControl(PortalDevice->device_handle, + IOCTL_HID_SET_OUTPUT_REPORT, + (unsigned char*)pb->data, write_buf_size, + (unsigned char*)pb->data, write_buf_size, + &bytes_returned, &ol); + ensureMsgf(res, TEXT("Unable to write to Portal")); +} + +#else +void USkyPortalIO::Write(FWriteBlock* pb) { + + if (!ensure(PortalDevice)) { + UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); + return; + } + + pb->buf[0] = 0; // Use report 0 + + + ensureMsgf(hid_write(PortalDevice, pb->data, read_buf_size) != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice)); + UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write to Portal. error:\n %s"), hid_error(PortalDevice)); +} +#endif + +void USkyPortalIO::WriteRaw(FWriteBlock* block) +{ + int res = hid_write(PortalDevice, block->data, write_buf_size); + if (res == -1) + { + UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write raw data to Portal. error:\n %s"), hid_error(PortalDevice)); + return; + } + block->BytesTransferred = res; +} + +uint8* USkyPortalIO::Read() +{ + uint8* output = 0; + hid_read_timeout(PortalDevice, output, 0x20, TIMEOUT); + return output; +} + +void USkyPortalIO::Close() { + if (PortalDevice) { + hid_close(PortalDevice); + } +} \ No newline at end of file diff --git a/Source/SkyPortal/Private/SkyPortalRunner.cpp b/Source/SkyPortal/Private/SkyPortalRunner.cpp new file mode 100644 index 0000000..ebcbd86 --- /dev/null +++ b/Source/SkyPortal/Private/SkyPortalRunner.cpp @@ -0,0 +1,2 @@ +#include "SkyPortalRunner.h" + diff --git a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp index 7a1819c..aee2b46 100644 --- a/Source/SkyPortal/Private/SkyPortalSubsystem.cpp +++ b/Source/SkyPortal/Private/SkyPortalSubsystem.cpp @@ -48,9 +48,9 @@ void USkyPortalSubsystem::Deinitialize() // Antenna up / activate void USkyPortalSubsystem::ActivatePortal(int active) { - RWBlock req, res; + FWriteBlock req, res; - memset(req.buf, 0, rw_buf_size); + memset(req.data, 0, write_buf_size); req.buf[1] = 'A'; req.buf[2] = active; do { Write(&req); } while (CheckResponse(&res, 'A')); @@ -58,88 +58,24 @@ void USkyPortalSubsystem::ActivatePortal(int active) } // Start portal -void USkyPortalSubsystem::RestartPortal() +void USkyPortalSubsystem::Ready() { - RWBlock req, res; + FWriteBlock command; - memset(req.buf, 0, rw_buf_size); - req.buf[1] = 'R'; + //memset(command.data, 0, write_buf_size); + command.data[1] = 'R'; + uint8* output; + do { + PortalHandle->Write(&command); + output = PortalHandle->Read(); + } while (output[0] != 'R'); - do { Write(&req); } while (CheckResponse(&res, 'R')); + uint16 _PortalId = ((output[1] << 8) + output[2]); + PortalId = _PortalId; //Need a conversion as uint16 is not supported in BP } -/* -Number of endpoints : 2 -found an IN End Point 0 with attributes interrupt and address 0x1 -found an OUT End Point 1 with attributes interrupt and address 0x1 -*/ -bool USkyPortalSubsystem::OpenPortalHandle() { - - //reset - if (PortalDevice) { - hid_close(PortalDevice); - } - - /* - Declare two pointers to hold information about HID devices. - "list" will point to the head of the linked list of devices, - "attributes" will be used to iterate through the list. - */ - struct hid_device_info* list, * attributes; - - list = hid_enumerate(0x0, 0x0); - // If `list` is NULL, that means no devices were found or there was an error. - // In this case, print an error message and terminate the program. - if (!list) { - UE_LOG(LogHIDApi, Error, TEXT("No devices found")); - // Get the error message from the HIDAPI - HidError = hid_error(NULL); - UE_LOG(LogHIDApi, Error, TEXT("%s"), *HidError); - return false; - } - attributes = list; - - - - - // Iterate through the linked list of devices - int vendorCount = sizeof(VendorIds) / sizeof(VendorIds[0]); - int productCount = sizeof(ProductIds) / sizeof(ProductIds[0]); - - while (attributes) { - // Check if the devices match any of vendor_id and product_id - for (int i = 0; i < vendorCount; i++) { - for (int j = 0; j < productCount; j++) { - if (attributes->vendor_id == VendorIds[i] && attributes->product_id == ProductIds[j]) { - UE_LOG(LogHIDApi, Display, TEXT("Portal found")); - UE_LOG(LogHIDApi, Log, TEXT("Vendor ID: 0x%x, Product ID: 0x%x"), attributes->vendor_id, attributes->product_id); - - PortalDevice = hid_open(attributes->vendor_id, attributes->product_id, NULL); - if (PortalDevice) { - UE_LOG(LogHIDApi, Display, TEXT("Successful connection to Portal.")); - - // Free the device list - hid_free_enumeration(list); - //bPortalConnected = true; - return true; - } - - break; - } - } - } - - // Move to the next device in the list - attributes = attributes->next; - } - - // Free the device list - hid_free_enumeration(list); - UE_LOG(LogHIDApi, Error, TEXT("No Portals found")); - return false; -} //{ Region Color & light functions void USkyPortalSubsystem::ChangePortalColor(const FLinearColor& Color) { @@ -210,70 +146,7 @@ void USkyPortalSubsystem::ChangePortalColorside(const FLinearColor& Color, const //} -// write function need to be different on windows, as hid_write doesn't work with the way windows handle I/O -#if PLATFORM_WINDOWS -#include - -#define HID_CTL_CODE(id) \ - CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS) -#define HID_IN_CTL_CODE(id) \ - CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101) - -struct hid_device_ { - HANDLE device_handle; - BOOL blocking; - USHORT output_report_length; - unsigned char* write_buf; - size_t input_report_length; - USHORT feature_report_length; - unsigned char* feature_buf; - wchar_t* last_error_str; - BOOL read_pending; - char* read_buf; - OVERLAPPED ol; - OVERLAPPED write_ol; - struct hid_device_info* device_info; -}; - - -void USkyPortalSubsystem::Write(RWBlock* pb) -{ - if (!ensure(PortalDevice)) { - UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); - return; - } - BOOL res; - - OVERLAPPED ol; - memset(&ol, 0, sizeof(ol)); - - DWORD bytes_returned; - - res = DeviceIoControl(PortalDevice->device_handle, - IOCTL_HID_SET_OUTPUT_REPORT, - (unsigned char*)pb->buf, 0x21, - (unsigned char*)pb->buf, 0x21, - &bytes_returned, &ol); - ensureMsgf(res, TEXT("Unable to write to Portal")); -} - -#else -void USkyPortalSubsystem::Write(RWBlock* pb) { - - if (!ensure(PortalDevice)) { - UE_LOG(LogSkyportalIO, Error, TEXT("No Portal found")); - return; - } - - pb->buf[0] = 0; // Use report 0 - - - ensureMsgf(hid_write(PortalDevice, pb->buf, 0x21) != -1, TEXT("Unable to write to Portal, %s"), hid_error(PortalDevice)); - UE_LOG(LogSkyportalIO, Error, TEXT("Unable to write to Portal. error:\n %s"), hid_error(PortalDevice)); -} -#endif FPortalStatusData USkyPortalSubsystem::ParsePortalStatus(const RWBlock& ResponseBlock) @@ -488,39 +361,6 @@ bool USkyPortalSubsystem::CheckResponse(RWBlock* res, char expect) -bool USkyPortalSubsystem::WriteBlock(unsigned int block, unsigned char data[0x10], int skylander) { - RWBlock req, res; //request and response buffer - unsigned char verify[0x10]; // A 16-byte array used to verify the data that was written to the portal. - - UE_LOG(LogSkyportalIO, Verbose, TEXT("Trying to write the current block :%X\n"), block); - - // Trying to write 3 times - for (int retries = 0; retries < 3; retries++) { - // Write request - // W 57 10 <0x10 bytes of data> - memset(req.buf, 0, rw_buf_size);//Reset request buffer - req.buf[1] = 'W'; - req.buf[2] = 0x10 + skylander; - req.buf[3] = (unsigned char)block; - memcpy(req.buf + 4, data, 0x10); - - do { Write(&req); } while (CheckResponse(&res, 'W')); - - Sleep(100); //Wait 0.1 seconds for write to take effect - - memset(verify, 0xCD, sizeof(verify)); // 0xCD is a placeholder value - ReadBlock(block, verify, skylander); - - if (memcmp(data, verify, sizeof(verify))) { - UE_LOG(LogSkyportalIO, Error, TEXT("verification of the written block failed")); - continue; //retry - } - UE_LOG(LogSkyportalIO, Verbose, TEXT("block successfully written")); - return true; - } - UE_LOG(LogSkyportalIO, Fatal, TEXT("failed to write block")); - return false; -} EPortalCommand USkyPortalSubsystem::GetPortalCommandFromChar(unsigned char Char) @@ -606,18 +446,17 @@ bool USkyPortalSubsystem::ReadBlock(unsigned int block, unsigned char data[0x10] bool USkyPortalSubsystem::ConnectPortal() { - - bPortalConnected = OpenPortalHandle(); - if (bPortalConnected) { - RestartPortal(); + PortalHandle = NewObject(); + if (IsValidLowLevelFast(PortalHandle)) { + UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: ")); + Ready(); ActivatePortal(1); Sleep(500); ChangePortalColor(FLinearColor(0.5, 0.5, 0.5)); - - UE_LOG(LogSkyportalIO, Log, TEXT("Portal connected: ")); + return true; } - return bPortalConnected; + return false; } bool USkyPortalSubsystem::bIsPortalReady() diff --git a/Source/SkyPortal/Public/SkyPortalFigure.h b/Source/SkyPortal/Public/SkyPortalFigure.h index 07da0e2..e2e12f4 100644 --- a/Source/SkyPortal/Public/SkyPortalFigure.h +++ b/Source/SkyPortal/Public/SkyPortalFigure.h @@ -3,6 +3,14 @@ //#include "SkyPortalFigure.generated.h" +UENUM(BlueprintType) +enum class EFigureStatus : uint8 +{ + NOT_PRESENT = 0b00 UMETA(DisplayName = "Not Present"), + PRESENT = 0b01 UMETA(DisplayName = "Present"), + ADDED = 0b11 UMETA(DisplayName = "Added"), + REMOVED = 0b10 UMETA(DisplayName = "Removed") +}; #define FIGURE_TOTAL_BLOCKS 64 #define FIGURE_BLOCK_SIZE 16 @@ -31,12 +39,12 @@ public: uint16 ATQA; //always set to 0x01 0x0F FString ProductionYear; //last 2 digits of the year that the tag was manufactured as Binary-coded decimal #pragma endregion - int16 ID; #pragma region Toy code uint32 ToyCodeNumber1, ToyCodeNumber2; uint64 FullToyCodeNumber; FString ToyCode; #pragma endregion + int16 ID; int16 VariantID; #pragma region counters uint8 counter1; diff --git a/Source/SkyPortal/Public/SkyPortalIO.h b/Source/SkyPortal/Public/SkyPortalIO.h index 5936ea2..33f501a 100644 --- a/Source/SkyPortal/Public/SkyPortalIO.h +++ b/Source/SkyPortal/Public/SkyPortalIO.h @@ -10,24 +10,62 @@ DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All); -UCLASS(MinimalAPI) -class SkyPortalIO : public UObjectBase +constexpr auto write_buf_size = 0x21; +constexpr auto TIMEOUT = 30000; //milliseconds + +/* Portal physicial device IDs */ +const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 }; +const int ProductIds[4] = { 0x150, 0x967, 0x1f17 }; + +/* WriteBlock +* +* Contain all the data that pass inside hidapi write + the number of bytes in case of successful write +* @param data all the block data, should be 0x21 sized +* @param BytesTransferred In case of successful write, print the number of byte transfered. Could be used for verifications +*/ +USTRUCT() +struct FWriteBlock { + GENERATED_BODY() + unsigned char data[write_buf_size]; + int BytesTransferred; +} ; + +/* This class will contain and handle all the low-lewel functions +* Should be able to be called anywhere +*/ +UCLASS() +class USkyPortalIO : public UObject { GENERATED_BODY() public: - SkyPortalIO() - { - OpenPortalHandle(); - } + /* hidapi will write error message in here*/ + UPROPERTY(BlueprintReadOnly) + FString HidError; -private: + /*Portal ready to be listened or to receive commands*/ + UPROPERTY(BlueprintReadOnly) + bool bPortalReady; + /* Connect to Portal - will write the PortalDevice var if success */ bool OpenPortalHandle(); - //Portal ref used in the subsystem - hid_device* PortalDevice; + void Write(FWriteBlock* Block); + void WriteRaw(FWriteBlock* Block); + /* Listen to portal + * @return The data sended by the portal device + */ + UFUNCTION() + uint8* Read(); + + void Close(); +private: + + + + /* Portal ref used in the subsystem */ + hid_device* PortalDevice; }; diff --git a/Source/SkyPortal/Public/SkyPortalRunner.h b/Source/SkyPortal/Public/SkyPortalRunner.h new file mode 100644 index 0000000..9bda771 --- /dev/null +++ b/Source/SkyPortal/Public/SkyPortalRunner.h @@ -0,0 +1,81 @@ +#pragma once + +#include "HAL/Runnable.h" +#include "SkyPortalFigure.h" + +class SkyPortalRunner +{ + +}; + +USTRUCT(BlueprintType) +struct FPortalStatusData +{ + GENERATED_USTRUCT_BODY() + + // Array of statuses + UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder)) + TArray StatusArray; + + // timestamp. + // 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; + + // Should always be true + UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure") + bool bIsReady; + + explicit FPortalStatusData(uint8 ArraySize = 16, EFigureStatus DefaultStatus = EFigureStatus::NOT_PRESENT) : + Counter(0), // Utilisation correcte de l'initialisation directe + bIsReady(true) // Utilisation correcte de l'initialisation directe + { + // Initialisation du tableau StatusArray avec 16 éléments par défaut + StatusArray.Init(DefaultStatus, ArraySize); + } + + // 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); + } +}; + + +class FPortalStatusChecker : public FRunnable { +public: + // Constructor: pass the subsystem and desired check interval (in seconds) + FPortalStatusChecker(USkyPortalSubsystem* InSubsystem, float InCheckInterval); + + // FRunnable interface + virtual bool Init() override; + virtual uint32 Run() override; + virtual void Stop() override; + virtual void Exit() override; + +private: + // Pointer to the subsystem that contains PortalStatus() + USkyPortalSubsystem* SkyPortalSubsystem; + + // Time interval (in seconds) for status checking + float CheckInterval; + + // Thread control variables + FThreadSafeBool bShouldRun; + + // Helper function to check portal status + void CheckPortalStatus(); +}; + diff --git a/Source/SkyPortal/Public/SkyPortalSubsystem.h b/Source/SkyPortal/Public/SkyPortalSubsystem.h index 40ef96d..5e85e97 100644 --- a/Source/SkyPortal/Public/SkyPortalSubsystem.h +++ b/Source/SkyPortal/Public/SkyPortalSubsystem.h @@ -1,9 +1,7 @@ #pragma once #include "Subsystems/EngineSubsystem.h" -#include "hidapi.h" -#include "HAL/Runnable.h" -#include "SkyPortalFigure.h" +#include "SkyPortalRunner.h" #include "SkyPortalSubsystem.generated.h" @@ -30,68 +28,10 @@ enum EPortalCommand { S UMETA(DisplayName = "Status") }; -UENUM(BlueprintType) -enum class EFigureStatus : uint8 -{ - NOT_PRESENT = 0b00 UMETA(DisplayName = "Not Present"), - PRESENT = 0b01 UMETA(DisplayName = "Present"), - ADDED = 0b11 UMETA(DisplayName = "Added"), - REMOVED = 0b10 UMETA(DisplayName = "Removed") -}; -USTRUCT(BlueprintType) -struct FPortalStatusData -{ - GENERATED_USTRUCT_BODY() - // Array of statuses - UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder)) - TArray StatusArray; - // timestamp. - // 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; - // Should always be true - UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure") - bool bIsReady; - - explicit FPortalStatusData(uint8 ArraySize = 16, EFigureStatus DefaultStatus = EFigureStatus::NOT_PRESENT) : - Counter(0), // Utilisation correcte de l'initialisation directe - bIsReady(true) // Utilisation correcte de l'initialisation directe - { - // Initialisation du tableau StatusArray avec 16 éléments par défaut - StatusArray.Init(DefaultStatus, ArraySize); - } - - // 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 - -typedef struct { - unsigned char buf[rw_buf_size]; int BytesTransferred; -} RWBlock; @@ -102,51 +42,21 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnSkylanderRemovedDelegate, int32, #pragma endregion -class FPortalStatusChecker : public FRunnable { -public: - // Constructor: pass the subsystem and desired check interval (in seconds) - FPortalStatusChecker(USkyPortalSubsystem* InSubsystem, float InCheckInterval); - - // FRunnable interface - virtual bool Init() override; - virtual uint32 Run() override; - virtual void Stop() override; - virtual void Exit() override; - -private: - // Pointer to the subsystem that contains PortalStatus() - USkyPortalSubsystem* SkyPortalSubsystem; - - // Time interval (in seconds) for status checking - float CheckInterval; - - // Thread control variables - FThreadSafeBool bShouldRun; - - // Helper function to check portal status - void CheckPortalStatus(); -}; - - -/* Handle all the portal I/O -* -* -* +/* +* Handle all the blueprints functions and game logic. +* */ 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; @@ -162,6 +72,10 @@ public: UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal")) SKYPORTAL_API bool ConnectPortal(); + + UFUNCTION(BlueprintCallable, CallInEditor, meta = (Category = "SkyPortal|Commands")) + SKYPORTAL_API void Ready(); + /*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(); @@ -202,26 +116,25 @@ public: UPROPERTY(BlueprintReadOnly) FPortalStatusData OldStatusData; + UPROPERTY(BlueprintReadOnly) + uint32 PortalId; + EPortalCommand GetPortalCommandFromChar(unsigned char Char); UPROPERTY(VisibleAnywhere, BlueprintReadOnly) bool bPortalConnected = false; - FString HidError; - - bool ReadBlock(unsigned int block, unsigned char data[0x10], int skylander); - bool WriteBlock(unsigned int, unsigned char[0x10], int); - bool CheckResponse(RWBlock*, char); - void CheckComplexResponse(); + UFUNCTION() TArray QueryBlock(uint8 characterIndex, uint8 block = 0x00); + USkyPortalIO* PortalHandle; private: - FPortalStatusData ParsePortalStatus(const RWBlock& ResponseBlock); - + FPortalStatusData ParsePortalStatus(const WriteBlock& ResponseBlock); + @@ -231,12 +144,12 @@ private: void ActivatePortal(int active); - void RestartPortal(); + // Block/byte related data write/read functions - bool OpenPortalHandle(); - void Write(RWBlock*); + + FigureDataBlock ReadFigureBlocks(uint8 FigureIndex); bool FalsePositive() const; @@ -247,15 +160,6 @@ private: 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; };