Implemented basic memory viewer
This commit is contained in:
@@ -5,10 +5,12 @@ find_package(Qt5Multimedia CONFIG REQUIRED)
|
||||
find_package(Qt5Gamepad CONFIG REQUIRED)
|
||||
|
||||
set(HEADERS
|
||||
memorymodel.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
memorymodel.cpp
|
||||
)
|
||||
|
||||
add_executable(nesemu ${HEADERS} ${SOURCES})
|
||||
|
@@ -5,6 +5,8 @@
|
||||
#include <QDataStream>
|
||||
#include <QImage>
|
||||
#include <QFile>
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
#include <QTimer>
|
||||
#include <QAudioFormat>
|
||||
#include <QAudioDeviceInfo>
|
||||
@@ -22,6 +24,9 @@
|
||||
#include "nesemulator.h"
|
||||
#include "emusettings.h"
|
||||
|
||||
// local includes
|
||||
#include "memorymodel.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
@@ -103,6 +108,23 @@ int main(int argc, char **argv)
|
||||
dataStream << frame;
|
||||
});
|
||||
|
||||
MemoryModel model(emulator);
|
||||
QObject::connect(&emulator.ppu(), &Ppu::frameFinished, &model, &MemoryModel::refresh);
|
||||
|
||||
QTableView tableView;
|
||||
{
|
||||
QHeaderView *horizontalHeader = tableView.horizontalHeader();
|
||||
horizontalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
||||
horizontalHeader->setDefaultSectionSize(0);
|
||||
}
|
||||
{
|
||||
QHeaderView *verticalHeader = tableView.verticalHeader();
|
||||
verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
|
||||
verticalHeader->setDefaultSectionSize(0);
|
||||
}
|
||||
tableView.setModel(&model);
|
||||
tableView.show();
|
||||
|
||||
QTimer timer;
|
||||
QObject::connect(&timer, &QTimer::timeout, &emulator, &NesEmulator::emuClockFrame);
|
||||
timer.setInterval(EmuSettings::emuTimeFramePeriod);
|
||||
|
64
nesemu/memorymodel.cpp
Normal file
64
nesemu/memorymodel.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "memorymodel.h"
|
||||
|
||||
// nescorelib includes
|
||||
#include "nesemulator.h"
|
||||
|
||||
MemoryModel::MemoryModel(NesEmulator &emu, QObject *parent) :
|
||||
QAbstractTableModel(parent),
|
||||
m_emu(emu),
|
||||
m_wram(emu.memory().wram())
|
||||
{
|
||||
}
|
||||
|
||||
int MemoryModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return (END_ADDR - START_ADDR) / VALUES_PER_ROW;
|
||||
}
|
||||
|
||||
int MemoryModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return VALUES_PER_ROW;
|
||||
}
|
||||
|
||||
QVariant MemoryModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
const quint16 address = START_ADDR + (index.row() * VALUES_PER_ROW) + index.column();
|
||||
const auto arrIndex = Memory::wramAddressToIndex(address);
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return QString("%0").arg(m_wram[arrIndex], 2, 16, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant MemoryModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
if(orientation == Qt::Horizontal)
|
||||
return QString::number(section, 16);
|
||||
else
|
||||
return QString("0x%0").arg(START_ADDR + (section * VALUES_PER_ROW), 4, 16, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void MemoryModel::refresh()
|
||||
{
|
||||
const auto &newWram = m_emu.memory().wram();
|
||||
|
||||
for(quint16 i = START_ADDR; i < END_ADDR; i++)
|
||||
{
|
||||
const auto arrIndex = Memory::wramAddressToIndex(i);
|
||||
if(m_wram[arrIndex] != newWram[arrIndex])
|
||||
{
|
||||
QModelIndex index = createIndex((i-START_ADDR)/VALUES_PER_ROW, (i-START_ADDR)%VALUES_PER_ROW);
|
||||
Q_EMIT dataChanged(index, index, QVector<int> { Qt::DisplayRole });
|
||||
m_wram[arrIndex] = newWram[arrIndex];
|
||||
}
|
||||
}
|
||||
}
|
34
nesemu/memorymodel.h
Normal file
34
nesemu/memorymodel.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
// Qt includes
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
// system includes
|
||||
#include <array>
|
||||
|
||||
// forward declarations
|
||||
class NesEmulator;
|
||||
|
||||
class MemoryModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MemoryModel(NesEmulator &emu, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
|
||||
|
||||
public Q_SLOTS:
|
||||
void refresh();
|
||||
|
||||
private:
|
||||
static constexpr quint16 START_ADDR = 0x0000;
|
||||
static constexpr quint16 END_ADDR = 0x2000;
|
||||
static constexpr quint16 VALUES_PER_ROW = 16;
|
||||
|
||||
NesEmulator &m_emu;
|
||||
std::array<quint8, 0x0800> m_wram;
|
||||
};
|
Reference in New Issue
Block a user