From: slack Date: Thu, 12 Mar 2009 02:40:14 +0000 (+0100) Subject: QTBoi WIP, first steps X-Git-Url: http://slack.codemaniacs.com/git/?a=commitdiff_plain;h=e4022e5e5e85bbdadac04fba9257c141aea0e002;p=wenboi.git QTBoi WIP, first steps --- diff --git a/qtboi/CMakeLists.txt b/qtboi/CMakeLists.txt new file mode 100644 index 0000000..b6c045c --- /dev/null +++ b/qtboi/CMakeLists.txt @@ -0,0 +1,19 @@ +FIND_PACKAGE(Qt4 REQUIRED) +INCLUDE( ${QT_USE_FILE} ) + +SET(QTBOI_MOC_HDRS + QtBoiMainWindow.h + QtBoiEmuThread.h +) + +SET(QTBOI_SOURCES + qtboi.cc + QtBoiMainWindow.cc + QtBoiEmuThread.cc +) + +QT4_WRAP_CPP(QTBOI_MOC_SRCS ${QTBOI_MOC_HDRS}) +ADD_EXECUTABLE(qtboi ${QTBOI_SOURCES} ${QTBOI_MOC_SRCS}) + +TARGET_LINK_LIBRARIES(qtboi ${QT_LIBRARIES} wenboicore) + diff --git a/qtboi/QtBoiEmuThread.cc b/qtboi/QtBoiEmuThread.cc new file mode 100644 index 0000000..260ba91 --- /dev/null +++ b/qtboi/QtBoiEmuThread.cc @@ -0,0 +1,126 @@ +#include "QtBoiEmuThread.h" +#include + +using std::cout; +using std::endl; + +void print_run_result(GameBoy &gb, int status) +{ + + if (status == GameBoy::BREAKPOINT) + { + cout << "Breakpoint reached " << endl; + cout << gb.status_string() << endl; + } + else if (status == GameBoy::WATCHPOINT) + { + cout << "Watchpoint reached" << endl; + + cout << "Watchpoint 0x" << std::hex << std::setw(4) << std::setfill('0') << + int(gb.memory.watchpoint_addr) << " hit at 0x" << gb.regs.PC; + + // FIXME: Move/expose this things somewhere + if (gb.memory.watchpoint_newvalue == 0xFFFF) + { + cout << " (READ)" << endl << + "value = " << int(gb.memory.watchpoint_oldvalue) << endl; + } + else + { + cout << " (WRITE)" << endl << + "old = " << int(gb.memory.watchpoint_oldvalue) << + " new = " << int(gb.memory.watchpoint_newvalue) << endl; + } + } + else + { + cout << "run returned with status " << status << endl; + cout << gb.status_string() << endl; + } +} + + +QtBoiEmuThread::QtBoiEmuThread(QObject *parent, QString romName) + :QThread(parent) +{ + gb = new GameBoy(romName.toStdString()); + isPaused = true; + quitRequested = false; + frameCount = 0; +} + +QtBoiEmuThread::~QtBoiEmuThread() +{ + stop(); + wait(); + delete gb; +} + +void QtBoiEmuThread::toggle_paused() +{ + isPaused = !isPaused; +} + +void QtBoiEmuThread::cont() +{ + status = GameBoy::NORMAL; + runningMode = RUN; + isPaused = false; +} + +void QtBoiEmuThread::stop() +{ + quitRequested = true; + isPaused = true; +} + +void QtBoiEmuThread::step() +{ + runningMode = STEP; + isPaused = false; +} + +void QtBoiEmuThread::run() +{ + cout << "Running! \\o/" << endl; + while(!quitRequested) + { + if(isPaused) + usleep(100); + else { + switch (runningMode) + { + case RUN: + while (!isPaused && + (status == GameBoy::NORMAL || status == GameBoy::WAIT)) + { + status = gb->run_cycle(); + if (gb->video.get_frames_rendered() > frameCount) + { + frameCount = gb->video.get_frames_rendered(); + emit redraw(gb->video.get_screen_buffer()); + } + } + break; + case STEP: + do + { + status = gb->run_cycle(); + if (gb->video.get_frames_rendered() > frameCount) + { + frameCount = gb->video.get_frames_rendered(); + emit redraw(gb->video.get_screen_buffer()); + } + } while(status == GameBoy::WAIT); // do nothing + + break; + } + + print_run_result(*gb, status); + isPaused=true; + emit emulationPaused(); + } + } +} + + diff --git a/qtboi/QtBoiEmuThread.h b/qtboi/QtBoiEmuThread.h new file mode 100644 index 0000000..cb5e804 --- /dev/null +++ b/qtboi/QtBoiEmuThread.h @@ -0,0 +1,41 @@ +#ifndef QTBOIEMUTHREAD_H +#define QTBOIEMUTHREAD_H + +#include +#include +#include "../core/GameBoy.h" + +class QtBoiEmuThread: public QThread +{ + Q_OBJECT + + public: + GameBoy::run_status status; + bool isPaused; + int frameCount; + QtBoiEmuThread(QObject *parent, QString romName); + ~QtBoiEmuThread(); + + public slots: + void run(); + void stop(); + void toggle_paused(); + void cont(); + void step(); + + signals: + void emulationPaused(); + void redraw(const uchar *buffer); + + private: + enum RunningMode { RUN, STEP }; + GameBoy *gb; + RunningMode runningMode; + bool quitRequested; +}; + + + +#endif + + diff --git a/qtboi/QtBoiMainWindow.cc b/qtboi/QtBoiMainWindow.cc new file mode 100644 index 0000000..d54e075 --- /dev/null +++ b/qtboi/QtBoiMainWindow.cc @@ -0,0 +1,104 @@ +#include "QtBoiMainWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QtBoiMainWindow::QtBoiMainWindow(QWidget *parent) + :QMainWindow(parent), emuThread(0) +{ + screen = new QImage(160, 144, QImage::Format_Indexed8); + screen->setNumColors(8); + screen->setColor(7, qRgb(0,0,0)); + screen->setColor(6, qRgb(36,36,36)); + screen->setColor(5, qRgb(73,73,73)); + screen->setColor(4, qRgb(109,109,109)); + screen->setColor(3, qRgb(146,146,146)); + screen->setColor(2, qRgb(182,182,182)); + screen->setColor(1, qRgb(219,219,219)); + screen->setColor(0, qRgb(255,255,255)); + + createMenu(); + resize(640,480); + centralWindow = new QLabel(this); + setCentralWidget(centralWindow); + + +} + +QtBoiMainWindow::~QtBoiMainWindow() +{ + if (emuThread) { + emuThread->stop(); + delete emuThread; + } +} + +void QtBoiMainWindow::createMenu() +{ + loadROM = new QAction("&Load ROM...", this); + quit = new QAction("&Quit", this); + emulatorPause = new QAction("&Toggle pause", this); + emulatorCont = new QAction("&Go", this); + emulatorStop = new QAction("&Stop", this); + emulatorStep = new QAction("St&ep", this); + + QMenu *file; + file = menuBar()->addMenu("&File"); + file->addAction(loadROM); + file->addAction(quit); + + QMenu *emulator; + emulator = menuBar()->addMenu("&Emulator"); + emulator->addAction(emulatorCont); + emulator->addAction(emulatorPause); + emulator->addAction(emulatorStop); + + QMenu *debug; + debug = menuBar()->addMenu("&Debug"); + debug->addAction(emulatorStep); + + connect(quit, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(loadROM, SIGNAL(triggered()), this, SLOT(onLoadROM())); +} + +void QtBoiMainWindow::onLoadROM() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Load ROM"), "../roms", tr("GameBoy ROMs (*.gb *.gbc)")); + if (filename == "") return; + + std::cout << filename.toStdString() << std::endl; + + if (emuThread) { + emuThread->stop(); + emuThread->wait(); + delete emuThread; + } + + emuThread = new QtBoiEmuThread(0, filename); + + connect(emulatorCont, SIGNAL(triggered()), emuThread, SLOT(cont()), Qt::DirectConnection); + connect(emulatorStop, SIGNAL(triggered()), emuThread, SLOT(stop()), Qt::DirectConnection); + connect(emulatorPause, SIGNAL(triggered()), emuThread, SLOT(toggle_paused()), Qt::DirectConnection); + connect(emulatorStep, SIGNAL(triggered()), emuThread, SLOT(step()), Qt::DirectConnection); + connect(emuThread, SIGNAL(redraw(const uchar*)), this, SLOT(onRedraw(const uchar*))); + + emuThread->start(); +} + +void QtBoiMainWindow::onRedraw(const uchar *buffer) +{ + uchar *pixels = screen->bits(); + memcpy(pixels, buffer, 160*144); + //centralWindow->setPixmap(QPixmap::fromImage(screen->scaled(320,288))); + centralWindow->setPixmap(QPixmap::fromImage(*screen)); +} + + + + diff --git a/qtboi/QtBoiMainWindow.h b/qtboi/QtBoiMainWindow.h new file mode 100644 index 0000000..8794aea --- /dev/null +++ b/qtboi/QtBoiMainWindow.h @@ -0,0 +1,41 @@ +#ifndef QTBOIMAINWINDOW_H +#define QTBOIMAINWINDOW_H + +#include +#include +#include +#include +#include +#include "QtBoiEmuThread.h" + +class QtBoiMainWindow: public QMainWindow +{ + Q_OBJECT + + public: + QtBoiMainWindow(QWidget *parent=0); + ~QtBoiMainWindow(); + + public slots: + void onLoadROM(); + void onRedraw(const uchar *buffer); + + private: + void createMenu(); + QtBoiEmuThread *emuThread; + + QLabel *centralWindow; + QImage *screen; + + QAction *loadROM; + QAction *quit; + QAction *emulatorPause; + QAction *emulatorCont; + QAction *emulatorStop; + QAction *emulatorStep; +}; + + +#endif + + diff --git a/qtboi/qtboi.cc b/qtboi/qtboi.cc new file mode 100644 index 0000000..0cf133f --- /dev/null +++ b/qtboi/qtboi.cc @@ -0,0 +1,11 @@ +#include +#include "QtBoiMainWindow.h" +#include "../core/GameBoy.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QtBoiMainWindow mainwindow; + mainwindow.show(); + return app.exec(); +} diff --git a/qtboi/qtboi.h b/qtboi/qtboi.h new file mode 100644 index 0000000..e69de29