mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-10 00:41:19 +12:00
nsyshid: Emulate Infinity Base (#1246)
This commit is contained in:
parent
64232ffdbd
commit
a1c1a608d7
10 changed files with 1478 additions and 22 deletions
|
@ -1,4 +1,5 @@
|
|||
#include "BackendEmulated.h"
|
||||
#include "Infinity.h"
|
||||
#include "Skylander.h"
|
||||
#include "config/CemuConfig.h"
|
||||
|
||||
|
@ -25,5 +26,12 @@ namespace nsyshid::backend::emulated
|
|||
auto device = std::make_shared<SkylanderPortalDevice>();
|
||||
AttachDevice(device);
|
||||
}
|
||||
if (GetConfig().emulated_usb_devices.emulate_infinity_base && !FindDeviceById(0x0E6F, 0x0129))
|
||||
{
|
||||
cemuLog_logDebug(LogType::Force, "Attaching Emulated Base");
|
||||
// Add Infinity Base
|
||||
auto device = std::make_shared<InfinityBaseDevice>();
|
||||
AttachDevice(device);
|
||||
}
|
||||
}
|
||||
} // namespace nsyshid::backend::emulated
|
1102
src/Cafe/OS/libs/nsyshid/Infinity.cpp
Normal file
1102
src/Cafe/OS/libs/nsyshid/Infinity.cpp
Normal file
File diff suppressed because it is too large
Load diff
105
src/Cafe/OS/libs/nsyshid/Infinity.h
Normal file
105
src/Cafe/OS/libs/nsyshid/Infinity.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "nsyshid.h"
|
||||
#include "Backend.h"
|
||||
|
||||
#include "Common/FileStream.h"
|
||||
|
||||
namespace nsyshid
|
||||
{
|
||||
class InfinityBaseDevice final : public Device {
|
||||
public:
|
||||
InfinityBaseDevice();
|
||||
~InfinityBaseDevice() = default;
|
||||
|
||||
bool Open() override;
|
||||
|
||||
void Close() override;
|
||||
|
||||
bool IsOpened() override;
|
||||
|
||||
ReadResult Read(ReadMessage* message) override;
|
||||
|
||||
WriteResult Write(WriteMessage* message) override;
|
||||
|
||||
bool GetDescriptor(uint8 descType,
|
||||
uint8 descIndex,
|
||||
uint8 lang,
|
||||
uint8* output,
|
||||
uint32 outputMaxLength) override;
|
||||
|
||||
bool SetProtocol(uint8 ifIndex, uint8 protocol) override;
|
||||
|
||||
bool SetReport(ReportMessage* message) override;
|
||||
|
||||
private:
|
||||
bool m_IsOpened;
|
||||
};
|
||||
|
||||
constexpr uint16 INF_BLOCK_COUNT = 0x14;
|
||||
constexpr uint16 INF_BLOCK_SIZE = 0x10;
|
||||
constexpr uint16 INF_FIGURE_SIZE = INF_BLOCK_COUNT * INF_BLOCK_SIZE;
|
||||
constexpr uint8 MAX_FIGURES = 9;
|
||||
class InfinityUSB {
|
||||
public:
|
||||
struct InfinityFigure final
|
||||
{
|
||||
std::unique_ptr<FileStream> infFile;
|
||||
std::array<uint8, INF_FIGURE_SIZE> data{};
|
||||
bool present = false;
|
||||
uint8 orderAdded = 255;
|
||||
void Save();
|
||||
};
|
||||
|
||||
void SendCommand(uint8* buf, sint32 originalLength);
|
||||
std::array<uint8, 32> GetStatus();
|
||||
|
||||
void GetBlankResponse(uint8 sequence, std::array<uint8, 32>& replyBuf);
|
||||
void DescrambleAndSeed(uint8* buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
void GetNextAndScramble(uint8 sequence, std::array<uint8, 32>& replyBuf);
|
||||
void GetPresentFigures(uint8 sequence, std::array<uint8, 32>& replyBuf);
|
||||
void QueryBlock(uint8 figNum, uint8 block, std::array<uint8, 32>& replyBuf,
|
||||
uint8 sequence);
|
||||
void WriteBlock(uint8 figNum, uint8 block, const uint8* toWriteBuf,
|
||||
std::array<uint8, 32>& replyBuf, uint8 sequence);
|
||||
void GetFigureIdentifier(uint8 figNum, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
|
||||
bool RemoveFigure(uint8 position);
|
||||
uint32 LoadFigure(const std::array<uint8, INF_FIGURE_SIZE>& buf,
|
||||
std::unique_ptr<FileStream>, uint8 position);
|
||||
bool CreateFigure(fs::path pathName, uint32 figureNum, uint8 series);
|
||||
static std::map<const uint32, const std::pair<const uint8, const char*>> GetFigureList();
|
||||
std::pair<uint8, std::string> FindFigure(uint32 figNum);
|
||||
|
||||
protected:
|
||||
std::shared_mutex m_infinityMutex;
|
||||
std::array<InfinityFigure, 9> m_figures;
|
||||
|
||||
private:
|
||||
uint8 GenerateChecksum(const std::array<uint8, 32>& data,
|
||||
int numOfBytes) const;
|
||||
uint32 Descramble(uint64 numToDescramble);
|
||||
uint64 Scramble(uint32 numToScramble, uint32 garbage);
|
||||
void GenerateSeed(uint32 seed);
|
||||
uint32 GetNext();
|
||||
InfinityFigure& GetFigureByOrder(uint8 orderAdded);
|
||||
uint8 DeriveFigurePosition(uint8 position);
|
||||
std::array<uint8, 16> GenerateInfinityFigureKey(const std::vector<uint8>& sha1Data);
|
||||
std::array<uint8, 16> GenerateBlankFigureData(uint32 figureNum, uint8 series);
|
||||
|
||||
uint32 m_randomA;
|
||||
uint32 m_randomB;
|
||||
uint32 m_randomC;
|
||||
uint32 m_randomD;
|
||||
|
||||
uint8 m_figureOrder = 0;
|
||||
std::queue<std::array<uint8, 32>> m_figureAddedRemovedResponses;
|
||||
std::queue<std::array<uint8, 32>> m_queries;
|
||||
};
|
||||
extern InfinityUSB g_infinitybase;
|
||||
|
||||
} // namespace nsyshid
|
|
@ -855,7 +855,7 @@ namespace nsyshid
|
|||
return false;
|
||||
}
|
||||
|
||||
std::array<uint8, BLOCK_COUNT * BLOCK_SIZE> data{};
|
||||
std::array<uint8, SKY_FIGURE_SIZE> data{};
|
||||
|
||||
uint32 first_block = 0x690F0F0F;
|
||||
uint32 other_blocks = 0x69080F7F;
|
||||
|
|
|
@ -38,9 +38,9 @@ namespace nsyshid
|
|||
bool m_IsOpened;
|
||||
};
|
||||
|
||||
constexpr uint16 BLOCK_COUNT = 0x40;
|
||||
constexpr uint16 BLOCK_SIZE = 0x10;
|
||||
constexpr uint16 FIGURE_SIZE = BLOCK_COUNT * BLOCK_SIZE;
|
||||
constexpr uint16 SKY_BLOCK_COUNT = 0x40;
|
||||
constexpr uint16 SKY_BLOCK_SIZE = 0x10;
|
||||
constexpr uint16 SKY_FIGURE_SIZE = SKY_BLOCK_COUNT * SKY_BLOCK_SIZE;
|
||||
constexpr uint8 MAX_SKYLANDERS = 16;
|
||||
|
||||
class SkylanderUSB {
|
||||
|
@ -50,7 +50,7 @@ namespace nsyshid
|
|||
std::unique_ptr<FileStream> skyFile;
|
||||
uint8 status = 0;
|
||||
std::queue<uint8> queuedStatus;
|
||||
std::array<uint8, BLOCK_COUNT * BLOCK_SIZE> data{};
|
||||
std::array<uint8, SKY_BLOCK_SIZE> data{};
|
||||
uint32 lastId = 0;
|
||||
void Save();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue