diff --git a/src/core.h b/src/core.h index 9a92937b3..fda23b5fb 100644 --- a/src/core.h +++ b/src/core.h @@ -72,12 +72,14 @@ struct RustError *update_firmware(const char *root, void *cx, void (*status)(const char*, uint64_t, uint64_t, void*)); -struct Vmm *vmm_new(struct RustError **err); +struct Vmm *vmm_new(size_t screen, struct RustError **err); void vmm_free(struct Vmm *vmm); struct RustError *vmm_run(struct Vmm *vmm, const char *kernel); +struct RustError *vmm_draw(struct Vmm *vmm); + void vmm_logs(const struct Vmm *vmm, void *cx, void (*cb)(uint8_t, const char*, size_t, void*)); #if defined(__linux__) diff --git a/src/core/src/vmm/mod.rs b/src/core/src/vmm/mod.rs index 59428e7d0..4abd02813 100644 --- a/src/core/src/vmm/mod.rs +++ b/src/core/src/vmm/mod.rs @@ -33,7 +33,7 @@ const ELF_MACHINE: u16 = 62; const ELF_MACHINE: u16 = 183; #[no_mangle] -pub unsafe extern "C" fn vmm_new(err: *mut *mut RustError) -> *mut Vmm { +pub unsafe extern "C" fn vmm_new(screen: usize, err: *mut *mut RustError) -> *mut Vmm { // Setup RAM. let ram = match Ram::new() { Ok(v) => Arc::new(v), @@ -273,6 +273,11 @@ pub unsafe extern "C" fn vmm_run(vmm: *mut Vmm, kernel: *const c_char) -> *mut R null_mut() } +#[no_mangle] +pub unsafe extern "C" fn vmm_draw(vmm: *mut Vmm) -> *mut RustError { + null_mut() +} + #[no_mangle] pub unsafe extern "C" fn vmm_logs( vmm: *const Vmm, diff --git a/src/main_window.cpp b/src/main_window.cpp index 6e5151eec..40f673e0a 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -96,6 +96,8 @@ MainWindow::MainWindow() : // Screen. m_screen = new Screen(); + connect(m_screen, &Screen::updateRequestReceived, this, &MainWindow::updateScreen); + m_main->addWidget(createWindowContainer(m_screen)); // Show the window. @@ -298,7 +300,7 @@ void MainWindow::startKernel() Rust error; Rust vmm; - vmm = vmm_new(&error); + vmm = vmm_new(m_screen->winId(), &error); if (!vmm) { QMessageBox::critical( @@ -320,7 +322,36 @@ void MainWindow::startKernel() } m_kernel = std::move(vmm); + + // Swap launch settings with the screen and start drawing loop. m_main->setCurrentIndex(1); + m_screen->requestUpdate(); +} + +void MainWindow::updateScreen() +{ + // Do nothing if the kernel is not running. + if (!m_kernel) { + return; + } + + // Draw the screen. + Rust error; + + error = vmm_draw(m_kernel); + + if (error) { + m_kernel.free(); + + QMessageBox::critical( + this, + "Error", + QString("Couldn't draw the screen: %1").arg(error_message(error))); + return; + } + + // Queue next update. + m_screen->requestUpdate(); } bool MainWindow::loadGame(const QString &gameId) diff --git a/src/main_window.hpp b/src/main_window.hpp index c492f5b1c..51559db3e 100644 --- a/src/main_window.hpp +++ b/src/main_window.hpp @@ -29,6 +29,7 @@ private slots: void reportIssue(); void aboutObliteration(); void startKernel(); + void updateScreen(); private: bool loadGame(const QString &gameId); diff --git a/src/screen.cpp b/src/screen.cpp index 1d492804c..b04dcf0e9 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -12,3 +12,12 @@ Screen::Screen() Screen::~Screen() { } + +bool Screen::event(QEvent *ev) +{ + if (ev->type() == QEvent::UpdateRequest) { + emit updateRequestReceived(); + } + + return QWindow::event(ev); +} diff --git a/src/screen.hpp b/src/screen.hpp index 4efb74e07..c0628f7e1 100644 --- a/src/screen.hpp +++ b/src/screen.hpp @@ -3,7 +3,12 @@ #include class Screen final : public QWindow { + Q_OBJECT public: Screen(); ~Screen() override; +signals: + void updateRequestReceived(); +protected: + bool event(QEvent *ev) override; };