Expand Up
@@ -36,6 +36,8 @@
#include " DolphinQt/QtUtils/ModalMessageBox.h"
#include " DolphinQt/Settings.h"
using Type = MemoryViewWidget::Type;
MemoryWidget::MemoryWidget (QWidget* parent) : QDockWidget(parent)
{
setWindowTitle (tr (" Memory" ));
Expand Down
Expand Up
@@ -127,16 +129,16 @@ void MemoryWidget::CreateWidgets()
m_input_combo = new QComboBox;
m_input_combo->setMaxVisibleItems (20 );
// Order here determines combo list order.
m_input_combo->addItem (tr (" Hex Byte String" ), int (InputID::HEXSTR ));
m_input_combo->addItem (tr (" ASCII" ), int (InputID ::ASCII));
m_input_combo->addItem (tr (" Float" ), int (InputID::FLOAT ));
m_input_combo->addItem (tr (" Double" ), int (InputID::DOUBLE ));
m_input_combo->addItem (tr (" Unsigned 8" ), int (InputID::U8 ));
m_input_combo->addItem (tr (" Unsigned 16" ), int (InputID::U16 ));
m_input_combo->addItem (tr (" Unsigned 32" ), int (InputID::U32 ));
m_input_combo->addItem (tr (" Signed 8" ), int (InputID::S8 ));
m_input_combo->addItem (tr (" Signed 16" ), int (InputID::S16 ));
m_input_combo->addItem (tr (" Signed 32" ), int (InputID::S32 ));
m_input_combo->addItem (tr (" Hex Byte String" ), int (Type::HexString ));
m_input_combo->addItem (tr (" ASCII" ), int (Type ::ASCII));
m_input_combo->addItem (tr (" Float" ), int (Type:: Float32 ));
m_input_combo->addItem (tr (" Double" ), int (Type::Double ));
m_input_combo->addItem (tr (" Unsigned 8" ), int (Type::Unsigned8 ));
m_input_combo->addItem (tr (" Unsigned 16" ), int (Type::Unsigned16 ));
m_input_combo->addItem (tr (" Unsigned 32" ), int (Type::Unsigned32 ));
m_input_combo->addItem (tr (" Signed 8" ), int (Type::Signed8 ));
m_input_combo->addItem (tr (" Signed 16" ), int (Type::Signed16 ));
m_input_combo->addItem (tr (" Signed 32" ), int (Type::Signed32 ));
// Dump
auto * dump_group = new QGroupBox (tr (" Dump" ));
Expand Down
Expand Up
@@ -192,18 +194,18 @@ void MemoryWidget::CreateWidgets()
m_display_combo = new QComboBox;
m_display_combo->setMaxVisibleItems (20 );
m_display_combo->addItem (tr (" Hex 8" ), int (MemoryViewWidget:: Type::Hex8));
m_display_combo->addItem (tr (" Hex 16" ), int (MemoryViewWidget:: Type::Hex16));
m_display_combo->addItem (tr (" Hex 32" ), int (MemoryViewWidget:: Type::Hex32));
m_display_combo->addItem (tr (" Unsigned 8" ), int (MemoryViewWidget:: Type::Unsigned8));
m_display_combo->addItem (tr (" Unsigned 16" ), int (MemoryViewWidget:: Type::Unsigned16));
m_display_combo->addItem (tr (" Unsigned 32" ), int (MemoryViewWidget:: Type::Unsigned32));
m_display_combo->addItem (tr (" Signed 8" ), int (MemoryViewWidget:: Type::Signed8));
m_display_combo->addItem (tr (" Signed 16" ), int (MemoryViewWidget:: Type::Signed16));
m_display_combo->addItem (tr (" Signed 32" ), int (MemoryViewWidget:: Type::Signed32));
m_display_combo->addItem (tr (" ASCII" ), int (MemoryViewWidget:: Type::ASCII));
m_display_combo->addItem (tr (" Float" ), int (MemoryViewWidget:: Type::Float32 ));
m_display_combo->addItem (tr (" Double" ), int (MemoryViewWidget:: Type::Double));
m_display_combo->addItem (tr (" Hex 8" ), int (Type::Hex8));
m_display_combo->addItem (tr (" Hex 16" ), int (Type::Hex16));
m_display_combo->addItem (tr (" Hex 32" ), int (Type::Hex32));
m_display_combo->addItem (tr (" Unsigned 8" ), int (Type::Unsigned8));
m_display_combo->addItem (tr (" Unsigned 16" ), int (Type::Unsigned16));
m_display_combo->addItem (tr (" Unsigned 32" ), int (Type::Unsigned32));
m_display_combo->addItem (tr (" Signed 8" ), int (Type::Signed8));
m_display_combo->addItem (tr (" Signed 16" ), int (Type::Signed16));
m_display_combo->addItem (tr (" Signed 32" ), int (Type::Signed32));
m_display_combo->addItem (tr (" ASCII" ), int (Type::ASCII));
m_display_combo->addItem (tr (" Float" ), int (Type::Float32 ));
m_display_combo->addItem (tr (" Double" ), int (Type::Double));
m_align_combo = new QComboBox;
m_align_combo->addItem (tr (" Fixed Alignment" ));
Expand Down
Expand Up
@@ -435,12 +437,12 @@ void MemoryWidget::OnAddressSpaceChanged()
void MemoryWidget::OnDisplayChanged ()
{
const auto type = static_cast <MemoryViewWidget:: Type>(m_display_combo->currentData ().toInt ());
const auto type = static_cast <Type>(m_display_combo->currentData ().toInt ());
int bytes_per_row = m_row_length_combo->currentData ().toInt ();
int alignment;
bool dual_view = m_dual_check->isChecked ();
if (type == MemoryViewWidget:: Type::Double && bytes_per_row == 4 )
if (type == Type::Double && bytes_per_row == 4 )
bytes_per_row = 8 ;
// Alignment: First (fixed) option equals bytes per row. 'currentData' is correct for other
Expand Down
Expand Up
@@ -522,119 +524,40 @@ void MemoryWidget::ValidateAndPreviewInputValue()
{
m_data_preview->clear ();
QString input_text = m_data_edit->text ();
const auto combo_id = static_cast <InputID >(m_input_combo->currentData ().toInt ());
const auto input_type = static_cast <Type >(m_input_combo->currentData ().toInt ());
m_base_check->setEnabled (combo_id == InputID::U32 || combo_id == InputID::S32 ||
combo_id == InputID::U16 || combo_id == InputID::S16 ||
combo_id == InputID::U8 || combo_id == InputID::S8 );
m_base_check->setEnabled (input_type == Type::Unsigned32 || input_type == Type::Signed32 ||
input_type == Type::Unsigned16 || input_type == Type::Signed16 ||
input_type == Type::Unsigned8 || input_type == Type::Signed8 );
if (input_text.isEmpty ())
return ;
// Remove any spaces
if (combo_id != InputID ::ASCII)
if (input_type != Type ::ASCII)
input_text.remove (QLatin1Char (' ' ));
QFont font;
QPalette palette;
QString hex_string;
bool good = false ;
const int radix = (m_base_check->isChecked () && m_base_check->isEnabled ()) ? 16 : 0 ;
switch (combo_id)
{
case InputID::ASCII:
if (m_base_check->isChecked ())
{
good = true ;
const QByteArray bytes = input_text.toLatin1 ( );
hex_string = QString::fromLatin1 (bytes. toHex ());
break ;
if (input_text. startsWith ( QLatin1Char ( ' - ' )))
input_text.insert ( 1 , QStringLiteral ( " 0x " ) );
else
input_text. prepend ( QStringLiteral ( " 0x " )) ;
}
case InputID::FLOAT:
{
const float value_float = input_text.toFloat (&good);
if (good)
{
const u32 hex_out = Common::BitCast<u32>(value_float);
hex_string = QString::fromStdString (fmt::format (" {:08X}" , hex_out));
}
break ;
}
case InputID::DOUBLE:
{
const double value_double = input_text.toDouble (&good);
QFont font;
QPalette palette;
std::vector<u8> bytes = m_memory_view->ConvertTextToBytes (input_type, input_text);
if (good)
{
const u64 hex_out = Common::BitCast<u64>(value_double);
hex_string = QString::fromStdString (fmt::format (" {:016X}" , hex_out));
}
break ;
}
case InputID::S8:
{
const short value = input_text.toShort (&good, radix);
good &= std::numeric_limits<signed char >::min () <= value &&
value <= std::numeric_limits<signed char >::max ();
if (good)
hex_string = QString::fromStdString (fmt::sprintf (" %02hhX" , value));
break ;
}
case InputID::S16:
{
const short value = input_text.toShort (&good, radix);
if (good)
hex_string = QString::fromStdString (fmt::sprintf (" %04hX" , value));
break ;
}
case InputID::S32:
if (!bytes.empty ())
{
const int value_int = input_text.toInt (&good, radix);
if (good)
hex_string = QString::fromStdString (fmt::sprintf (" %08X" , value_int));
break ;
}
case InputID::U8:
{
const unsigned short value = input_text.toUShort (&good, radix);
good &= (value & 0xFF00 ) == 0 ;
if (good)
hex_string = QString::fromStdString (fmt::format (" {:02X}" , value));
break ;
}
case InputID::U16:
{
const unsigned short value = input_text.toUShort (&good, radix);
if (good)
hex_string = QString::fromStdString (fmt::format (" {:04X}" , value));
break ;
}
case InputID::U32:
{
const u32 value = input_text.toUInt (&good, radix);
if (good)
hex_string = QString::fromStdString (fmt::format (" {:08X}" , value));
break ;
}
case InputID::HEXSTR:
{
// Confirm it is only hex bytes
const QRegularExpression is_hex (QStringLiteral (" ^([0-9A-F]{2})*$" ),
QRegularExpression::CaseInsensitiveOption);
const QRegularExpressionMatch match = is_hex.match (input_text);
good = match.hasMatch ();
if (good)
{
const QByteArray hbytes = QByteArray::fromHex (input_text.toUtf8 ());
hex_string = QString::fromLatin1 (hbytes.toHex ());
}
break ;
}
}
QString hex_string;
std::string s;
if (good)
{
for (const u8 c : bytes)
s.append (fmt::format (" {:02x}" , c));
hex_string = QString::fromStdString (s);
int output_length = hex_string.length ();
if (output_length > 16 )
Expand Down
Expand Up
@@ -665,14 +588,14 @@ QByteArray MemoryWidget::GetInputData() const
if (m_data_preview->text ().isEmpty ())
return QByteArray ();
const auto combo_id = static_cast <InputID >(m_input_combo->currentData ().toInt ());
const auto input_type = static_cast <Type >(m_input_combo->currentData ().toInt ());
// Ascii might be truncated, pull from data edit box.
if (combo_id == InputID ::ASCII)
if (input_type == Type ::ASCII)
return QByteArray (m_data_edit->text ().toUtf8 ());
// If we are doing a large aray of hex bytes
if (combo_id == InputID::HEXSTR )
// If we are doing a large array of hex bytes
if (input_type == Type::HexString )
return QByteArray::fromHex (m_data_edit->text ().toUtf8 ());
// Data preview has exactly what we want to input, so pull it from there.
Expand Down
Expand Up
@@ -708,6 +631,13 @@ void MemoryWidget::OnSetValue()
}
AddressSpace::Accessors* accessors = AddressSpace::GetAccessors (m_memory_view->GetAddressSpace ());
u32 end_address = target_addr.address + static_cast <u32>(bytes.size ()) - 1 ;
if (!accessors->IsValidAddress (target_addr.address ) || !accessors->IsValidAddress (end_address))
{
ModalMessageBox::critical (this , tr (" Error" ), tr (" Target address range is invalid." ));
return ;
}
for (const char c : bytes)
accessors->WriteU8 (target_addr.address ++, static_cast <u8>(c));
Expand Down