2013-03-15 13:11:33 +00:00
|
|
|
namespace phoenix {
|
|
|
|
|
2013-07-29 09:42:45 +00:00
|
|
|
void pCanvas::setDroppable(bool droppable) {
|
|
|
|
qtCanvas->setAcceptDrops(droppable);
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::setSize(Size size) {
|
2011-11-04 11:57:54 +00:00
|
|
|
delete qtImage;
|
Update to v084r03 release.
(r02 was not posted to the WIP thread)
byuu says:
Internally, all color is processed with 30-bit precision. The filters
also operate at 30-bit depth.
There's a new config file setting, video.depth, which defaults to 24.
This causes the final output to downsample to 24-bit, as most will
require.
If you set it to 30-bit, the downsampling will not occur, and bsnes will
ask ruby for a 30-bit surface. If you don't have one available, you're
going to get bad colors. Or maybe even a crash with OpenGL.
I don't yet have detection code to make sure you have an appropriate
visual in place.
30-bit mode will really only work if you are running Linux, running Xorg
at Depth 30, use the OpenGL or XShm driver, have an nVidia Quadro or AMD
FireGL card with the official drivers, and have a 30-bit capable
monitor.
Lots of planning and work for very little gain here, but it's nice that
it's finally finished.
Oh, I had to change the contrast/brightness formulas a tiny bit, but
they still work and look nice.
2011-12-03 03:22:54 +00:00
|
|
|
qtImage = new QImage(size.width, size.height, QImage::Format_ARGB32);
|
2011-04-27 08:57:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::update() {
|
2013-05-02 11:25:45 +00:00
|
|
|
uint32_t* dp = (uint32_t*)qtImage->bits(), *sp = (uint32_t*)canvas.state.data;
|
Update to v084r05 release.
(note: before the post announcing this release, there had been
a discussion of a performance optimisation that made the Super Scope
emulation a lot faster, but caused problems for the Justifier perpheral)
byuu says:
Spent a good two hours trying things to no avail.
I was trying to allow the CPU to run ahead, and sync on accesses to
$4016/4017/4201/4213, but that doesn't work because the controllers have
access to strobe IObit at will.
The codebase is really starting to get difficult to work with. I am
guessing because the days of massive development are long over, and the
code is starting to age.
Jonas' fix works 98% of the time, but there's still a few missed shots
here and there. So that's not going to work either.
So ... I give up. I've disabled the speed hack, so that it works 100% of
the time.
Did the same for the Super Scope: it may not have the same problem, but
I like consistency and don't feel like taking the chance.
This doesn't affect the mouse, since the mouse does not latch the
counters to indicate its X/Y position.
Speed hit is 92->82fps (accuracy profile), but only for Super Scope and
Justifier games.
But ... at least it works now. Slow and working is better than fast and
broken.
I appreciate the help in researching the issue, Jonas and krom.
Also pulled in phoenix/Makefile, which simplifies ui/Makefile.
Linux port defaults to GTK+ now. I can't get QGtkStyle to look good on
Debian.
2011-12-18 03:19:45 +00:00
|
|
|
for(unsigned n = 0; n < canvas.state.width * canvas.state.height; n++) *dp++ = 0xff000000 | *sp++;
|
2011-04-27 08:57:31 +00:00
|
|
|
qtCanvas->update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::constructor() {
|
|
|
|
qtWidget = qtCanvas = new QtCanvas(*this);
|
2012-01-26 06:50:09 +00:00
|
|
|
qtCanvas->setMouseTracking(true);
|
Update to v084r03 release.
(r02 was not posted to the WIP thread)
byuu says:
Internally, all color is processed with 30-bit precision. The filters
also operate at 30-bit depth.
There's a new config file setting, video.depth, which defaults to 24.
This causes the final output to downsample to 24-bit, as most will
require.
If you set it to 30-bit, the downsampling will not occur, and bsnes will
ask ruby for a 30-bit surface. If you don't have one available, you're
going to get bad colors. Or maybe even a crash with OpenGL.
I don't yet have detection code to make sure you have an appropriate
visual in place.
30-bit mode will really only work if you are running Linux, running Xorg
at Depth 30, use the OpenGL or XShm driver, have an nVidia Quadro or AMD
FireGL card with the official drivers, and have a 30-bit capable
monitor.
Lots of planning and work for very little gain here, but it's nice that
it's finally finished.
Oh, I had to change the contrast/brightness formulas a tiny bit, but
they still work and look nice.
2011-12-03 03:22:54 +00:00
|
|
|
qtImage = new QImage(canvas.state.width, canvas.state.height, QImage::Format_ARGB32);
|
2011-11-04 11:57:54 +00:00
|
|
|
memcpy(qtImage->bits(), canvas.state.data, canvas.state.width * canvas.state.height * sizeof(uint32_t));
|
2011-09-05 03:48:23 +00:00
|
|
|
|
Update to v082r18 release.
byuu says:
There we go, the GUI is nearly feature-complete once again.
All cores now output their native video format (NES={emphasis}{palette},
SNES=BGR555, GameBoy={ bright, normal, darker, darkest }), and are
transformed to RGB555 data that is passed to the video renderer.
The video renderer then uses its internal palette to apply
brightness/contrast/gamma/ramp adjustments and outputs in RGB888 color
space.
This does add in another rendering pass, unfortunately, but it's
a necessary one for universal support.
The plan is to adapt all filters to take RGB555 input, and output RGB555
data as well. By doing this, it will be possible to stack filters.
However, it's a bit complicated: I need to plan how the stacking should
occur (eg we never want to apply scanlines before HQ2x, etc.)
Added input frequency adjustments for all three systems. I can easily
get perfect video/audio sync on all three now, hooray.
Long-term, it seems like we only really need one, and we can do
a video/audio delta to get an adjusted value. But for now, this gets the
job done.
Added audio volume adjust. I left out the balance for now, since it's
obviously impossible to balance the NES' single channel audio (I can
duplicate the channel, and do twice the filtering work, but ... why?)
I replaced NTSC/PAL TV mode selection with an "Enable Overscan"
checkbox. On, you get 240 lines on NES+SNES. Off, you get 224 lines on
NES+SNES.
Also added aspect correction box back. I don't do that gross PAL
distortion shit anymore, sorry PAL people. I just scale up the
54/47*(240/224) aspect correction for overscan off mode.
All memory is loaded and saved now, for all three systems (hooray, now
you can actually play Zelda 1&2.)
Added all of the old bsnes hotkeys, with the exception of capture
screenshot. May add again later. May come up with something a bit
different for extra features.
Re-added the NSS DIP switch setting window. Since geometry is saved,
I didn't want to auto-hide rows, so now you'll see all eight possible
DIPs, and the ones not used are grayed out.
Ultimately, nobody will notice since we only have DIPs for ActRaiser
NSS, and nobody's probably even using the XML file for that anyway.
Whatever, it's nice to have anyway.
Took FitzRoy's advice and single-item combo boxes on the input selection
are disabled, so the user doesn't waste time checking them.
I wanted to leave text so that you know there's not a problem. Qt
disabled radio box items look almost exactly like enabled ones.
Fixed lots of issues in phoenix and extended it a bit. But I was still
having trouble with radio box grouping, so I said fuck it and made the
panels show/hide based instead of append/remove based.
That's all for stuff off the checklist, I did a bunch of other things
I don't recall.
So yeah, I'd say the GUI is 100% usable now. This is my opinion on how
multi-platform GUIs should be done =)
Oh, I figure I should mention, but the NES core is GPLv3, and all future
SNES+GB releases will be as well. It's a move against Microsoft's Metro
store.
2011-09-20 14:04:43 +00:00
|
|
|
pWidget::synchronizeState();
|
2011-09-05 03:48:23 +00:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::destructor() {
|
|
|
|
delete qtCanvas;
|
|
|
|
delete qtImage;
|
2013-03-15 13:11:33 +00:00
|
|
|
qtWidget = qtCanvas = nullptr;
|
|
|
|
qtImage = nullptr;
|
2011-09-05 03:48:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::orphan() {
|
|
|
|
destructor();
|
|
|
|
constructor();
|
2011-04-27 08:57:31 +00:00
|
|
|
}
|
|
|
|
|
2013-07-29 09:42:45 +00:00
|
|
|
void pCanvas::QtCanvas::dragEnterEvent(QDragEnterEvent* event) {
|
|
|
|
if(event->mimeData()->hasUrls()) {
|
|
|
|
event->acceptProposedAction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void pCanvas::QtCanvas::dropEvent(QDropEvent* event) {
|
|
|
|
lstring paths = DropPaths(event);
|
|
|
|
if(paths.empty()) return;
|
|
|
|
if(self.canvas.onDrop) self.canvas.onDrop(paths);
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
void pCanvas::QtCanvas::leaveEvent(QEvent* event) {
|
2012-01-26 06:50:09 +00:00
|
|
|
if(self.canvas.onMouseLeave) self.canvas.onMouseLeave();
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
void pCanvas::QtCanvas::mouseMoveEvent(QMouseEvent* event) {
|
2013-03-15 13:11:33 +00:00
|
|
|
if(self.canvas.onMouseMove) self.canvas.onMouseMove({event->pos().x(), event->pos().y()});
|
2012-01-26 06:50:09 +00:00
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
void pCanvas::QtCanvas::mousePressEvent(QMouseEvent* event) {
|
2013-03-15 13:11:33 +00:00
|
|
|
if(!self.canvas.onMousePress) return;
|
2012-01-26 06:50:09 +00:00
|
|
|
switch(event->button()) {
|
|
|
|
case Qt::LeftButton: self.canvas.onMousePress(Mouse::Button::Left); break;
|
|
|
|
case Qt::MidButton: self.canvas.onMousePress(Mouse::Button::Middle); break;
|
|
|
|
case Qt::RightButton: self.canvas.onMousePress(Mouse::Button::Right); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
void pCanvas::QtCanvas::mouseReleaseEvent(QMouseEvent* event) {
|
2013-03-15 13:11:33 +00:00
|
|
|
if(!self.canvas.onMouseRelease) return;
|
2012-01-26 06:50:09 +00:00
|
|
|
switch(event->button()) {
|
|
|
|
case Qt::LeftButton: self.canvas.onMouseRelease(Mouse::Button::Left); break;
|
|
|
|
case Qt::MidButton: self.canvas.onMouseRelease(Mouse::Button::Middle); break;
|
|
|
|
case Qt::RightButton: self.canvas.onMouseRelease(Mouse::Button::Right); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
void pCanvas::QtCanvas::paintEvent(QPaintEvent* event) {
|
2011-04-27 08:57:31 +00:00
|
|
|
QPainter painter(self.qtCanvas);
|
|
|
|
painter.drawImage(0, 0, *self.qtImage);
|
2011-11-04 11:57:54 +00:00
|
|
|
|
|
|
|
//this will scale the source image to fit the target widget size (nearest-neighbor):
|
|
|
|
//painter.drawImage(
|
|
|
|
// QRect(0, 0, geometry().width(), geometry().height()),
|
|
|
|
// *self.qtImage,
|
|
|
|
// QRect(0, 0, self.canvas.state.width, self.canvas.state.height)
|
|
|
|
//);
|
2011-04-27 08:57:31 +00:00
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
pCanvas::QtCanvas::QtCanvas(pCanvas& self) : self(self) {
|
2011-04-27 08:57:31 +00:00
|
|
|
}
|
2013-03-15 13:11:33 +00:00
|
|
|
|
|
|
|
}
|