mirror of
https://github.com/Treeki/WindEmu.git
synced 2025-08-28 22:00:23 +00:00
initial commit
This commit is contained in:
51
WindQt/WindQt.pro
Normal file
51
WindQt/WindQt.pro
Normal file
@@ -0,0 +1,51 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-12-18T16:17:36
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui widgets
|
||||
|
||||
TARGET = WindQt
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../WindCore/release/ -lWindCore
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../WindCore/debug/ -lWindCore
|
||||
else:unix: LIBS += -L$$OUT_PWD/../WindCore/ -lWindCore
|
||||
|
||||
INCLUDEPATH += $$PWD/../WindCore
|
||||
DEPENDPATH += $$PWD/../WindCore
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../WindCore/release/libWindCore.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../WindCore/debug/libWindCore.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../WindCore/release/WindCore.lib
|
||||
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../WindCore/debug/WindCore.lib
|
||||
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../WindCore/libWindCore.a
|
11
WindQt/main.cpp
Normal file
11
WindQt/main.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
171
WindQt/mainwindow.cpp
Normal file
171
WindQt/mainwindow.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "../WindCore/wind.h"
|
||||
#include <QTimer>
|
||||
#include <QKeyEvent>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
emu = new Emu;
|
||||
emu->loadROM("/Users/ash/src/psion/Sys$rom.bin");
|
||||
|
||||
timer = new QTimer(this);
|
||||
timer->start(1000/64);
|
||||
connect(timer, SIGNAL(timeout()), SLOT(execTimer()));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::execTimer()
|
||||
{
|
||||
emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED / 64));
|
||||
ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles()));
|
||||
updateScreen();
|
||||
}
|
||||
|
||||
void MainWindow::on_stepButton_clicked()
|
||||
{
|
||||
emu->executeUntil(emu->currentCycles() + (CLOCK_SPEED * 2));
|
||||
ui->cycleCounter->setText(QString("Cycles: %1").arg(emu->currentCycles()));
|
||||
updateScreen();
|
||||
}
|
||||
|
||||
void MainWindow::updateScreen()
|
||||
{
|
||||
const uint8_t *lcdBuf = emu->getLCDBuffer();
|
||||
if (lcdBuf) {
|
||||
QImage img(640, 240, QImage::Format_Grayscale8);
|
||||
|
||||
// fetch palette
|
||||
int bpp = 1 << (lcdBuf[1] >> 4);
|
||||
int ppb = 8 / bpp;
|
||||
uint16_t palette[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
palette[i] = lcdBuf[i*2] | ((lcdBuf[i*2+1] << 8) & 0xF00);
|
||||
|
||||
// build our image out
|
||||
int lineWidth = (img.width() * bpp) / 8;
|
||||
for (int y = 0; y < img.height(); y++) {
|
||||
uint8_t *scanline = img.scanLine(y);
|
||||
int lineOffs = 0x20 + (lineWidth * y);
|
||||
for (int x = 0; x < img.width(); x++) {
|
||||
uint8_t byte = lcdBuf[lineOffs + (x / ppb)];
|
||||
int shift = (x & (ppb - 1)) * bpp;
|
||||
int mask = (bpp << 1) - 1;
|
||||
int palIdx = (byte >> shift) & mask;
|
||||
int palValue = palette[palIdx];
|
||||
|
||||
if (bpp <= 1)
|
||||
palValue |= (palValue << 1);
|
||||
if (bpp <= 2)
|
||||
palValue |= (palValue << 2);
|
||||
if (bpp <= 4)
|
||||
palValue |= (palValue << 4);
|
||||
scanline[x] = palValue ^ 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
ui->screen->setPixmap(QPixmap::fromImage(std::move(img)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int resolveKey(int key) {
|
||||
switch (key) {
|
||||
case Qt::Key_6: return 0;
|
||||
case Qt::Key_5: return 1;
|
||||
case Qt::Key_4: return 2;
|
||||
case Qt::Key_3: return 3;
|
||||
case Qt::Key_2: return 4;
|
||||
case Qt::Key_1: return 5;
|
||||
// missing 6: F13/rec
|
||||
|
||||
case Qt::Key_Apostrophe: return 7;
|
||||
case Qt::Key_Backspace: return 8;
|
||||
case Qt::Key_0: return 9;
|
||||
case Qt::Key_9: return 10;
|
||||
case Qt::Key_8: return 11;
|
||||
case Qt::Key_7: return 12;
|
||||
// missing 13: F15/play
|
||||
|
||||
case Qt::Key_Y: return 14;
|
||||
case Qt::Key_T: return 15;
|
||||
case Qt::Key_R: return 16;
|
||||
case Qt::Key_E: return 17;
|
||||
case Qt::Key_W: return 18;
|
||||
case Qt::Key_Q: return 19;
|
||||
case Qt::Key_Escape: return 20;
|
||||
|
||||
case Qt::Key_Enter: return 21;
|
||||
case Qt::Key_Return: return 21;
|
||||
case Qt::Key_L: return 22;
|
||||
case Qt::Key_P: return 23;
|
||||
case Qt::Key_O: return 24;
|
||||
case Qt::Key_I: return 25;
|
||||
case Qt::Key_U: return 26;
|
||||
case Qt::Key_Alt: return 27; // actually Menu
|
||||
|
||||
case Qt::Key_G: return 28;
|
||||
case Qt::Key_F: return 29;
|
||||
case Qt::Key_D: return 30;
|
||||
case Qt::Key_S: return 31;
|
||||
case Qt::Key_A: return 32;
|
||||
case Qt::Key_Tab: return 33;
|
||||
#ifdef Q_OS_MAC
|
||||
case Qt::Key_Meta: return 34; // Control -> Control
|
||||
#else
|
||||
case Qt::Key_Control: return 34; // Control -> Control
|
||||
#endif
|
||||
|
||||
case Qt::Key_Down: return 35;
|
||||
case Qt::Key_Period: return 36;
|
||||
case Qt::Key_M: return 37;
|
||||
case Qt::Key_K: return 38;
|
||||
case Qt::Key_J: return 39;
|
||||
case Qt::Key_H: return 40;
|
||||
#ifdef Q_OS_MAC
|
||||
case Qt::Key_Control: return 41; // Command -> Fn
|
||||
#else
|
||||
case Qt::Key_Meta: return 41; // Super -> Fn
|
||||
#endif
|
||||
|
||||
case Qt::Key_N: return 42;
|
||||
case Qt::Key_B: return 43;
|
||||
case Qt::Key_V: return 44;
|
||||
case Qt::Key_C: return 45;
|
||||
case Qt::Key_X: return 46;
|
||||
case Qt::Key_Z: return 47;
|
||||
case Qt::Key_Shift: return 48;
|
||||
|
||||
case Qt::Key_Right: return 49;
|
||||
case Qt::Key_Left: return 50;
|
||||
case Qt::Key_Comma: return 51;
|
||||
case Qt::Key_Up: return 52;
|
||||
case Qt::Key_Space: return 53;
|
||||
// missing 54: F14/stop
|
||||
// missing 55: another Shift
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
int k = resolveKey(event->key());
|
||||
if (k >= 0)
|
||||
emu->keyboardKeys[k] = true;
|
||||
}
|
||||
|
||||
void MainWindow::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
int k = resolveKey(event->key());
|
||||
if (k >= 0)
|
||||
emu->keyboardKeys[k] = false;
|
||||
}
|
35
WindQt/mainwindow.h
Normal file
35
WindQt/mainwindow.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "../WindCore/emu.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow() override;
|
||||
|
||||
private slots:
|
||||
void on_stepButton_clicked();
|
||||
void execTimer();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
Emu *emu;
|
||||
QTimer *timer;
|
||||
void updateScreen();
|
||||
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void keyReleaseEvent(QKeyEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
58
WindQt/mainwindow.ui
Normal file
58
WindQt/mainwindow.ui
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>752</width>
|
||||
<height>429</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="stepButton">
|
||||
<property name="text">
|
||||
<string>Step</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="cycleCounter">
|
||||
<property name="text">
|
||||
<string>Cycles</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="screen">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Reference in New Issue
Block a user