-#include "QtBoiMainWindow.h"
-
#include <QMenu>
#include <QMenuBar>
#include <QToolBar>
#include <QFileDialog>
#include <QPushButton>
#include <QColor>
+#include <QGroupBox>
+#include <QHBoxLayout>
#include <QVBoxLayout>
#include <iostream>
+#include "QtBoiMainWindow.h"
+
QtBoiMainWindow::QtBoiMainWindow(QWidget *parent)
:QMainWindow(parent), emuThread(0)
{
- screen_image = new QImage(160, 144, QImage::Format_Indexed8);
- screen_image->setNumColors(7);
+ screenImage = new QImage(160, 144, QImage::Format_Indexed8);
+ screenImage->setNumColors(7);
// gray palette
- //screen_image->setColor(6, qRgb(0,0,0));
- //screen_image->setColor(5, qRgb(42,42,42));
- //screen_image->setColor(4, qRgb(85,85,85));
- //screen_image->setColor(3, qRgb(127,127,127));
- //screen_image->setColor(2, qRgb(170,170,170));
- //screen_image->setColor(1, qRgb(212,212,212));
- //screen_image->setColor(0, qRgb(255,255,255));
+ //screenImage->setColor(6, qRgb(0,0,0));
+ //screenImage->setColor(5, qRgb(42,42,42));
+ //screenImage->setColor(4, qRgb(85,85,85));
+ //screenImage->setColor(3, qRgb(127,127,127));
+ //screenImage->setColor(2, qRgb(170,170,170));
+ //screenImage->setColor(1, qRgb(212,212,212));
+ //screenImage->setColor(0, qRgb(255,255,255));
// greenish palette
- screen_image->setColor(6, qRgb(64,64,64));
- screen_image->setColor(5, qRgb(82,82,53));
- screen_image->setColor(4, qRgb(101,101,42));
- screen_image->setColor(3, qRgb(120,120,31));
- screen_image->setColor(2, qRgb(139,139,21));
- screen_image->setColor(1, qRgb(166,166,10));
- screen_image->setColor(0, qRgb(192,192,0));
+ screenImage->setColor(6, qRgb(64,64,64));
+ screenImage->setColor(5, qRgb(82,82,53));
+ screenImage->setColor(4, qRgb(101,101,42));
+ screenImage->setColor(3, qRgb(120,120,31));
+ screenImage->setColor(2, qRgb(139,139,21));
+ screenImage->setColor(1, qRgb(166,166,10));
+ screenImage->setColor(0, qRgb(192,192,0));
emuThread = new QtBoiEmuThread(this);
emuThread->start();
createMenu();
createToolbar();
+ statusbar = statusBar();
+
connect(emulatorCont, SIGNAL(triggered()), emuThread, SLOT(cont()));
+ connect(emulatorCont, SIGNAL(triggered()), this, SLOT(onResume()));
connect(emulatorStop, SIGNAL(triggered()), emuThread, SLOT(stop()));
connect(emulatorPause, SIGNAL(triggered()), emuThread, SLOT(pause()));
connect(emulatorStep, SIGNAL(triggered()), emuThread, SLOT(step()));
connect(emuThread, SIGNAL(redraw(const uchar*)), this, SLOT(onRedraw(const uchar*)));
connect(emuThread, SIGNAL(emulationPaused()), this, SLOT(onPause()));
- resize(640,480);
+ resize(800,600);
centralWindow = new QWidget(this);
setCentralWidget(centralWindow);
- QVBoxLayout *vbox = new QVBoxLayout(centralWindow);
+ QHBoxLayout *topHBoxLayout = new QHBoxLayout;
+
+ QWidget *leftVBox = new QWidget(centralWindow);
+ QWidget *rightVBox = new QWidget(centralWindow);
+ QVBoxLayout *leftVBoxLayout = new QVBoxLayout;
+ QVBoxLayout *rightVBoxLayout = new QVBoxLayout;
+ leftVBox->setLayout(leftVBoxLayout);
+ rightVBox->setLayout(rightVBoxLayout);
screen = new QLabel(centralWindow);
screen->resize(320,288);
+ uchar buf[160*144];
+ memset(buf, 0, 160*144);
+ onRedraw(buf);
- status = new QLabel;
+ status = new QtBoiStatusWindow(centralWindow, &emuThread->gb);
status->setFont(QFont("courier"));
- vbox->addWidget(screen);
- vbox->addWidget(status);
+ topHBoxLayout->addWidget(leftVBox);
+ topHBoxLayout->addWidget(rightVBox);
+ leftVBoxLayout->addWidget(screen);
+ leftVBoxLayout->addWidget(status);
+
+ disassembly = new QtBoiDisassemblyWindow(centralWindow, &emuThread->gb);
+ disassembly->setOpenLinks(false);
+ disassembly->setFont(QFont("courier"));
+
+ rightVBoxLayout->addWidget(disassembly);
- centralWindow->setLayout(vbox);
+ centralWindow->setLayout(topHBoxLayout);
}
if (filename == "") return;
emuThread->loadROM(filename);
-
+ statusbar->showMessage(tr("Loaded ROM ")+filename);
}
void QtBoiMainWindow::onRedraw(const uchar *buffer)
{
- uchar *pixels = screen_image->bits();
+ uchar *pixels = screenImage->bits();
memcpy(pixels, buffer, 160*144);
- screen->setPixmap(QPixmap::fromImage(screen_image->scaled(320,288)));
+ screen->setPixmap(QPixmap::fromImage(screenImage->scaled(320,288)));
}
void QtBoiMainWindow::onPause()
{
status->setText(QString(emuThread->gb.status_string().c_str()));
+ disassembly->gotoPC();
+ status->update();
+ statusbar->showMessage(tr("Emulation paused", "Status bar emulation paused msg"));
}
+void QtBoiMainWindow::onResume()
+{
+ statusbar->showMessage(tr("Emulation running", "Status bar emulation running msg"));
+}
void QtBoiMainWindow::keyPressEvent(QKeyEvent *event)
{
--- /dev/null
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+#include "QtBoiStatusWindow.h"
+
+QtBoiStatusWindow::QtBoiStatusWindow(QWidget *parent, GameBoy *gb)
+ :gb(gb)
+{
+ setFocusPolicy(Qt::NoFocus);
+ setMinimumSize(200,200);
+}
+
+QtBoiStatusWindow::~QtBoiStatusWindow()
+{
+}
+
+void QtBoiStatusWindow::update()
+{
+ std::ostringstream str;
+
+ str << "<html><head><title>Status</title></head><body>";
+
+ str << "<table cellpadding=0 cellspacing=0><tr><td>";
+ // 8-bit regs table
+ str << "<table cellpadding=0 cellspacing=0>";
+ str << "<tr bgcolor=#c0ffc0><th colspan=\"2\">8-bit</th></tr>";
+ str << "<tr><td>A = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.A) << "</td></tr>";
+ str << "<tr><td>B = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.B) << "</td></tr>";
+ str << "<tr><td>C = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.C) << "</td></tr>";
+ str << "<tr><td>D = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.D) << "</td></tr>";
+ str << "<tr><td>E = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.E) << "</td></tr>";
+ str << "<tr><td>H = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.H) << "</td></tr>";
+ str << "<tr><td>L = </td><td>0x" << std::hex << std::setw(2) << std::setfill('0') << int(gb->regs.L) << "</td></tr>";
+ str << "</table>";
+ str << "</td><td width=20></td><td>";
+ // 16-bit regs table
+ str << "<table cellpadding=0 cellspacing=0>";
+ str << "<tr bgcolor=#c0ffc0><th colspan=\"2\">16-bit</th></tr>";
+ str << "<tr><td>BC = </td><td>0x" << std::hex << std::setw(4) << std::setfill('0') << int(gb->regs.BC) << "</td></tr>";
+ str << "<tr><td>DE = </td><td>0x" << std::hex << std::setw(4) << std::setfill('0') << int(gb->regs.DE) << "</td></tr>";
+ str << "<tr><td>HL = </td><td>0x" << std::hex << std::setw(4) << std::setfill('0') << int(gb->regs.HL) << "</td></tr>";
+ str << "<tr></tr>";
+ str << "<tr><td>SP = </td><td>0x" << std::hex << std::setw(4) << std::setfill('0') << int(gb->regs.SP) << "</td></tr>";
+ str << "<tr></tr>";
+ str << "<tr><td>PC = </td><td>0x" << std::hex << std::setw(4) << std::setfill('0') << int(gb->regs.PC) << "</td></tr>";
+ str << "</table>";
+ str << "</td><td width=20></td><td>";
+ // Flags & state table (TODO: Interpret IE and IF registers)
+ str << "<table cellpadding=0 cellspacing=0>";
+ str << "<tr bgcolor=#c0ffc0><th colspan=\"2\">Flags</th></tr>";
+ str << "<tr><td bgcolor=" << (gb->check_flag(GameBoy::ZERO_FLAG)? "#FF0000" : "#FFFFFF") << ">Z</td></tr>";
+ str << "<tr><td bgcolor=" << (gb->check_flag(GameBoy::ADD_SUB_FLAG)? "#FF0000" : "#FFFFFF") << ">N</td></tr>";
+ str << "<tr><td bgcolor=" << (gb->check_flag(GameBoy::HALF_CARRY_FLAG)? "#FF0000" : "#FFFFFF") << ">H</td></tr>";
+ str << "<tr><td bgcolor=" << (gb->check_flag(GameBoy::CARRY_FLAG)? "#FF0000" : "#FFFFFF") << ">C</td></tr>";
+ str << "<tr><td>IME = " << int(gb->IME) << "</td></tr>";
+ str << "<tr><td>IE = " << int(gb->memory.read(0xFFFF, GBMemory::DONT_WATCH)) << "</td></tr>";
+ str << "<tr><td>IF = " << int(gb->memory.read(0xFF0F, GBMemory::DONT_WATCH)) << "</td></tr>";
+ str << "</td></tr>";
+ str << "</table></body></html>";
+
+ setHtml(QString(str.str().c_str()));
+}
+
+