mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v039r06? release.
New WIP, looking for feedback on these changes. First, I switched from a standard QWidget to a more semantically- correct QMainWindow. Not much difference, except it adds an automatic menubar and statusbar, no need to make my own. One advantage was free status hint support without having to catch the event. So I took that and redesigned the status system. First, the game name on the status bar ate up too much space for nothing. I moved it to the titlebar: bsnes v0.nnn - Game Title (U) Second, I merged the FPS counter with the system state and put it on the right-hand side of the status bar. It shows "No cartridge loaded", "Power off", "Paused" and the framerate. This is persistent and always visible. FPS doesn't show ideal FPS next to it anymore. That just wastes space. Third, the new left-hand stuff. It uses the native QStatusBar support for timed messages. I use that to pump power state changes ("System was reset.", "Loaded Star Ocean (J), and applied UPS patch.", etc.) They go away after ~3 seconds. Unsupported special chip warnings now pop up a modal dialog box instead of showing in the status bar. Fourth, we can now set special menu group / item descriptions that appear when the items are hovered. For instance, mouse over settings->video mode->ntsc and it explains that the setting affects the perceived video output size, rather than the core emulator mode. The descriptions there now suck, but it shows off the concept. We'll leave them off for all the obvious items. With all of that, I was able to kill off the "Status" class, ~4kb of nasty code that polled the time constantly and maintained an internal string queue for statusbar messages. Also new to this WIP ... it's apparently not trivial to set a fixed window size with Qt on Xlib. My MinimizeWindowHint that worked on Windows was making the window top-most on Xfce, and breaking fullscreen mode. So, I tried again to write code that could properly switch between windowed and fullscreen mode. For some reason, this always causes tons of problems. Window managers like to take their sweet ass time updating internal states, so rapid geometry changes often fail, leaving the window in odd positions and sizes. It took quite a while, but I have it working, hopefully, 100% on Windows. I even account for the desk area (ignoring the taskbar and such) and the window decorations. Centering should be truly perfect, and scale max should be a pixel-perfect fit to all available screen size, while maintaining the ratio. Linux support is still kind of flaky, though. Long shot, but any knowledgeable help here would be appreciated. void Utility::updateFullscreenState() { if(config.video.isFullscreen == false) { config.video.context = &config.video.windowed; winMain->window->showNormal(); application.processEvents(); } else { config.video.context = &config.video.fullscreen; winMain->window->showFullScreen(); application.processEvents(); } //refresh options that are unique to each video context for(unsigned i = 0; i < 2; i++) resizeMainWindow(); //call twice as Xlib drops window messages sometimes updateHardwareFilter(); updateSoftwareFilter(); } //if max exceeds x: x is set to max, and y is scaled down to keep proportion to x void Utility::constrainSize(unsigned &x, unsigned &y, unsigned max) { if(x > max) { double scalar = (double)max / (double)x; y = (unsigned)((double)y * (double)scalar); x = max; } } //0 = use config file value, 1+ = override with new multiplier void Utility::resizeMainWindow(unsigned multiplier /* = 0 */) { if(multiplier != 0) config.video.context->multiplier = multiplier; else multiplier = config.video.context->multiplier; unsigned width = 256 * config.video.context->multiplier; unsigned height = (config.video.context->region == 0 ? 224 : 239) * config.video.context->multiplier; if(config.video.context->correctAspectRatio) { if(config.video.context->region == 0) { width = (double)width * 54.0 / 47.0 + 0.5; //NTSC adjust } else { width = (double)width * 32.0 / 23.0 + 0.5; //PAL adjust } } QDesktopWidget *desktop = QApplication::desktop(); if(config.video.isFullscreen == false) { //get effective desktop work area region (ignore Windows taskbar, OS X doc, etc.) QRect deskRect = desktop->availableGeometry(); unsigned deskWidth = (deskRect.right() - deskRect.left() + 1); unsigned deskHeight = (deskRect.bottom() - deskRect.top() + 1); //place window offscreen so resize events do not cause flickering winMain->window->move(desktop->width(), desktop->height()); application.processEvents(); //shrink window as much as possible to compute frame + menubar + statusbar size winMain->canvas->setFixedSize(0, 0); winMain->canvasContainer->resize(0, 0); application.processEvents(); winMain->window->resize(0, 0); application.processEvents(); QRect frameRect = winMain->window->frameGeometry(); //constrain window so that it will fit inside desktop work area constrainSize(height, width, deskHeight - (frameRect.bottom() - frameRect.top() + 1)); constrainSize(width, height, deskWidth - (frameRect.right() - frameRect.left() + 1)); //resize canvas to desired size winMain->canvas->setFixedSize(width, height); application.processEvents(); //shrink window so that it contains all of canvas, but is no larger winMain->window->resize(width, height); //allow canvas to be resized along with window by user winMain->canvas->setMinimumSize(256, config.video.context->region == 0 ? 224 : 239); winMain->canvas->setMaximumSize(desktop->width(), desktop->height()); winMain->canvas->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); application.processEvents(); //force window size change to take effect winMain->window->resize(width, height); application.processEvents(); //center window onscreen: //take desktop work area and window frame decorations into account QRect windowRect = winMain->window->frameGeometry(); unsigned windowWidth = (windowRect.right() - windowRect.left() + 1); unsigned windowHeight = (windowRect.bottom() - windowRect.top() + 1); winMain->window->move( deskRect.left() + (deskWidth - windowWidth ) / 2, deskRect.top () + (deskHeight - windowHeight) / 2 ); } else { constrainSize(height, width, winMain->canvasContainer->size().height()); constrainSize(width, height, winMain->canvasContainer->size().width()); winMain->canvas->setFixedSize(width, height); } } If anyone wanted to get stupid, a style for QWidget.backdrop { background: url(border.png); } when designed for a specific resolution + scaling mode would allow Super Gameboy-style borders :P Let's see ... properly subclassed the generic input binding pools for clarity, and added user interface key binding support again. So far only for exit emu + toggle fullscreen, but the rest should be easy now. I can't reduce the space for the QFrameWidgets. Only setMargin works, but it reduces margins on all sides where only the top is bad. I may have to revert it back to a section label + horizontal separator between each area. Probably a good idea, QGtkStyle doesn't support QFrameWidget's decoration anyway. Looks terrible on GNOME. Finally, fixed ui_hiro for Windows. Still need to fix up the Linux target. They share the same Makefile, so additional targets should be easy, eg a pure SDL port or whatever. > Darn. Oh well, guess I could keep whatever I concoct to myself. Or tell me what you want to do, as I probably won't mind :P [No archive available]
This commit is contained in:
parent
148bbddb1a
commit
94004f86ec