Implemented basic memory viewer

This commit is contained in:
Daniel Brunner
2018-12-17 21:58:48 +01:00
parent f480276243
commit 7a878f2946
4 changed files with 122 additions and 0 deletions

View File

@@ -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})

View File

@@ -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
View 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
View 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;
};