mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-04-10 02:11:29 -06:00
Move Minifgure Dialog
This commit is contained in:
parent
08f789a313
commit
0829d33a48
@ -609,9 +609,11 @@ namespace nsyshid
|
||||
m_queries.push(q_result);
|
||||
}
|
||||
|
||||
uint32 DimensionsUSB::LoadFigure(const std::array<uint8, 0x2D * 0x04>& buf, std::unique_ptr<FileStream> file, uint8 pad, uint8 index)
|
||||
uint32 DimensionsUSB::LoadFigure(const std::array<uint8, 0x2D * 0x04>& buf, std::unique_ptr<FileStream> file, uint8 pad, uint8 index, bool lock)
|
||||
{
|
||||
std::lock_guard lock(m_dimensionsMutex);
|
||||
if (lock)
|
||||
std::shared_lock lock(m_dimensionsMutex);
|
||||
|
||||
const uint32 id = GetFigureId(buf);
|
||||
|
||||
DimensionsMini& figure = GetFigureByIndex(index);
|
||||
@ -625,30 +627,44 @@ namespace nsyshid
|
||||
std::array<uint8, 32> figureChangeResponse = {0x56, 0x0b, figure.pad, 0x00, figure.index, 0x00, buf[0], buf[1], buf[2], buf[4], buf[5], buf[6], buf[7]};
|
||||
figureChangeResponse[13] = GenerateChecksum(figureChangeResponse, 13);
|
||||
m_figureAddedRemovedResponses.push(figureChangeResponse);
|
||||
|
||||
if (lock)
|
||||
std::shared_lock unlock(m_dimensionsMutex);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
bool DimensionsUSB::RemoveFigure(uint8 pad, uint8 index)
|
||||
bool DimensionsUSB::RemoveFigure(uint8 pad, uint8 index, bool save, bool lock)
|
||||
{
|
||||
std::lock_guard lock(m_dimensionsMutex);
|
||||
DimensionsMini& figure = GetFigureByIndex(index);
|
||||
if (figure.index == 255)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lock)
|
||||
std::shared_lock lock(m_dimensionsMutex);
|
||||
|
||||
// When a figure is removed from the toypad, respond to the game with the pad they were removed from, their index,
|
||||
// the direction (0x01 in byte 6 for removed) and their UID
|
||||
std::array<uint8, 32> figureChangeResponse = {0x56, 0x0b, figure.pad, 0x00, figure.index, 0x01,
|
||||
figure.data[0], figure.data[1], figure.data[2],
|
||||
figure.data[4], figure.data[5], figure.data[6], figure.data[7]};
|
||||
figure.Save();
|
||||
figure.dimFile.reset();
|
||||
if (save)
|
||||
{
|
||||
figure.Save();
|
||||
figure.dimFile.reset();
|
||||
}
|
||||
figure.index = 255;
|
||||
figure.pad = 255;
|
||||
figure.id = 0;
|
||||
memcpy(&figureChangeResponse[6], figure.data.data(), 7);
|
||||
figureChangeResponse[13] = GenerateChecksum(figureChangeResponse, 13);
|
||||
m_figureAddedRemovedResponses.push(figureChangeResponse);
|
||||
|
||||
if (lock)
|
||||
std::shared_lock unlock(m_dimensionsMutex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -697,8 +713,40 @@ namespace nsyshid
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DimensionsUSB::MoveFigure(uint8 pad, uint8 index, uint8 oldPad, uint8 oldIndex)
|
||||
{
|
||||
std::lock_guard lock(m_dimensionsMutex);
|
||||
|
||||
if (oldIndex == index)
|
||||
{
|
||||
// Don't bother removing and loading again, just send response to the game
|
||||
const DimensionsMini& figure = GetFigureByIndex(oldIndex);
|
||||
std::array<uint8, 32> figureRemoveResponse = {0x56, 0x0b, pad, 0x00, figure.index, 0x01, figure.data[0], figure.data[1], figure.data[2], figure.data[4], figure.data[5], figure.data[6], figure.data[7]};
|
||||
figureRemoveResponse[13] = GenerateChecksum(figureRemoveResponse, 13);
|
||||
std::array<uint8, 32> figureAddResponse = {0x56, 0x0b, pad, 0x00, figure.index, 0x00, figure.data[0], figure.data[1], figure.data[2], figure.data[4], figure.data[5], figure.data[6], figure.data[7]};
|
||||
figureAddResponse[13] = GenerateChecksum(figureAddResponse, 13);
|
||||
m_figureAddedRemovedResponses.push(std::move(figureRemoveResponse));
|
||||
m_figureAddedRemovedResponses.push(std::move(figureAddResponse));
|
||||
return true;
|
||||
}
|
||||
|
||||
// When moving figures between spaces on the toypad, remove any figure from the space they are moving to,
|
||||
// then remove them from their current space, then load them to the space they are moving to
|
||||
RemoveFigure(pad, index, true, false);
|
||||
|
||||
DimensionsMini& figure = GetFigureByIndex(oldIndex);
|
||||
const std::array<uint8, 0x2D * 0x04> data = figure.data;
|
||||
std::unique_ptr<FileStream> inFile = std::move(figure.dimFile);
|
||||
|
||||
RemoveFigure(oldPad, oldIndex, false, false);
|
||||
|
||||
LoadFigure(data, std::move(inFile), pad, index, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DimensionsUSB::GenerateRandomNumber(std::span<const uint8, 8> buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf)
|
||||
std::array<uint8, 32>& replyBuf)
|
||||
{
|
||||
// Decrypt payload into an 8 byte array
|
||||
std::array<uint8, 8> value = Decrypt(buf, std::nullopt);
|
||||
@ -720,7 +768,7 @@ namespace nsyshid
|
||||
}
|
||||
|
||||
void DimensionsUSB::GetChallengeResponse(std::span<const uint8, 8> buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf)
|
||||
std::array<uint8, 32>& replyBuf)
|
||||
{
|
||||
// Decrypt payload into an 8 byte array
|
||||
std::array<uint8, 8> value = Decrypt(buf, std::nullopt);
|
||||
@ -731,8 +779,8 @@ namespace nsyshid
|
||||
// Encrypt an 8 byte array, first 4 bytes are the next random number (little endian)
|
||||
// followed by the confirmation from the decrypted payload
|
||||
std::array<uint8, 8> valueToEncrypt = {uint8(nextRandom & 0xFF), uint8((nextRandom >> 8) & 0xFF),
|
||||
uint8((nextRandom >> 16) & 0xFF), uint8((nextRandom >> 24) & 0xFF),
|
||||
value[0], value[1], value[2], value[3]};
|
||||
uint8((nextRandom >> 16) & 0xFF), uint8((nextRandom >> 24) & 0xFF),
|
||||
value[0], value[1], value[2], value[3]};
|
||||
std::array<uint8, 8> encrypted = Encrypt(valueToEncrypt, std::nullopt);
|
||||
replyBuf[0] = 0x55;
|
||||
replyBuf[1] = 0x09;
|
||||
@ -941,7 +989,7 @@ namespace nsyshid
|
||||
DimensionsUSB::DimensionsMini&
|
||||
DimensionsUSB::GetFigureByIndex(uint8 index)
|
||||
{
|
||||
return figures[index];
|
||||
return m_figures[index];
|
||||
}
|
||||
|
||||
void DimensionsUSB::QueryBlock(uint8 index, uint8 page,
|
||||
@ -970,7 +1018,7 @@ namespace nsyshid
|
||||
}
|
||||
|
||||
void DimensionsUSB::WriteBlock(uint8 index, uint8 page, std::span<const uint8, 4> toWriteBuf,
|
||||
std::array<uint8, 32>& replyBuf, uint8 sequence)
|
||||
std::array<uint8, 32>& replyBuf, uint8 sequence)
|
||||
{
|
||||
std::lock_guard lock(m_dimensionsMutex);
|
||||
|
||||
@ -1000,7 +1048,7 @@ namespace nsyshid
|
||||
}
|
||||
|
||||
void DimensionsUSB::GetModel(std::span<const uint8, 8> buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf)
|
||||
std::array<uint8, 32>& replyBuf)
|
||||
{
|
||||
// Decrypt payload to 8 byte array, byte 1 is the index, 4-7 are the confirmation
|
||||
std::array<uint8, 8> value = Decrypt(buf, std::nullopt);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "nsyshid.h"
|
||||
#include "Backend.h"
|
||||
@ -54,31 +54,32 @@ namespace nsyshid
|
||||
std::array<uint8, 32> GetStatus();
|
||||
|
||||
void GenerateRandomNumber(std::span<const uint8, 8> buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
void InitializeRNG(uint32 seed);
|
||||
void GetChallengeResponse(std::span<const uint8, 8> buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
void QueryBlock(uint8 index, uint8 page, std::array<uint8, 32>& replyBuf,
|
||||
uint8 sequence);
|
||||
uint8 sequence);
|
||||
void WriteBlock(uint8 index, uint8 page, std::span<const uint8, 4> toWriteBuf, std::array<uint8, 32>& replyBuf,
|
||||
uint8 sequence);
|
||||
uint8 sequence);
|
||||
void GetModel(std::span<const uint8, 8> buf, uint8 sequence,
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
std::array<uint8, 32>& replyBuf);
|
||||
|
||||
bool RemoveFigure(uint8 pad, uint8 index);
|
||||
uint32 LoadFigure(const std::array<uint8, 0x2D * 0x04>& buf, std::unique_ptr<FileStream> file, uint8 pad, uint8 index);
|
||||
bool RemoveFigure(uint8 pad, uint8 index, bool save, bool lock);
|
||||
uint32 LoadFigure(const std::array<uint8, 0x2D * 0x04>& buf, std::unique_ptr<FileStream> file, uint8 pad, uint8 index, bool lock);
|
||||
bool CreateFigure(fs::path pathName, uint32 id);
|
||||
bool MoveFigure(uint8 pad, uint8 index, uint8 oldPad, uint8 oldIndex);
|
||||
static std::map<const uint32, const char*> GetListMinifigs();
|
||||
std::string FindFigure(uint32 figNum);
|
||||
|
||||
protected:
|
||||
std::mutex m_dimensionsMutex;
|
||||
std::array<DimensionsMini, 7> figures;
|
||||
std::shared_mutex m_dimensionsMutex;
|
||||
std::array<DimensionsMini, 7> m_figures{};
|
||||
|
||||
private:
|
||||
void RandomUID(std::array<uint8, 0x2D * 0x04>& uidBuffer);
|
||||
uint8 GenerateChecksum(const std::array<uint8, 32>& data,
|
||||
int numOfBytes) const;
|
||||
int numOfBytes) const;
|
||||
std::array<uint8, 8> Decrypt(std::span<const uint8, 8> buf, std::optional<std::array<uint8, 16>> key);
|
||||
std::array<uint8, 8> Encrypt(std::span<const uint8, 8> buf, std::optional<std::array<uint8, 16>> key);
|
||||
std::array<uint8, 16> GenerateFigureKey(const std::array<uint8, 0x2D * 0x04>& uid);
|
||||
|
||||
@ -168,8 +168,7 @@ wxPanel* EmulatedUSBDeviceFrame::AddDimensionsPage(wxNotebook* notebook)
|
||||
return panel;
|
||||
}
|
||||
|
||||
wxBoxSizer* EmulatedUSBDeviceFrame::AddSkylanderRow(uint8 rowNumber,
|
||||
wxStaticBox* box)
|
||||
wxBoxSizer* EmulatedUSBDeviceFrame::AddSkylanderRow(uint8 rowNumber, wxStaticBox* box)
|
||||
{
|
||||
auto* row = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
@ -237,10 +236,13 @@ wxBoxSizer* EmulatedUSBDeviceFrame::AddDimensionPanel(uint8 pad, uint8 index, wx
|
||||
auto* panel = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto* combo_row = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_dimension_slots[index] = new wxTextCtrl(box, wxID_ANY, _("None"), wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_READONLY);
|
||||
combo_row->Add(m_dimension_slots[index], 1, wxEXPAND | wxALL, 2);
|
||||
m_dimensionSlots[index] = new wxTextCtrl(box, wxID_ANY, _("None"), wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_READONLY);
|
||||
combo_row->Add(m_dimensionSlots[index], 1, wxEXPAND | wxALL, 2);
|
||||
auto* move_button = new wxButton(box, wxID_ANY, _("Move"));
|
||||
move_button->Bind(wxEVT_BUTTON, [pad, index, this](wxCommandEvent&) {
|
||||
MoveMinifig(pad, index);
|
||||
});
|
||||
|
||||
combo_row->Add(move_button, 1, wxEXPAND | wxALL, 2);
|
||||
|
||||
@ -434,6 +436,80 @@ wxString CreateSkylanderDialog::GetFilePath() const
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::UpdateSkylanderEdits()
|
||||
{
|
||||
for (auto i = 0; i < nsyshid::MAX_SKYLANDERS; i++)
|
||||
{
|
||||
std::string displayString;
|
||||
if (auto sd = m_skySlots[i])
|
||||
{
|
||||
auto [portalSlot, skyId, skyVar] = sd.value();
|
||||
displayString = nsyshid::g_skyportal.FindSkylander(skyId, skyVar);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayString = "None";
|
||||
}
|
||||
|
||||
m_skylanderSlots[i]->ChangeValue(displayString);
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadFigure(uint8 slot)
|
||||
{
|
||||
wxFileDialog openFileDialog(this, _("Open Infinity Figure dump"), "", "",
|
||||
"BIN files (*.bin)|*.bin",
|
||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if (openFileDialog.ShowModal() != wxID_OK || openFileDialog.GetPath().empty())
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "File Okay Error");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
LoadFigurePath(slot, openFileDialog.GetPath());
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadFigurePath(uint8 slot, wxString path)
|
||||
{
|
||||
std::unique_ptr<FileStream> infFile(FileStream::openFile2(_utf8ToPath(path.utf8_string()), true));
|
||||
if (!infFile)
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "File Open Error");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<uint8, nsyshid::INF_FIGURE_SIZE> fileData;
|
||||
if (infFile->readData(fileData.data(), fileData.size()) != fileData.size())
|
||||
{
|
||||
wxMessageDialog open_error(this, "Failed to read file! File was too small");
|
||||
open_error.ShowModal();
|
||||
return;
|
||||
}
|
||||
ClearFigure(slot);
|
||||
|
||||
uint32 number = nsyshid::g_infinitybase.LoadFigure(fileData, std::move(infFile), slot);
|
||||
m_infinitySlots[slot]->ChangeValue(nsyshid::g_infinitybase.FindFigure(number).second);
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::CreateFigure(uint8 slot)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Create Figure: {}", slot);
|
||||
CreateInfinityFigureDialog create_dlg(this, slot);
|
||||
create_dlg.ShowModal();
|
||||
if (create_dlg.GetReturnCode() == 1)
|
||||
{
|
||||
LoadFigurePath(slot, create_dlg.GetFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::ClearFigure(uint8 slot)
|
||||
{
|
||||
m_infinitySlots[slot]->ChangeValue("None");
|
||||
nsyshid::g_infinitybase.RemoveFigure(slot);
|
||||
}
|
||||
|
||||
CreateInfinityFigureDialog::CreateInfinityFigureDialog(wxWindow* parent, uint8 slot)
|
||||
: wxDialog(parent, wxID_ANY, _("Infinity Figure Creator"), wxDefaultPosition, wxSize(500, 150))
|
||||
{
|
||||
@ -530,6 +606,77 @@ wxString CreateInfinityFigureDialog::GetFilePath() const
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadMinifig(uint8 pad, uint8 index)
|
||||
{
|
||||
wxFileDialog openFileDialog(this, _("Load Dimensions Figure"), "", "",
|
||||
"Dimensions files (*.bin)|*.bin",
|
||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if (openFileDialog.ShowModal() != wxID_OK || openFileDialog.GetPath().empty())
|
||||
return;
|
||||
|
||||
LoadMinifigPath(openFileDialog.GetPath(), pad, index);
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadMinifigPath(wxString path_name, uint8 pad, uint8 index)
|
||||
{
|
||||
std::unique_ptr<FileStream> dim_file(FileStream::openFile2(_utf8ToPath(path_name.utf8_string()), true));
|
||||
if (!dim_file)
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "Failed to open minifig file");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<uint8, 0x2D * 0x04> file_data;
|
||||
|
||||
if (dim_file->readData(file_data.data(), file_data.size()) != file_data.size())
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "Failed to read minifig file data");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
ClearMinifig(pad, index);
|
||||
|
||||
uint32 id = nsyshid::g_dimensionstoypad.LoadFigure(file_data, std::move(dim_file), pad, index, true);
|
||||
m_dimensionSlots[index]->ChangeValue(nsyshid::g_dimensionstoypad.FindFigure(id));
|
||||
m_dimSlots[index] = id;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::ClearMinifig(uint8 pad, uint8 index)
|
||||
{
|
||||
nsyshid::g_dimensionstoypad.RemoveFigure(pad, index, true, true);
|
||||
m_dimensionSlots[index]->ChangeValue("None");
|
||||
m_dimSlots[index] = std::nullopt;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::CreateMinifig(uint8 pad, uint8 index)
|
||||
{
|
||||
CreateDimensionFigureDialog create_dlg(this);
|
||||
create_dlg.ShowModal();
|
||||
if (create_dlg.GetReturnCode() == 1)
|
||||
{
|
||||
LoadMinifigPath(create_dlg.GetFilePath(), pad, index);
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::MoveMinifig(uint8 pad, uint8 index)
|
||||
{
|
||||
MoveDimensionFigureDialog move_dlg(this, index);
|
||||
move_dlg.ShowModal();
|
||||
if (move_dlg.GetReturnCode() == 1)
|
||||
{
|
||||
nsyshid::g_dimensionstoypad.MoveFigure(move_dlg.GetNewPad(), move_dlg.GetNewIndex(), pad, index);
|
||||
if (index != move_dlg.GetNewIndex())
|
||||
{
|
||||
m_dimSlots[move_dlg.GetNewIndex()] = m_dimSlots[index];
|
||||
m_dimensionSlots[move_dlg.GetNewIndex()]->ChangeValue(m_dimensionSlots[index]->GetValue());
|
||||
m_dimSlots[index] = std::nullopt;
|
||||
m_dimensionSlots[index]->ChangeValue("None");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CreateDimensionFigureDialog::CreateDimensionFigureDialog(wxWindow* parent)
|
||||
: wxDialog(parent, wxID_ANY, _("Dimensions Figure Creator"), wxDefaultPosition, wxSize(500, 200))
|
||||
{
|
||||
@ -618,125 +765,64 @@ wxString CreateDimensionFigureDialog::GetFilePath() const
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadMinifig(uint8 pad, uint8 index)
|
||||
MoveDimensionFigureDialog::MoveDimensionFigureDialog(EmulatedUSBDeviceFrame* parent, uint8 currentIndex)
|
||||
: wxDialog(parent, wxID_ANY, _("Dimensions Figure Mover"), wxDefaultPosition, wxSize(700, 300))
|
||||
{
|
||||
wxFileDialog openFileDialog(this, _("Load Dimensions Figure"), "", "",
|
||||
"Dimensions files (*.bin)|*.bin",
|
||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if (openFileDialog.ShowModal() != wxID_OK || openFileDialog.GetPath().empty())
|
||||
return;
|
||||
auto* sizer = new wxGridSizer(2, 5, 10, 10);
|
||||
|
||||
LoadMinifigPath(openFileDialog.GetPath(), pad, index);
|
||||
}
|
||||
void EmulatedUSBDeviceFrame::LoadMinifigPath(wxString path_name, uint8 pad, uint8 index)
|
||||
{
|
||||
std::unique_ptr<FileStream> dim_file(FileStream::openFile2(_utf8ToPath(path_name.utf8_string()), true));
|
||||
if (!dim_file)
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "Failed to open minifig file");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
std::array<std::optional<uint32>, 7> ids = parent->GetCurrentMinifigs();
|
||||
|
||||
std::array<uint8, 0x2D * 0x04> file_data;
|
||||
sizer->Add(AddMinifigSlot(2, 0, currentIndex, ids[0]), 1, wxALL, 5);
|
||||
sizer->Add(new wxStaticText(this, wxID_ANY, ""), 1, wxALL, 5);
|
||||
sizer->Add(AddMinifigSlot(1, 1, currentIndex, ids[1]), 1, wxALL, 5);
|
||||
sizer->Add(new wxStaticText(this, wxID_ANY, ""), 1, wxALL, 5);
|
||||
sizer->Add(AddMinifigSlot(3, 2, currentIndex, ids[2]), 1, wxALL, 5);
|
||||
|
||||
if (dim_file->readData(file_data.data(), file_data.size()) != file_data.size())
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "Failed to read minifig file data");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
sizer->Add(AddMinifigSlot(1, 3, currentIndex, ids[3]), 1, wxALL, 5);
|
||||
sizer->Add(AddMinifigSlot(1, 4, currentIndex, ids[4]), 1, wxALL, 5);
|
||||
sizer->Add(new wxStaticText(this, wxID_ANY, ""), 1, wxALL, 5);
|
||||
sizer->Add(AddMinifigSlot(3, 5, currentIndex, ids[5]), 1, wxALL, 5);
|
||||
sizer->Add(AddMinifigSlot(3, 6, currentIndex, ids[6]), 1, wxALL, 5);
|
||||
|
||||
ClearMinifig(pad, index);
|
||||
|
||||
uint32 id = nsyshid::g_dimensionstoypad.LoadFigure(file_data, std::move(dim_file), pad, index);
|
||||
m_dimension_slots[index]->ChangeValue(nsyshid::g_dimensionstoypad.FindFigure(id));
|
||||
}
|
||||
void EmulatedUSBDeviceFrame::ClearMinifig(uint8 pad, uint8 index)
|
||||
{
|
||||
nsyshid::g_dimensionstoypad.RemoveFigure(pad, index);
|
||||
m_dimension_slots[index]->ChangeValue("None");
|
||||
}
|
||||
void EmulatedUSBDeviceFrame::CreateMinifig(uint8 pad, uint8 index)
|
||||
{
|
||||
CreateDimensionFigureDialog create_dlg(this);
|
||||
create_dlg.ShowModal();
|
||||
if (create_dlg.GetReturnCode() == 1)
|
||||
{
|
||||
LoadMinifigPath(create_dlg.GetFilePath(), pad, index);
|
||||
}
|
||||
this->SetSizer(sizer);
|
||||
this->Centre(wxBOTH);
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadFigure(uint8 slot)
|
||||
wxBoxSizer* MoveDimensionFigureDialog::AddMinifigSlot(uint8 pad, uint8 index, uint8 currentIndex, std::optional<uint32> currentId)
|
||||
{
|
||||
wxFileDialog openFileDialog(this, _("Open Infinity Figure dump"), "", "",
|
||||
"BIN files (*.bin)|*.bin",
|
||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
if (openFileDialog.ShowModal() != wxID_OK || openFileDialog.GetPath().empty())
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "File Okay Error");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
auto* panel = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
LoadFigurePath(slot, openFileDialog.GetPath());
|
||||
auto* label = new wxStaticText(this, wxID_ANY, "None");
|
||||
if (currentId)
|
||||
label->SetLabel(nsyshid::g_dimensionstoypad.FindFigure(currentId.value()));
|
||||
|
||||
auto* moveButton = new wxButton(this, wxID_ANY, _("Move Here"));
|
||||
if (index == currentIndex)
|
||||
moveButton->SetLabelText("Pick up and Place");
|
||||
|
||||
moveButton->Bind(wxEVT_BUTTON, [pad, index, this](wxCommandEvent&) {
|
||||
m_newPad = pad;
|
||||
m_newIndex = index;
|
||||
this->EndModal(1);
|
||||
});
|
||||
|
||||
panel->Add(label, 1, wxALL, 5);
|
||||
panel->Add(moveButton, 1, wxALL, 5);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::LoadFigurePath(uint8 slot, wxString path)
|
||||
uint8 MoveDimensionFigureDialog::GetNewPad() const
|
||||
{
|
||||
std::unique_ptr<FileStream> infFile(FileStream::openFile2(_utf8ToPath(path.utf8_string()), true));
|
||||
if (!infFile)
|
||||
{
|
||||
wxMessageDialog errorMessage(this, "File Open Error");
|
||||
errorMessage.ShowModal();
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<uint8, nsyshid::INF_FIGURE_SIZE> fileData;
|
||||
if (infFile->readData(fileData.data(), fileData.size()) != fileData.size())
|
||||
{
|
||||
wxMessageDialog open_error(this, "Failed to read file! File was too small");
|
||||
open_error.ShowModal();
|
||||
return;
|
||||
}
|
||||
ClearFigure(slot);
|
||||
|
||||
uint32 number = nsyshid::g_infinitybase.LoadFigure(fileData, std::move(infFile), slot);
|
||||
m_infinitySlots[slot]->ChangeValue(nsyshid::g_infinitybase.FindFigure(number).second);
|
||||
return m_newPad;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::CreateFigure(uint8 slot)
|
||||
uint8 MoveDimensionFigureDialog::GetNewIndex() const
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Create Figure: {}", slot);
|
||||
CreateInfinityFigureDialog create_dlg(this, slot);
|
||||
create_dlg.ShowModal();
|
||||
if (create_dlg.GetReturnCode() == 1)
|
||||
{
|
||||
LoadFigurePath(slot, create_dlg.GetFilePath());
|
||||
}
|
||||
return m_newIndex;
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::ClearFigure(uint8 slot)
|
||||
std::array<std::optional<uint32>, 7> EmulatedUSBDeviceFrame::GetCurrentMinifigs()
|
||||
{
|
||||
m_infinitySlots[slot]->ChangeValue("None");
|
||||
nsyshid::g_infinitybase.RemoveFigure(slot);
|
||||
}
|
||||
|
||||
void EmulatedUSBDeviceFrame::UpdateSkylanderEdits()
|
||||
{
|
||||
for (auto i = 0; i < nsyshid::MAX_SKYLANDERS; i++)
|
||||
{
|
||||
std::string displayString;
|
||||
if (auto sd = m_skySlots[i])
|
||||
{
|
||||
auto [portalSlot, skyId, skyVar] = sd.value();
|
||||
displayString = nsyshid::g_skyportal.FindSkylander(skyId, skyVar);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayString = "None";
|
||||
}
|
||||
|
||||
m_skylanderSlots[i]->ChangeValue(displayString);
|
||||
}
|
||||
return m_dimSlots;
|
||||
}
|
||||
@ -17,10 +17,12 @@ class wxStaticBox;
|
||||
class wxString;
|
||||
class wxTextCtrl;
|
||||
|
||||
class EmulatedUSBDeviceFrame : public wxFrame {
|
||||
class EmulatedUSBDeviceFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
EmulatedUSBDeviceFrame(wxWindow* parent);
|
||||
~EmulatedUSBDeviceFrame();
|
||||
std::array<std::optional<uint32>, 7> GetCurrentMinifigs();
|
||||
|
||||
private:
|
||||
wxCheckBox* m_emulatePortal;
|
||||
@ -28,9 +30,9 @@ class EmulatedUSBDeviceFrame : public wxFrame {
|
||||
wxCheckBox* m_emulate_toypad;
|
||||
std::array<wxTextCtrl*, nsyshid::MAX_SKYLANDERS> m_skylanderSlots;
|
||||
std::array<wxTextCtrl*, nsyshid::MAX_FIGURES> m_infinitySlots;
|
||||
std::array<wxTextCtrl*, 7> m_dimension_slots;
|
||||
std::array<wxTextCtrl*, 7> m_dimensionSlots;
|
||||
std::array<std::optional<std::tuple<uint8, uint16, uint16>>, nsyshid::MAX_SKYLANDERS> m_skySlots;
|
||||
std::array<std::optional<std::tuple<uint8, uint8, uint8>>, 7> dim_slots;
|
||||
std::array<std::optional<uint32>, 7> m_dimSlots;
|
||||
|
||||
wxPanel* AddSkylanderPage(wxNotebook* notebook);
|
||||
wxPanel* AddInfinityPage(wxNotebook* notebook);
|
||||
@ -42,17 +44,20 @@ class EmulatedUSBDeviceFrame : public wxFrame {
|
||||
void LoadSkylanderPath(uint8 slot, wxString path);
|
||||
void CreateSkylander(uint8 slot);
|
||||
void ClearSkylander(uint8 slot);
|
||||
void LoadMinifigPath(wxString path_name, uint8 pad, uint8 index);
|
||||
void LoadMinifig(uint8 pad, uint8 index);
|
||||
void CreateMinifig(uint8 pad, uint8 index);
|
||||
void ClearMinifig(uint8 pad, uint8 index);
|
||||
void UpdateSkylanderEdits();
|
||||
void LoadFigure(uint8 slot);
|
||||
void LoadFigurePath(uint8 slot, wxString path);
|
||||
void CreateFigure(uint8 slot);
|
||||
void ClearFigure(uint8 slot);
|
||||
void UpdateSkylanderEdits();
|
||||
void LoadMinifig(uint8 pad, uint8 index);
|
||||
void LoadMinifigPath(wxString path_name, uint8 pad, uint8 index);
|
||||
void CreateMinifig(uint8 pad, uint8 index);
|
||||
void ClearMinifig(uint8 pad, uint8 index);
|
||||
void MoveMinifig(uint8 pad, uint8 index);
|
||||
};
|
||||
class CreateSkylanderDialog : public wxDialog {
|
||||
|
||||
class CreateSkylanderDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
explicit CreateSkylanderDialog(wxWindow* parent, uint8 slot);
|
||||
wxString GetFilePath() const;
|
||||
@ -61,7 +66,8 @@ class CreateSkylanderDialog : public wxDialog {
|
||||
wxString m_filePath;
|
||||
};
|
||||
|
||||
class CreateInfinityFigureDialog : public wxDialog {
|
||||
class CreateInfinityFigureDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
explicit CreateInfinityFigureDialog(wxWindow* parent, uint8 slot);
|
||||
wxString GetFilePath() const;
|
||||
@ -70,11 +76,27 @@ class CreateInfinityFigureDialog : public wxDialog {
|
||||
wxString m_filePath;
|
||||
};
|
||||
|
||||
class CreateDimensionFigureDialog : public wxDialog {
|
||||
class CreateDimensionFigureDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
explicit CreateDimensionFigureDialog(wxWindow* parent);
|
||||
wxString GetFilePath() const;
|
||||
|
||||
protected:
|
||||
wxString m_filePath;
|
||||
};
|
||||
|
||||
class MoveDimensionFigureDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
explicit MoveDimensionFigureDialog(EmulatedUSBDeviceFrame* parent, uint8 currentIndex);
|
||||
uint8 GetNewPad() const;
|
||||
uint8 GetNewIndex() const;
|
||||
|
||||
protected:
|
||||
uint8 m_newIndex = 0;
|
||||
uint8 m_newPad = 0;
|
||||
|
||||
private:
|
||||
wxBoxSizer* AddMinifigSlot(uint8 pad, uint8 index, uint8 oldIndex, std::optional<uint32> currentId);
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user