Skip to content

Commit

Permalink
Add black and white mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Eeems committed Jan 12, 2024
1 parent afc0829 commit a3bd875
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/FilePicker.qml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Item {
Component {
id: fileDelegate
Clickable {
visible: fileName != "."
visible: fileName !== "."
text: fileName !== ".." ? fileName + (fileIsDir ? "/" : "") : "(Parent Directory)"
width: {
if(parent == undefined){
Expand Down
60 changes: 56 additions & 4 deletions src/gameboy.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,31 @@
#include <QPainter>
#include <QQuickPaintedItem>
#include <QSGSimpleRectNode>
#include <QGuiApplication>
#include <QScreen>
#include <QtQml/qqml.h>

#ifdef EPAPER
#include <epframebuffer.h>
#endif

#include "gameboythread.h"

class Gameboy : public QQuickPaintedItem {
Q_OBJECT
Q_PROPERTY(bool running READ running NOTIFY runningChanged REVISION 1)
Q_PROPERTY(bool paused READ paused NOTIFY pausedChanged REVISION 1)
Q_PROPERTY(bool slowedDown READ slowedDown NOTIFY slowedDownChanged REVISION 1)
Q_PROPERTY(bool greyscale READ isGreyscale WRITE setGreyscale NOTIFY greyscaleChanged REVISION 1)
Q_PROPERTY(QString homeFolder READ homeFolder CONSTANT REVISION 1)
Q_PROPERTY(QString romsFolder READ romsFolder CONSTANT REVISION 1)
Q_PROPERTY(QString romName READ romName NOTIFY romNameChanged REVISION 1)
QML_NAMED_ELEMENT(Gameboy)

public:
explicit Gameboy(QQuickItem* parent = nullptr)
: QQuickPaintedItem(parent)
: QQuickPaintedItem(parent),
greyscale(true)
{
image = nullptr;
connect(this, &Gameboy::runningChanged, [this](bool){
Expand All @@ -32,18 +40,20 @@ class Gameboy : public QQuickPaintedItem {
}
});
thread = new GameboyThread(this);
connect(thread, &GameboyThread::updated, this, [this]{ update(rect()); }, Qt::QueuedConnection);
connect(thread, &GameboyThread::updated, this, &Gameboy::updated, Qt::QueuedConnection);
connect(thread, &GameboyThread::started, this, [this]{ emit runningChanged(running()); }, Qt::QueuedConnection);
connect(thread, &GameboyThread::finished, this, [this]{ emit runningChanged(running()); }, Qt::QueuedConnection);
connect(thread, &GameboyThread::paused, this, [this]{ emit pausedChanged(true); }, Qt::QueuedConnection);
connect(thread, &GameboyThread::resumed, this, [this]{ emit pausedChanged(false); }, Qt::QueuedConnection);
connect(thread, &GameboyThread::slowedDownChanged, this, &Gameboy::slowedDownChanged, Qt::QueuedConnection);
connect(thread, &GameboyThread::romNameChanged, this, &Gameboy::romNameChanged, Qt::QueuedConnection);
#ifdef EPAPER
screenCentre = qGuiApp->primaryScreen()->geometry().center();
#endif
}
~Gameboy(){
delete thread;
}
QRect rect(){ return QRect(0, 0, width(), height()); }
bool running(){ return thread->isRunning(); }
bool paused(){ return thread->isPaused(); }
Q_REVISION(1) Q_INVOKABLE void loadROM(QString path){ thread->loadROM(path); }
Expand All @@ -63,21 +73,63 @@ class Gameboy : public QQuickPaintedItem {
}
bool slowedDown(){ return thread->slowedDown(); }
QString romName(){ return thread->romName(); }
bool isGreyscale(){ return greyscale; }
void setGreyscale(bool value){
greyscale = value;
emit greyscaleChanged(greyscale);
}

signals:
void runningChanged(bool);
void pausedChanged(bool);
void slowedDownChanged(bool);
void romNameChanged(QString);
void greyscaleChanged(bool);

protected slots:
void updated(){
QRect rect = boundingRect().toRect();
#ifdef EPAPER
rect.moveCenter(screenCentre);
QPainter painter(EPFrameBuffer::instance()->framebuffer());
painter.drawImage(rect, *image, image->rect());
painter.end();
EPFrameBuffer::sendUpdate(
rect,
greyscale ? EPFrameBuffer::Grayscale : EPFrameBuffer::Mono,
EPFrameBuffer::PartialUpdate
);
#else
update(rect);
#endif
}

protected:
void paint(QPainter* painter){
#ifndef EPAPER
if(image != nullptr){
painter->drawImage(rect(), *image, image->rect());
painter->drawImage(
boundingRect(),
greyscale ? *image : monoImage(),
image->rect()
);
}
#else
Q_UNUSED(painter)
#endif
}
#ifndef EPAPER
QImage monoImage(){
return image->convertToFormat(
QImage::Format_Mono,
Qt::MonoOnly | Qt::DiffuseDither | Qt::DiffuseAlphaDither | Qt::PreferDither
);
}
#endif

private:
QImage* image;
GameboyThread* thread;
QPoint screenCentre;
bool greyscale;
};
3 changes: 2 additions & 1 deletion src/gameboy.oxide
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"bin": "/opt/bin/gameboy",
"icon": "oxide:gameboy-48",
"splash": "oxide:splash:gameboy-48",
"type": "foreground"
"type": "foreground",
"flags": ["preload.qt"]
}
2 changes: 1 addition & 1 deletion src/gameboythread.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class GameboyThread : public QThread{
qDebug() << "Starting emulation";
pauseRequested = false;
int thirds = 0;
auto lastFrame = std::chrono::steady_clock::now();;
auto lastFrame = std::chrono::steady_clock::now();
while(!isInterruptionRequested()){
if(pauseRequested){
mutex.lock();
Expand Down
16 changes: 13 additions & 3 deletions src/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ ApplicationWindow {

ColumnLayout {
id: speedButtons
enabled: gameboy.running
anchors.bottom: {
if(gameboyContainer.bottom < buttonUp.top){
return gameboyContainer.bottom
Expand All @@ -130,7 +129,7 @@ ApplicationWindow {
}
anchors.right: gameboyContainer.left
anchors.rightMargin: 20
width: 150
width: 180
Clickable {
text: "1x"
onClicked: gameboyContainer.scale = 1
Expand Down Expand Up @@ -166,6 +165,14 @@ ApplicationWindow {
Layout.fillWidth: true
backgroundColor: "white"
}
Clickable {
text: gameboy.greyscale ? "Greyscale" : "B&W"
color: "black"
backgroundColor: gameboy.greyscale ? "grey" : "white"
onClicked: gameboy.greyscale = !gameboy.greyscale
border: 1
Layout.fillWidth: true
}
}

Rectangle {
Expand Down Expand Up @@ -203,7 +210,7 @@ ApplicationWindow {
}
anchors.left: gameboyContainer.right
anchors.leftMargin: 20
width: 150
width: speedButtons.width

Clickable {
id: stopButton
Expand Down Expand Up @@ -407,6 +414,9 @@ ApplicationWindow {
from: "*"; to: "picker"
SequentialAnimation {
ScriptAction { script: {
if(gameboy.running && !gameboy.paused){
gameboy.toggle();
}
console.log("Showing file picker");
picker.currentIndex = -1;
picker.forceActiveFocus();
Expand Down

0 comments on commit a3bd875

Please sign in to comment.