1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-21 18:22:33 +01:00

sys_usbd: Better Dimensions Move Handling

This commit is contained in:
Joshua de Reeper 2024-11-03 17:11:40 +00:00 committed by Megamouse
parent 6d766ccbb5
commit 73cee9a43d
3 changed files with 67 additions and 22 deletions

View File

@ -259,9 +259,9 @@ dimensions_figure& dimensions_toypad::get_figure_by_index(u8 index)
void dimensions_toypad::random_uid(u8* uid_buffer)
{
uid_buffer[0] = 0x04;
uid_buffer[6] = 0x80;
uid_buffer[7] = 0x80;
for (u8 i = 1; i < 6; i++)
for (u8 i = 1; i < 7; i++)
{
u8 random = rand() % 255;
uid_buffer[i] = random;
@ -384,10 +384,10 @@ u32 dimensions_toypad::load_figure(const std::array<u8, 0x2D * 0x04>& buf, fs::f
std::memcpy(figure.data.data(), buf.data(), buf.size());
// When a figure is added to the toypad, respond to the game with the pad they were added to, their index,
// the direction (0x00 in byte 6 for added) and their UID
std::array<u8, 32> figure_change_response = {0x56, 0x0b, figure.pad, 0x00, figure.index, 0x00};
std::memcpy(&figure_change_response[6], buf.data(), 7);
std::array<u8, 32> figure_change_response = {0x56, 0x0b, figure.pad, 0x00, figure.index, 0x00,
buf[0], buf[1], buf[2], buf[4], buf[5], buf[6], buf[7]};
figure_change_response[13] = generate_checksum(figure_change_response, 13);
m_figure_added_removed_responses.push(figure_change_response);
m_figure_added_removed_responses.push(std::move(figure_change_response));
if (lock)
{
@ -396,7 +396,7 @@ u32 dimensions_toypad::load_figure(const std::array<u8, 0x2D * 0x04>& buf, fs::f
return id;
}
bool dimensions_toypad::remove_figure(u8 pad, u8 index, bool save, bool lock)
bool dimensions_toypad::remove_figure(u8 pad, u8 index, bool full_remove, bool lock)
{
dimensions_figure& figure = get_figure_by_index(index);
if (figure.index == 255)
@ -411,17 +411,20 @@ bool dimensions_toypad::remove_figure(u8 pad, u8 index, bool save, bool lock)
// 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<u8, 32> figure_change_response = {0x56, 0x0b, pad, 0x00, figure.index, 0x01};
std::memcpy(&figure_change_response[6], figure.data.data(), 7);
if (save)
if (full_remove)
{
std::array<u8, 32> figure_change_response = {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]};
figure_change_response[13] = generate_checksum(figure_change_response, 13);
m_figure_added_removed_responses.push(std::move(figure_change_response));
figure.save();
figure.dim_file.close();
}
figure.index = 255;
figure.pad = 255;
figure_change_response[13] = generate_checksum(figure_change_response, 13);
m_figure_added_removed_responses.push(figure_change_response);
figure.id = 0;
if (lock)
{
@ -430,23 +433,56 @@ bool dimensions_toypad::remove_figure(u8 pad, u8 index, bool save, bool lock)
return true;
}
bool dimensions_toypad::move_figure(u8 pad, u8 index, u8 old_pad, u8 old_index)
bool dimensions_toypad::temp_remove(u8 index)
{
std::lock_guard lock(m_dimensions_mutex);
const dimensions_figure& figure = get_figure_by_index(index);
if (figure.index == 255)
return false;
// Send a response to the game that the figure has been "Picked up" from existing slot,
// until either the movement is cancelled, or user chooses a space to move to
std::array<u8, 32> figure_change_response = {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_change_response[13] = generate_checksum(figure_change_response, 13);
m_figure_added_removed_responses.push(std::move(figure_change_response));
return true;
}
bool dimensions_toypad::cancel_remove(u8 index)
{
std::lock_guard lock(m_dimensions_mutex);
dimensions_figure& figure = get_figure_by_index(index);
if (figure.index == 255)
return false;
// Cancel the previous movement of the figure
std::array<u8, 32> figure_change_response = {0x56, 0x0b, figure.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]};
figure_change_response[13] = generate_checksum(figure_change_response, 13);
m_figure_added_removed_responses.push(std::move(figure_change_response));
return true;
}
bool dimensions_toypad::move_figure(u8 pad, u8 index, u8 old_pad, u8 old_index)
{
if (old_index == index)
{
// Don't bother removing and loading again, just send response to the game
const dimensions_figure& figure = get_figure_by_index(old_index);
std::array<u8, 32> figure_remove_response = {0x56, 0x0b, pad, 0x00, figure.index, 0x01};
figure_remove_response[13] = generate_checksum(figure_remove_response, 13);
std::array<u8, 32> figure_add_response = {0x56, 0x0b, pad, 0x00, figure.index, 0x00};
figure_add_response[13] = generate_checksum(figure_add_response, 13);
m_figure_added_removed_responses.push(std::move(figure_remove_response));
m_figure_added_removed_responses.push(std::move(figure_add_response));
cancel_remove(index);
return true;
}
std::lock_guard lock(m_dimensions_mutex);
// 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
remove_figure(pad, index, true, false);
@ -465,14 +501,16 @@ bool dimensions_toypad::move_figure(u8 pad, u8 index, u8 old_pad, u8 old_index)
bool dimensions_toypad::create_blank_character(std::array<u8, 0x2D * 0x04>& buf, u16 id)
{
random_uid(buf.data());
buf[7] = id & 0xFF;
std::array<u8, 7> uid = {buf[0], buf[1], buf[2], buf[4], buf[5], buf[6], buf[7]};
buf[3] = id & 0xFF;
// Only characters are created with their ID encrypted and stored in pages 36 and 37,
// as well as a password stored in page 43. Blank tags have their information populated
// by the game when it calls the write_block command.
if (id != 0)
{
// LEGO Dimensions figures use NTAG213 tag types, and the UID for these is stored in
// bytes 0, 1, 2, 4, 5, 6 and 7 (out of 180 bytes)
std::array<u8, 7> uid = {buf[0], buf[1], buf[2], buf[4], buf[5], buf[6], buf[7]};
const std::array<u8, 16> figure_key = generate_figure_key(buf);
std::array<u8, 8> value_to_encrypt = {};

View File

@ -30,7 +30,9 @@ public:
void get_model(const u8* buf, u8 sequence, std::array<u8, 32>& reply_buf);
std::optional<std::array<u8, 32>> pop_added_removed_response();
bool remove_figure(u8 pad, u8 index, bool save, bool lock);
bool remove_figure(u8 pad, u8 index, bool full_remove, bool lock);
bool temp_remove(u8 index);
bool cancel_remove(u8 index);
u32 load_figure(const std::array<u8, 0x2D * 0x04>& buf, fs::file in_file, u8 pad, u8 index, bool lock);
bool move_figure(u8 pad, u8 index, u8 old_pad, u8 old_index);
static bool create_blank_character(std::array<u8, 0x2D * 0x04>& buf, u16 id);

View File

@ -724,6 +724,7 @@ void dimensions_dialog::move_figure(u8 pad, u8 index)
{
ensure(index < figure_slots.size());
minifig_move_dialog move_dlg(this, index);
g_dimensionstoypad.temp_remove(index);
if (move_dlg.exec() == Accepted)
{
g_dimensionstoypad.move_figure(move_dlg.get_new_pad(), move_dlg.get_new_index(), pad, index);
@ -735,6 +736,10 @@ void dimensions_dialog::move_figure(u8 pad, u8 index)
m_edit_figures[index]->setText(tr("None"));
}
}
else
{
g_dimensionstoypad.cancel_remove(index);
}
}
void dimensions_dialog::load_figure_path(u8 pad, u8 index, const QString& path)