-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
252 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
145 changes: 145 additions & 0 deletions
145
src/platform/qt/src/widget/debugger/ppu/tile_viewer.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* Copyright (C) 2024 fleroviux | ||
* | ||
* Licensed under GPLv3 or any later version. | ||
* Refer to the included LICENSE file. | ||
*/ | ||
|
||
#include <fmt/format.h> | ||
#include <nba/common/punning.hpp> | ||
#include <QGroupBox> | ||
#include <QHBoxLayout> | ||
#include <QPainter> | ||
#include <QRadioButton> | ||
#include <QVBoxLayout> | ||
|
||
#include "widget/debugger/utility.hpp" | ||
#include "tile_viewer.hpp" | ||
|
||
TileViewer::TileViewer(nba::CoreBase* core, QWidget* parent) : QWidget(parent) { | ||
vram = core->GetVRAM(); | ||
pram = (u16*)core->GetPRAM(); | ||
|
||
QHBoxLayout* hbox = new QHBoxLayout{}; | ||
|
||
{ | ||
QVBoxLayout* vbox = new QVBoxLayout{}; | ||
|
||
magnification_input = new QSpinBox{}; | ||
magnification_input->setMinimum(1); | ||
magnification_input->setMaximum(16); | ||
vbox->addWidget(magnification_input); | ||
|
||
palette_input = new QSpinBox{}; | ||
palette_input->setMinimum(0); | ||
palette_input->setMaximum(15); | ||
vbox->addWidget(palette_input); | ||
|
||
QGroupBox* tile_base_group_box = new QGroupBox{}; | ||
tile_base_group_box->setTitle(tr("Tile Base")); | ||
|
||
QVBoxLayout* tile_base_vbox = new QVBoxLayout{}; | ||
|
||
for(u32 tile_base = 0x06000000u; tile_base <= 0x06010000u; tile_base += 0x4000u) { | ||
QRadioButton* radio_button = new QRadioButton{ | ||
QString::fromStdString(fmt::format("0x{:08X}", tile_base))}; | ||
|
||
connect(radio_button, &QRadioButton::pressed, [this, tile_base]() { | ||
this->tile_base = tile_base & 0xFFFFFFu; | ||
}); | ||
|
||
tile_base_vbox->addWidget(radio_button); | ||
|
||
if(tile_base == 0x06000000u) radio_button->click(); | ||
} | ||
|
||
tile_base_group_box->setLayout(tile_base_vbox); | ||
|
||
vbox->addWidget(tile_base_group_box); | ||
|
||
hbox->addLayout(vbox); | ||
} | ||
|
||
canvas = new QWidget{}; | ||
canvas->installEventFilter(this); | ||
hbox->addWidget(canvas); | ||
|
||
setLayout(hbox); | ||
} | ||
|
||
bool TileViewer::eventFilter(QObject* object, QEvent* event) { | ||
if(object == canvas && event->type() == QEvent::Paint) { | ||
const int canvas_w = canvas->size().width(); | ||
const int canvas_h = canvas->size().height(); | ||
|
||
const QRect src_rect{0, 0, 256, 256 * canvas_h / canvas_w}; | ||
const QRect dst_rect{0, 0, canvas_w, canvas_h}; | ||
|
||
QPainter painter{canvas}; | ||
painter.drawImage(dst_rect, image_rgb32, src_rect); | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
void TileViewer::Update() { | ||
if(!isVisible()) { | ||
return; | ||
} | ||
|
||
const int magnification = magnification_input->value(); | ||
const int palette_offset = tile_base == 0x10000u ? 256 : 0; | ||
|
||
u32* const buffer = (u32*)image_rgb32.bits(); | ||
|
||
int height = 256; | ||
u32 tile_address = tile_base; | ||
|
||
if(eight_bpp) { | ||
u16* const palette = &pram[palette_offset]; | ||
|
||
for(int tile = 0; tile < 512; tile++) { | ||
const int tile_base_x = (tile % 32) * 8; | ||
const int tile_base_y = (tile / 32) * 8; | ||
|
||
for(int y = 0; y < 8; y++) { | ||
u64 tile_row_data = nba::read<u64>(vram, tile_address); | ||
|
||
for(int x = 0; x < 8; x++) { | ||
buffer[(tile_base_y + y) * 256 + tile_base_x + x] = Rgb565ToArgb8888(palette[(u8)tile_row_data]); | ||
tile_row_data >>= 8; | ||
} | ||
|
||
tile_address += sizeof(u64); | ||
} | ||
} | ||
|
||
height /= 2; | ||
} else { | ||
u16* const palette = &pram[palette_input->value() * 16 + palette_offset]; | ||
|
||
for(int tile = 0; tile < 1024; tile++) { | ||
const int tile_base_x = (tile % 32) * 8; | ||
const int tile_base_y = (tile / 32) * 8; | ||
|
||
for(int y = 0; y < 8; y++) { | ||
u32 tile_row_data = nba::read<u32>(vram, tile_address); | ||
|
||
for(int x = 0; x < 8; x++) { | ||
buffer[(tile_base_y + y) * 256 + tile_base_x + x] = Rgb565ToArgb8888(palette[tile_row_data & 15]); | ||
tile_row_data >>= 4; | ||
} | ||
|
||
tile_address += sizeof(u32); | ||
} | ||
} | ||
} | ||
|
||
if(tile_base == 0xC000u) { | ||
height /= 2; | ||
} | ||
|
||
canvas->setFixedSize(256 * magnification, height * magnification); | ||
canvas->update(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (C) 2024 fleroviux | ||
* | ||
* Licensed under GPLv3 or any later version. | ||
* Refer to the included LICENSE file. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <nba/core.hpp> | ||
#include <QLabel> | ||
#include <QPaintEvent> | ||
#include <QSpinBox> | ||
#include <QWidget> | ||
|
||
struct TileViewer : QWidget { | ||
TileViewer(nba::CoreBase* core, QWidget* parent = nullptr); | ||
|
||
bool eventFilter(QObject* object, QEvent* event) override; | ||
|
||
void Update(); | ||
|
||
private: | ||
u8* vram; | ||
u16* pram; | ||
QImage image_rgb32{256, 256, QImage::Format_RGB32}; | ||
QSpinBox* palette_input; | ||
QSpinBox* magnification_input; | ||
QWidget* canvas; | ||
|
||
u32 tile_base = 0; | ||
bool eight_bpp = false; | ||
//int palette_index = 0; | ||
|
||
Q_OBJECT | ||
}; |
28 changes: 28 additions & 0 deletions
28
src/platform/qt/src/widget/debugger/ppu/tile_viewer_window.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (C) 2024 fleroviux | ||
* | ||
* Licensed under GPLv3 or any later version. | ||
* Refer to the included LICENSE file. | ||
*/ | ||
|
||
#include <QVBoxLayout> | ||
|
||
#include "tile_viewer_window.hpp" | ||
|
||
TileViewerWindow::TileViewerWindow(nba::CoreBase* core, QWidget* parent) : QDialog(parent) { | ||
const auto vbox = new QVBoxLayout{}; | ||
|
||
tile_viewer = new TileViewer{core, nullptr}; | ||
vbox->addWidget(tile_viewer); | ||
setLayout(vbox); | ||
|
||
setWindowTitle(tr("Tile Viewer")); | ||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | ||
} | ||
|
||
void TileViewerWindow::Update() { | ||
if(!isVisible()) { | ||
return; | ||
} | ||
tile_viewer->Update(); | ||
} |
26 changes: 26 additions & 0 deletions
26
src/platform/qt/src/widget/debugger/ppu/tile_viewer_window.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (C) 2024 fleroviux | ||
* | ||
* Licensed under GPLv3 or any later version. | ||
* Refer to the included LICENSE file. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <nba/core.hpp> | ||
#include <QDialog> | ||
#include <QLabel> | ||
|
||
#include "tile_viewer.hpp" | ||
|
||
struct TileViewerWindow : QDialog { | ||
TileViewerWindow(nba::CoreBase* core, QWidget* parent = nullptr); | ||
|
||
public slots: | ||
void Update(); | ||
|
||
private: | ||
TileViewer* tile_viewer; | ||
|
||
Q_OBJECT | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters