mirror of https://github.com/stella-emu/stella.git
First pass at converting to SDL3. Mostly still broken in several ways:
- only works in Linux - sound, debugger and joystick not working (compiled out) - QisBlitter not working (issues with render targets) - adaptable refresh not working (not converted, and unable to test) - text events not working (so no input in UI textboxes, etc) - not entirely optimized - probably some other stuff. It does create a launcher and selecting a ROM works. Toggling fullscreen also works.
This commit is contained in:
parent
c217990d6d
commit
c02aa1ea0a
|
@ -6,7 +6,7 @@
|
|||
# * command line options to...
|
||||
# - override the host settings (for cross compiles
|
||||
# - whether to do a debug build (with -g) or an optimized build (-O3 etc.)
|
||||
# * detect whether the chosen backend is available (e.g. call sdl2-config)
|
||||
# * detect whether the chosen backend is available
|
||||
# * ....
|
||||
|
||||
|
||||
|
@ -54,7 +54,6 @@ _rm_rec="$_rm -r"
|
|||
_zip="zip -q"
|
||||
_cp=cp
|
||||
_windowspath=""
|
||||
_sdlconfig=sdl2-config
|
||||
_sdlpath="$PATH"
|
||||
_prefix=/usr/local
|
||||
|
||||
|
@ -817,8 +816,8 @@ fi
|
|||
#
|
||||
# Now, add the appropriate defines/libraries/headers
|
||||
#
|
||||
echo
|
||||
find_sdlconfig
|
||||
#echo
|
||||
#find_sdlconfig
|
||||
|
||||
SRC="src"
|
||||
SRC_OS="$SRC/os"
|
||||
|
@ -845,15 +844,18 @@ HTTP_LIB="$SRC_LIB/httplib"
|
|||
|
||||
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$ELF -I$JSON -I$SQLITE_REPO"
|
||||
|
||||
INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
|
||||
if test "$_build_static" = yes ; then
|
||||
_sdl_conf_libs="--static-libs"
|
||||
LDFLAGS="-static $LDFLAGS"
|
||||
else
|
||||
_sdl_conf_libs="--libs"
|
||||
fi
|
||||
#INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
|
||||
#if test "$_build_static" = yes ; then
|
||||
# _sdl_conf_libs="--static-libs"
|
||||
# LDFLAGS="-static $LDFLAGS"
|
||||
#else
|
||||
# _sdl_conf_libs="--libs"
|
||||
#fi
|
||||
|
||||
#if test "$_libpng" = yes ; then #FIXME:
|
||||
LIBS="$LIBS `$_pkg_config --libs sdl3`"
|
||||
#fi
|
||||
|
||||
LIBS="$LIBS `$_sdlconfig $_sdl_conf_libs`"
|
||||
LD=$CXX
|
||||
|
||||
case $_host_os in
|
||||
|
|
|
@ -30,15 +30,19 @@ EventHandlerSDL::EventHandlerSDL(OSystem& osystem)
|
|||
#ifdef GUI_SUPPORT
|
||||
{
|
||||
ostringstream buf;
|
||||
#if 0 //FIXME: come back to this
|
||||
myQwertz = int{'y'} == static_cast<int>
|
||||
(SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(KBDK_Z)));
|
||||
#else
|
||||
myQwertz = false;
|
||||
#endif
|
||||
buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY");
|
||||
Logger::debug(buf.view());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
||||
if(!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Couldn't initialize SDL joystick support: "
|
||||
|
@ -63,12 +67,14 @@ EventHandlerSDL::~EventHandlerSDL()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandlerSDL::enableTextEvents(bool enable)
|
||||
{
|
||||
#if 0 // FIXME: needs a window ptr; refactor to pass this into the method
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
if(enable)
|
||||
SDL_StartTextInput();
|
||||
else
|
||||
SDL_StopTextInput();
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -98,31 +104,31 @@ void EventHandlerSDL::pollEvent()
|
|||
switch(myEvent.type)
|
||||
{
|
||||
// keyboard events
|
||||
case SDL_KEYUP:
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_EVENT_KEY_UP:
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
{
|
||||
handleKeyEvent(static_cast<StellaKey>(myEvent.key.keysym.scancode),
|
||||
static_cast<StellaMod>(myEvent.key.keysym.mod),
|
||||
myEvent.key.type == SDL_KEYDOWN,
|
||||
handleKeyEvent(static_cast<StellaKey>(myEvent.key.scancode),
|
||||
static_cast<StellaMod>(myEvent.key.mod),
|
||||
myEvent.type == SDL_EVENT_KEY_DOWN,
|
||||
myEvent.key.repeat);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
{
|
||||
handleTextEvent(*(myEvent.text.text));
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
handleMouseMotionEvent(myEvent.motion.x, myEvent.motion.y,
|
||||
myEvent.motion.xrel, myEvent.motion.yrel);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
// ToDo: check support of more buttons and double-click
|
||||
MouseButton b{MouseButton::NONE};
|
||||
|
@ -140,19 +146,23 @@ void EventHandlerSDL::pollEvent()
|
|||
default:
|
||||
break;
|
||||
}
|
||||
handleMouseButtonEvent(b, myEvent.button.type == SDL_MOUSEBUTTONDOWN,
|
||||
handleMouseButtonEvent(b, myEvent.button.type == SDL_EVENT_MOUSE_BUTTON_DOWN,
|
||||
myEvent.button.x, myEvent.button.y);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
{
|
||||
int x{0}, y{0};
|
||||
// TODO: SDL now uses float for mouse coords, but the core still
|
||||
// uses int throughout; maybe this is sufficient?
|
||||
float x{0.F}, y{0.F};
|
||||
SDL_GetMouseState(&x, &y); // we need mouse position too
|
||||
if(myEvent.wheel.y < 0)
|
||||
handleMouseButtonEvent(MouseButton::WHEELDOWN, true, x, y);
|
||||
handleMouseButtonEvent(MouseButton::WHEELDOWN, true,
|
||||
static_cast<int>(x), static_cast<int>(y));
|
||||
else if(myEvent.wheel.y > 0)
|
||||
handleMouseButtonEvent(MouseButton::WHEELUP, true, x, y);
|
||||
handleMouseButtonEvent(MouseButton::WHEELUP, true,
|
||||
static_cast<int>(x), static_cast<int>(y));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -202,57 +212,50 @@ void EventHandlerSDL::pollEvent()
|
|||
}
|
||||
#endif
|
||||
|
||||
case SDL_QUIT:
|
||||
case SDL_EVENT_QUIT:
|
||||
{
|
||||
handleEvent(Event::Quit);
|
||||
break; // SDL_QUIT
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
switch(myEvent.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
handleSystemEvent(SystemEvent::WINDOW_SHOWN);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_HIDDEN:
|
||||
handleSystemEvent(SystemEvent::WINDOW_HIDDEN);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_EXPOSED);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_MOVED,
|
||||
myEvent.window.data1, myEvent.window.data1);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_RESIZED,
|
||||
myEvent.window.data1, myEvent.window.data1);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_MINIMIZED);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_MAXIMIZED);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_RESTORED);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
handleSystemEvent(SystemEvent::WINDOW_ENTER);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
handleSystemEvent(SystemEvent::WINDOW_LEAVE);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_GAINED);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_LOST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break; // SDL_WINDOWEVENT
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
handleSystemEvent(SystemEvent::WINDOW_SHOWN);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_HIDDEN:
|
||||
handleSystemEvent(SystemEvent::WINDOW_HIDDEN);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_EXPOSED);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_MOVED,
|
||||
myEvent.window.data1, myEvent.window.data1);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_RESIZED,
|
||||
myEvent.window.data1, myEvent.window.data1);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_MINIMIZED);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_MAXIMIZED);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_RESTORED);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
handleSystemEvent(SystemEvent::WINDOW_ENTER);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
handleSystemEvent(SystemEvent::WINDOW_LEAVE);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_GAINED);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_LOST);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -260,13 +263,14 @@ void EventHandlerSDL::pollEvent()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EventHandlerSDL::JoystickSDL::JoystickSDL(int idx)
|
||||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// NOLINTNEXTLINE: we want to initialize here, not in the member list
|
||||
myStick = SDL_JoystickOpen(idx);
|
||||
myStick = SDL_OpenJoystick(idx);
|
||||
if(myStick)
|
||||
{
|
||||
// In Windows, all XBox controllers using the XInput API seem to name
|
||||
|
@ -274,13 +278,15 @@ EventHandlerSDL::JoystickSDL::JoystickSDL(int idx)
|
|||
// it also appends " #x", where x seems to vary. Obviously this wreaks
|
||||
// havoc with the idea that a joystick will always have the same name.
|
||||
// So we truncate the number.
|
||||
const char* const sdlname = SDL_JoystickName(myStick);
|
||||
const char* const sdlname = SDL_GetJoystickName(myStick);
|
||||
const string& desc = BSPF::startsWithIgnoreCase(sdlname, "XInput Controller")
|
||||
? "XInput Controller" : sdlname;
|
||||
|
||||
initialize(SDL_JoystickInstanceID(myStick), desc,
|
||||
SDL_JoystickNumAxes(myStick), SDL_JoystickNumButtons(myStick),
|
||||
SDL_JoystickNumHats(myStick), SDL_JoystickNumBalls(myStick));
|
||||
initialize(SDL_GetJoystickID(myStick), desc,
|
||||
SDL_GetNumJoystickAxes(myStick),
|
||||
SDL_GetNumJoystickButtons(myStick),
|
||||
SDL_GetNumJoystickHats(myStick),
|
||||
SDL_GetNumJoystickBalls(myStick));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,3 +298,4 @@ EventHandlerSDL::JoystickSDL::~JoystickSDL()
|
|||
if(SDL_WasInit(SDL_INIT_JOYSTICK) && myStick)
|
||||
SDL_JoystickClose(myStick);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -58,6 +58,7 @@ class EventHandlerSDL : public EventHandler
|
|||
private:
|
||||
SDL_Event myEvent{0};
|
||||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
// A thin wrapper around a basic PhysicalJoystick, holding the pointer to
|
||||
// the underlying SDL joystick device.
|
||||
class JoystickSDL : public PhysicalJoystick
|
||||
|
@ -77,6 +78,7 @@ class EventHandlerSDL : public EventHandler
|
|||
JoystickSDL& operator=(const JoystickSDL&) = delete;
|
||||
JoystickSDL& operator=(JoystickSDL&&) = delete;
|
||||
};
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -35,7 +35,7 @@ FBBackendSDL::FBBackendSDL(OSystem& osystem)
|
|||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// Initialize SDL context
|
||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||
if(!SDL_InitSubSystem(SDL_INIT_VIDEO))
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError();
|
||||
|
@ -47,7 +47,7 @@ FBBackendSDL::FBBackendSDL(OSystem& osystem)
|
|||
// It's done this way (vs directly accessing a FBSurfaceSDL object)
|
||||
// since the structure may be needed before any FBSurface's have
|
||||
// been created
|
||||
myPixelFormat = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);
|
||||
myPixelFormat = SDL_GetPixelFormatDetails(SDL_PIXELFORMAT_ARGB8888);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -55,8 +55,6 @@ FBBackendSDL::~FBBackendSDL()
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_FreeFormat(myPixelFormat);
|
||||
|
||||
if(myRenderer)
|
||||
{
|
||||
SDL_DestroyRenderer(myRenderer);
|
||||
|
@ -69,7 +67,7 @@ FBBackendSDL::~FBBackendSDL()
|
|||
SDL_DestroyWindow(myWindow);
|
||||
myWindow = nullptr;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -80,15 +78,27 @@ void FBBackendSDL::queryHardware(vector<Common::Size>& fullscreenRes,
|
|||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// Get number of displays (for most systems, this will be '1')
|
||||
myNumDisplays = SDL_GetNumVideoDisplays();
|
||||
int count = 0;
|
||||
SDL_DisplayID* displays = SDL_GetDisplays(&count);
|
||||
if(displays && count > 0)
|
||||
myNumDisplays = static_cast<uInt32>(count);
|
||||
else
|
||||
return;
|
||||
|
||||
// First get the maximum fullscreen desktop resolution
|
||||
SDL_DisplayMode display{};
|
||||
for(int i = 0; i < myNumDisplays; ++i)
|
||||
// Get the maximum fullscreen and windowed desktop resolutions
|
||||
for(uInt32 i = 0; i < myNumDisplays; ++i)
|
||||
{
|
||||
SDL_GetDesktopDisplayMode(i, &display);
|
||||
fullscreenRes.emplace_back(display.w, display.h);
|
||||
// Fullscreen mode
|
||||
const SDL_DisplayMode* fsmode = SDL_GetDesktopDisplayMode(displays[i]);
|
||||
fullscreenRes.emplace_back(fsmode->w, fsmode->h);
|
||||
|
||||
// Windowed mode
|
||||
SDL_Rect r{};
|
||||
if(SDL_GetDisplayUsableBounds(displays[i], &r))
|
||||
windowedRes.emplace_back(r.w, r.h);
|
||||
|
||||
#if 0 //FIXME: debug code, not yet converted to SDL3
|
||||
SDL_DisplayMode display{};
|
||||
// evaluate fullscreen display modes (debug only for now)
|
||||
const int numModes = SDL_GetNumDisplayModes(i);
|
||||
ostringstream s;
|
||||
|
@ -113,46 +123,21 @@ void FBBackendSDL::queryHardware(vector<Common::Size>& fullscreenRes,
|
|||
s << " " << lastRes << ": ";
|
||||
}
|
||||
s << mode.refresh_rate << "Hz";
|
||||
if(mode.w == display.w && mode.h == display.h && mode.refresh_rate == display.refresh_rate)
|
||||
if(mode.w == display.w && mode.h == display.h &&
|
||||
mode.refresh_rate == display.refresh_rate)
|
||||
s << "* ";
|
||||
else
|
||||
s << " ";
|
||||
}
|
||||
Logger::debug(s.view());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Now get the maximum windowed desktop resolution
|
||||
// Try to take into account taskbars, etc, if available
|
||||
#if SDL_VERSION_ATLEAST(2,0,5)
|
||||
// Take window title-bar into account; SDL_GetDisplayUsableBounds doesn't do that
|
||||
int wTop = 0, wLeft = 0, wBottom = 0, wRight = 0;
|
||||
SDL_Window* tmpWindow = SDL_CreateWindow("", 0, 0, 0, 0, SDL_WINDOW_HIDDEN);
|
||||
if(tmpWindow != nullptr)
|
||||
{
|
||||
SDL_GetWindowBordersSize(tmpWindow, &wTop, &wLeft, &wBottom, &wRight);
|
||||
SDL_DestroyWindow(tmpWindow);
|
||||
}
|
||||
|
||||
SDL_Rect r{};
|
||||
for(int i = 0; i < myNumDisplays; ++i)
|
||||
{
|
||||
// Display bounds minus dock
|
||||
SDL_GetDisplayUsableBounds(i, &r); // Requires SDL-2.0.5 or higher
|
||||
r.h -= (wTop + wBottom);
|
||||
windowedRes.emplace_back(r.w, r.h);
|
||||
}
|
||||
#else
|
||||
for(int i = 0; i < myNumDisplays; ++i)
|
||||
{
|
||||
SDL_GetDesktopDisplayMode(i, &display);
|
||||
windowedRes.emplace_back(display.w, display.h);
|
||||
}
|
||||
#endif
|
||||
SDL_free(displays);
|
||||
|
||||
struct RenderName
|
||||
{
|
||||
string sdlName;
|
||||
string stellaName;
|
||||
string_view sdlName;
|
||||
string_view stellaName;
|
||||
};
|
||||
// Create name map for all currently known SDL renderers
|
||||
static const std::array<RenderName, 8> RENDERER_NAMES = {{
|
||||
|
@ -169,22 +154,22 @@ void FBBackendSDL::queryHardware(vector<Common::Size>& fullscreenRes,
|
|||
const int numDrivers = SDL_GetNumRenderDrivers();
|
||||
for(int i = 0; i < numDrivers; ++i)
|
||||
{
|
||||
SDL_RendererInfo info;
|
||||
if(SDL_GetRenderDriverInfo(i, &info) == 0)
|
||||
const char* const rendername = SDL_GetRenderDriver(i);
|
||||
if(rendername)
|
||||
{
|
||||
// Map SDL names into nicer Stella names (if available)
|
||||
bool found = false;
|
||||
for(const auto& render: RENDERER_NAMES)
|
||||
{
|
||||
if(render.sdlName == info.name)
|
||||
if(render.sdlName == rendername)
|
||||
{
|
||||
VarList::push_back(renderers, render.stellaName, info.name);
|
||||
VarList::push_back(renderers, render.stellaName, rendername);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
VarList::push_back(renderers, info.name, info.name);
|
||||
VarList::push_back(renderers, rendername, rendername);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,8 +179,7 @@ bool FBBackendSDL::isCurrentWindowPositioned() const
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
return !myCenter
|
||||
&& myWindow && !(SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
return myWindow && !fullScreen() && !myCenter;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -210,11 +194,11 @@ Common::Point FBBackendSDL::getCurrentWindowPos() const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Int32 FBBackendSDL::getCurrentDisplayIndex() const
|
||||
uInt32 FBBackendSDL::getCurrentDisplayID() const
|
||||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
return SDL_GetWindowDisplayIndex(myWindow);
|
||||
return SDL_GetDisplayForWindow(myWindow);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -223,13 +207,13 @@ bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// cerr << mode << '\n';
|
||||
|
||||
// If not initialized by this point, then immediately fail
|
||||
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
||||
return false;
|
||||
|
||||
const bool fullScreen = mode.fsIndex != -1;
|
||||
const Int32 displayIndex = std::min(myNumDisplays - 1, winIdx);
|
||||
|
||||
const uInt32 displayIndex = std::min<uInt32>(myNumDisplays, winIdx);
|
||||
int posX = 0, posY = 0;
|
||||
|
||||
myCenter = myOSystem.settings().getBool("center");
|
||||
|
@ -259,11 +243,12 @@ bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
|||
posY = BSPF::clamp(posY, y0 + 50, y1 - 50);
|
||||
}
|
||||
|
||||
#if 0 // FIXME: adaptable
|
||||
#ifdef ADAPTABLE_REFRESH_SUPPORT
|
||||
SDL_DisplayMode adaptedSdlMode{};
|
||||
const int gameRefreshRate =
|
||||
myOSystem.hasConsole() ? myOSystem.console().gameRefreshRate() : 0;
|
||||
const bool shouldAdapt = fullScreen
|
||||
const bool shouldAdapt = mode.fullscreen
|
||||
&& myOSystem.settings().getBool("tia.fs_refresh")
|
||||
&& gameRefreshRate
|
||||
// take care of 59.94 Hz
|
||||
|
@ -274,21 +259,19 @@ bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
|||
#else
|
||||
const bool adaptRefresh = false;
|
||||
#endif
|
||||
const uInt32 flags = SDL_WINDOW_ALLOW_HIGHDPI
|
||||
| (fullScreen ? adaptRefresh ? SDL_WINDOW_FULLSCREEN :
|
||||
SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
#endif
|
||||
|
||||
// Don't re-create the window if its display and size hasn't changed,
|
||||
// as it's not necessary, and causes flashing in fullscreen mode
|
||||
if(myWindow)
|
||||
{
|
||||
const int d = SDL_GetWindowDisplayIndex(myWindow);
|
||||
const uInt32 d = getCurrentDisplayID();
|
||||
int w{0}, h{0};
|
||||
|
||||
SDL_GetWindowSize(myWindow, &w, &h);
|
||||
if(d != displayIndex ||
|
||||
std::cmp_not_equal(w, mode.screenS.w) ||
|
||||
std::cmp_not_equal(h, mode.screenS.h) || adaptRefresh)
|
||||
std::cmp_not_equal(h, mode.screenS.h) /*|| adaptRefresh*/) //FIXME
|
||||
{
|
||||
// Renderer has to be destroyed *before* the window gets destroyed to avoid memory leaks
|
||||
SDL_DestroyRenderer(myRenderer);
|
||||
|
@ -306,8 +289,27 @@ bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
|||
}
|
||||
else
|
||||
{
|
||||
myWindow = SDL_CreateWindow(myScreenTitle.c_str(), posX, posY,
|
||||
mode.screenS.w, mode.screenS.h, flags);
|
||||
// Re-create with new properties
|
||||
const SDL_PropertiesID props = SDL_CreateProperties();
|
||||
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING,
|
||||
myScreenTitle.c_str());
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, posX);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, posY);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER,
|
||||
mode.screenS.w);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER,
|
||||
mode.screenS.h);
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN,
|
||||
true);
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN,
|
||||
mode.fullscreen);
|
||||
SDL_SetBooleanProperty(props,
|
||||
SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN,
|
||||
true);
|
||||
// FIXME: adaptable (does it need a property??)
|
||||
|
||||
myWindow = SDL_CreateWindowWithProperties(props);
|
||||
SDL_DestroyProperties(props);
|
||||
if(myWindow == nullptr)
|
||||
{
|
||||
const string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
|
||||
|
@ -318,6 +320,7 @@ bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
|||
setWindowIcon();
|
||||
}
|
||||
|
||||
#if 0 // FIXME: adaptable
|
||||
#ifdef ADAPTABLE_REFRESH_SUPPORT
|
||||
if(adaptRefresh)
|
||||
{
|
||||
|
@ -339,15 +342,26 @@ bool FBBackendSDL::setVideoMode(const VideoModeHandler::Mode& mode,
|
|||
cerr << setSdlMode.refresh_rate << "Hz\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return createRenderer();
|
||||
const bool result = createRenderer();
|
||||
if(result)
|
||||
{
|
||||
// TODO: Checking for fullscreen status later returns invalid results,
|
||||
// so we check and cache it here
|
||||
myIsFullscreen = SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN;
|
||||
SDL_ShowWindow(myWindow);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FBBackendSDL::adaptRefreshRate(Int32 displayIndex,
|
||||
SDL_DisplayMode& adaptedSdlMode)
|
||||
{
|
||||
#if 0 // FIXME: adaptable
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_DisplayMode sdlMode;
|
||||
|
@ -402,6 +416,8 @@ bool FBBackendSDL::adaptRefreshRate(Int32 displayIndex,
|
|||
|
||||
// Only change if the display supports a better refresh rate
|
||||
return adapt;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -411,32 +427,40 @@ bool FBBackendSDL::createRenderer()
|
|||
|
||||
// A new renderer is only created when necessary:
|
||||
// - no renderer existing
|
||||
// - different renderer flags
|
||||
// - different renderer name
|
||||
// - different renderer vsync
|
||||
const bool enableVSync = myOSystem.settings().getBool("vsync") &&
|
||||
!myOSystem.settings().getBool("turbo");
|
||||
const string& video = myOSystem.settings().getString("video");
|
||||
|
||||
bool recreate = myRenderer == nullptr;
|
||||
uInt32 renderFlags = SDL_RENDERER_ACCELERATED;
|
||||
const string& video = myOSystem.settings().getString("video"); // Render hint
|
||||
SDL_RendererInfo renderInfo{};
|
||||
if(myRenderer)
|
||||
{
|
||||
recreate = recreate || video != SDL_GetRendererName(myRenderer);
|
||||
|
||||
if(myOSystem.settings().getBool("vsync")
|
||||
&& !myOSystem.settings().getBool("turbo")) // V'synced blits option
|
||||
renderFlags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
|
||||
// check renderer flags and name
|
||||
recreate |= (SDL_GetRendererInfo(myRenderer, &renderInfo) != 0)
|
||||
|| ((renderInfo.flags & (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) != renderFlags
|
||||
|| (video != renderInfo.name));
|
||||
SDL_PropertiesID props = SDL_GetRendererProperties(myRenderer);
|
||||
const bool currentVSync = SDL_GetNumberProperty(props,
|
||||
SDL_PROP_RENDERER_VSYNC_NUMBER, 0) != 0;
|
||||
recreate = recreate || currentVSync != enableVSync;
|
||||
}
|
||||
|
||||
if(recreate)
|
||||
{
|
||||
//cerr << "Create new renderer for buffer type #" << int(myBufferType) << '\n';
|
||||
if(myRenderer)
|
||||
SDL_DestroyRenderer(myRenderer);
|
||||
|
||||
// Re-create with new properties
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
if(!video.empty())
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, video.c_str());
|
||||
SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING,
|
||||
video.c_str());
|
||||
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER,
|
||||
enableVSync ? 1 : 0);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER,
|
||||
myWindow);
|
||||
|
||||
myRenderer = SDL_CreateRenderer(myWindow, -1, renderFlags);
|
||||
myRenderer = SDL_CreateRendererWithProperties(props);
|
||||
SDL_DestroyProperties(props);
|
||||
|
||||
detectFeatures();
|
||||
determineDimensions();
|
||||
|
@ -450,10 +474,9 @@ bool FBBackendSDL::createRenderer()
|
|||
}
|
||||
clear();
|
||||
|
||||
SDL_RendererInfo renderinfo;
|
||||
|
||||
if(SDL_GetRendererInfo(myRenderer, &renderinfo) >= 0)
|
||||
myOSystem.settings().setValue("video", renderinfo.name);
|
||||
const char* const detectedvideo = SDL_GetRendererName(myRenderer);
|
||||
if(detectedvideo)
|
||||
myOSystem.settings().setValue("video", detectedvideo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -466,7 +489,7 @@ void FBBackendSDL::setTitle(string_view title)
|
|||
myScreenTitle = title;
|
||||
|
||||
if(myWindow)
|
||||
SDL_SetWindowTitle(myWindow, string{title}.c_str());
|
||||
SDL_SetWindowTitle(myWindow, myScreenTitle.c_str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -476,16 +499,21 @@ string FBBackendSDL::about() const
|
|||
|
||||
ostringstream out;
|
||||
out << "Video system: " << SDL_GetCurrentVideoDriver() << '\n';
|
||||
SDL_RendererInfo info;
|
||||
if(SDL_GetRendererInfo(myRenderer, &info) >= 0)
|
||||
|
||||
SDL_PropertiesID props = SDL_GetRendererProperties(myRenderer);
|
||||
if(props != 0)
|
||||
{
|
||||
out << " Renderer: " << info.name << '\n';
|
||||
if(info.max_texture_width > 0 && info.max_texture_height > 0)
|
||||
out << " Max texture: " << info.max_texture_width << "x"
|
||||
<< info.max_texture_height << '\n';
|
||||
out << " Renderer: "
|
||||
<< SDL_GetStringProperty(props, SDL_PROP_RENDERER_NAME_STRING, "")
|
||||
<< '\n';
|
||||
const int maxTexSize =
|
||||
SDL_GetNumberProperty(props, SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 0);
|
||||
if(maxTexSize > 0)
|
||||
out << " Max texture: " << maxTexSize << "x" << maxTexSize << '\n';
|
||||
const bool usingVSync = SDL_GetNumberProperty(props,
|
||||
SDL_PROP_RENDERER_VSYNC_NUMBER, 0) != 0;
|
||||
out << " Flags: "
|
||||
<< ((info.flags & SDL_RENDERER_PRESENTVSYNC) ? "+" : "-") << "vsync, "
|
||||
<< ((info.flags & SDL_RENDERER_ACCELERATED) ? "+" : "-") << "accel"
|
||||
<< (usingVSync ? "+" : "-") << "vsync"
|
||||
<< '\n';
|
||||
}
|
||||
return out.str();
|
||||
|
@ -496,7 +524,8 @@ void FBBackendSDL::showCursor(bool show)
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
|
||||
if(show) SDL_ShowCursor();
|
||||
else SDL_HideCursor();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -504,7 +533,7 @@ void FBBackendSDL::grabMouse(bool grab)
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_SetWindowMouseGrab(myWindow, grab);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -513,7 +542,7 @@ bool FBBackendSDL::fullScreen() const
|
|||
ASSERT_MAIN_THREAD;
|
||||
|
||||
#ifdef WINDOWED_SUPPORT
|
||||
return SDL_GetWindowFlags(myWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
return myIsFullscreen; // TODO: should query SDL directly
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
@ -524,11 +553,11 @@ int FBBackendSDL::refreshRate() const
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
const uInt32 displayIndex = SDL_GetWindowDisplayIndex(myWindow);
|
||||
SDL_DisplayMode sdlMode;
|
||||
const SDL_DisplayID displayID = getCurrentDisplayID();
|
||||
const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displayID);
|
||||
|
||||
if(SDL_GetCurrentDisplayMode(displayIndex, &sdlMode) == 0)
|
||||
return sdlMode.refresh_rate;
|
||||
if(mode)
|
||||
return mode->refresh_rate;
|
||||
|
||||
if(myWindow != nullptr)
|
||||
Logger::error("Could not retrieve current display mode");
|
||||
|
@ -552,10 +581,10 @@ void FBBackendSDL::setWindowIcon()
|
|||
#include "stella_icon.hxx"
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(stella_icon, 32, 32, 32,
|
||||
32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
|
||||
SDL_Surface* surface =
|
||||
SDL_CreateSurfaceFrom(32, 32, SDL_PIXELFORMAT_ARGB8888, stella_icon, 32 * 4);
|
||||
SDL_SetWindowIcon(myWindow, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
SDL_DestroySurface(surface);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -575,6 +604,10 @@ unique_ptr<FBSurface> FBBackendSDL::createSurface(
|
|||
void FBBackendSDL::readPixels(uInt8* buffer, size_t pitch,
|
||||
const Common::Rect& rect) const
|
||||
{
|
||||
// FIXME: this method needs to be refactored to return an FBSurface,
|
||||
// since SDL_RenderReadPixels now returns an SDL_Surface
|
||||
// PNGLibrary is the only user of this; that will need to be refactored too
|
||||
#if 0
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_Rect r;
|
||||
|
@ -582,6 +615,7 @@ void FBBackendSDL::readPixels(uInt8* buffer, size_t pitch,
|
|||
r.w = rect.w(); r.h = rect.h();
|
||||
|
||||
SDL_RenderReadPixels(myRenderer, &r, 0, buffer, static_cast<int>(pitch));
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -609,25 +643,9 @@ bool FBBackendSDL::detectRenderTargetSupport()
|
|||
if(myRenderer == nullptr)
|
||||
return false;
|
||||
|
||||
SDL_RendererInfo info;
|
||||
SDL_GetRendererInfo(myRenderer, &info);
|
||||
|
||||
if(!(info.flags & SDL_RENDERER_TARGETTEXTURE))
|
||||
return false;
|
||||
|
||||
SDL_Texture* tex =
|
||||
SDL_CreateTexture(myRenderer, myPixelFormat->format,
|
||||
SDL_TEXTUREACCESS_TARGET, 16, 16);
|
||||
|
||||
if(!tex)
|
||||
return false;
|
||||
|
||||
const int sdlError = SDL_SetRenderTarget(myRenderer, tex);
|
||||
SDL_SetRenderTarget(myRenderer, nullptr);
|
||||
|
||||
SDL_DestroyTexture(tex);
|
||||
|
||||
return sdlError == 0;
|
||||
// All texture modes except software support render targets
|
||||
const char* const detectedvideo = SDL_GetRendererName(myRenderer);
|
||||
return detectedvideo && !BSPF::equalsIgnoreCase(detectedvideo, "software");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -643,5 +661,5 @@ void FBBackendSDL::determineDimensions()
|
|||
myRenderH = myWindowH;
|
||||
}
|
||||
else
|
||||
SDL_GetRendererOutputSize(myRenderer, &myRenderW, &myRenderH);
|
||||
SDL_GetCurrentRenderOutputSize(myRenderer, &myRenderW, &myRenderH);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class FBBackendSDL : public FBBackend
|
|||
/**
|
||||
Get the SDL pixel format.
|
||||
*/
|
||||
const SDL_PixelFormat& pixelFormat() const { return *myPixelFormat; }
|
||||
const SDL_PixelFormatDetails& pixelFormat() const { return *myPixelFormat; }
|
||||
|
||||
/**
|
||||
Does the renderer support render targets?
|
||||
|
@ -99,7 +99,7 @@ class FBBackendSDL : public FBBackend
|
|||
@param b The blue component of the color
|
||||
*/
|
||||
FORCE_INLINE void getRGB(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b) const override
|
||||
{ SDL_GetRGB(pixel, myPixelFormat, r, g, b); }
|
||||
{ SDL_GetRGB(pixel, myPixelFormat, nullptr, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to retrieve the R/G/B/A data from the given pixel.
|
||||
|
@ -111,7 +111,7 @@ class FBBackendSDL : public FBBackend
|
|||
@param a The alpha component of the color.
|
||||
*/
|
||||
FORCE_INLINE void getRGBA(uInt32 pixel, uInt8* r, uInt8* g, uInt8* b, uInt8* a) const override
|
||||
{ SDL_GetRGBA(pixel, myPixelFormat, r, g, b, a); }
|
||||
{ SDL_GetRGBA(pixel, myPixelFormat, nullptr, r, g, b, a); }
|
||||
|
||||
/**
|
||||
This method is called to map a given R/G/B triple to the screen palette.
|
||||
|
@ -121,7 +121,7 @@ class FBBackendSDL : public FBBackend
|
|||
@param b The blue component of the color.
|
||||
*/
|
||||
uInt32 mapRGB(uInt8 r, uInt8 g, uInt8 b) const override
|
||||
{ return SDL_MapRGB(myPixelFormat, r, g, b); }
|
||||
{ return SDL_MapRGB(myPixelFormat, nullptr, r, g, b); }
|
||||
|
||||
/**
|
||||
This method is called to map a given R/G/B/A triple to the screen palette.
|
||||
|
@ -132,7 +132,7 @@ class FBBackendSDL : public FBBackend
|
|||
@param a The alpha component of the color.
|
||||
*/
|
||||
uInt32 mapRGBA(uInt8 r, uInt8 g, uInt8 b, uInt8 a) const override
|
||||
{ return SDL_MapRGBA(myPixelFormat, r, g, b, a); }
|
||||
{ return SDL_MapRGBA(myPixelFormat, nullptr, r, g, b, a); }
|
||||
|
||||
/**
|
||||
This method is called to get a copy of the specified ARGB data from the
|
||||
|
@ -167,10 +167,9 @@ class FBBackendSDL : public FBBackend
|
|||
This method is called to query the video hardware for the index
|
||||
of the display the current window is displayed on
|
||||
|
||||
@return the current display index or a negative value if no
|
||||
window is displayed
|
||||
@return the current display index or a 0 if no window is displayed
|
||||
*/
|
||||
Int32 getCurrentDisplayIndex() const override;
|
||||
uInt32 getCurrentDisplayID() const override;
|
||||
|
||||
/**
|
||||
Clear the frame buffer.
|
||||
|
@ -286,7 +285,14 @@ class FBBackendSDL : public FBBackend
|
|||
SDL_Renderer* myRenderer{nullptr};
|
||||
|
||||
// Used by mapRGB (when palettes are created)
|
||||
SDL_PixelFormat* myPixelFormat{nullptr};
|
||||
const SDL_PixelFormatDetails* myPixelFormat{nullptr};
|
||||
|
||||
// Are we in fullscreen mode?
|
||||
// There seem to be issues with creating the window and renderer separately,
|
||||
// and doing so means we can't query the window for fullscreen status
|
||||
// So we do it at window creation and cache the result
|
||||
// TODO: Is this a bug in SDL?
|
||||
bool myIsFullscreen{false};
|
||||
|
||||
// Center setting of current window
|
||||
bool myCenter{false};
|
||||
|
@ -298,7 +304,7 @@ class FBBackendSDL : public FBBackend
|
|||
string myScreenTitle;
|
||||
|
||||
// Number of displays
|
||||
int myNumDisplays{1};
|
||||
uInt32 myNumDisplays{0};
|
||||
|
||||
// Window and renderer dimensions
|
||||
int myWindowW{0}, myWindowH{0}, myRenderW{0}, myRenderH{0};
|
||||
|
|
|
@ -59,7 +59,7 @@ FBSurfaceSDL::~FBSurfaceSDL()
|
|||
|
||||
if(mySurface)
|
||||
{
|
||||
SDL_FreeSurface(mySurface);
|
||||
SDL_DestroySurface(mySurface);
|
||||
mySurface = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ void FBSurfaceSDL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, ColorId colo
|
|||
tmp.y = y;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(mySurface, &tmp, myPalette[color]);
|
||||
SDL_FillSurfaceRect(mySurface, &tmp, myPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -183,7 +183,7 @@ void FBSurfaceSDL::invalidate()
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_FillRect(mySurface, nullptr, 0);
|
||||
SDL_FillSurfaceRect(mySurface, nullptr, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -199,7 +199,7 @@ void FBSurfaceSDL::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
|||
tmp.h = h;
|
||||
// Note: Transparency has to be 0 to clear the rectangle foreground
|
||||
// without affecting the background display.
|
||||
SDL_FillRect(mySurface, &tmp, 0);
|
||||
SDL_FillSurfaceRect(mySurface, &tmp, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -214,7 +214,7 @@ void FBSurfaceSDL::resize(uInt32 width, uInt32 height)
|
|||
ASSERT_MAIN_THREAD;
|
||||
|
||||
if(mySurface)
|
||||
SDL_FreeSurface(mySurface);
|
||||
SDL_DestroySurface(mySurface);
|
||||
|
||||
// NOTE: Currently, a resize changes a 'static' surface to 'streaming'
|
||||
// No code currently does this, but we should at least check for it
|
||||
|
@ -230,10 +230,8 @@ void FBSurfaceSDL::createSurface(uInt32 width, uInt32 height, const uInt32* data
|
|||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// Create a surface in the same format as the parent GL class
|
||||
const SDL_PixelFormat& pf = myBackend.pixelFormat();
|
||||
|
||||
mySurface = SDL_CreateRGBSurface(0, width, height,
|
||||
pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
|
||||
const SDL_PixelFormatDetails& pf = myBackend.pixelFormat();
|
||||
mySurface = SDL_CreateSurface(width, height, pf.format);
|
||||
//SDL_SetSurfaceBlendMode(mySurface, SDL_BLENDMODE_ADD); // default: SDL_BLENDMODE_BLEND
|
||||
|
||||
// We start out with the src and dst rectangles containing the same
|
||||
|
@ -246,7 +244,7 @@ void FBSurfaceSDL::createSurface(uInt32 width, uInt32 height, const uInt32* data
|
|||
////////////////////////////////////////////////////
|
||||
// These *must* be set for the parent class
|
||||
myPixels = static_cast<uInt32*>(mySurface->pixels);
|
||||
myPitch = mySurface->pitch / pf.BytesPerPixel;
|
||||
myPitch = mySurface->pitch / pf.bytes_per_pixel;
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
myIsStatic = data != nullptr;
|
||||
|
|
|
@ -43,8 +43,7 @@ namespace {
|
|||
StellaMod::KBDM_RGUI,
|
||||
StellaMod::KBDM_NUM,
|
||||
StellaMod::KBDM_CAPS,
|
||||
StellaMod::KBDM_MODE,
|
||||
StellaMod::KBDM_RESERVED
|
||||
StellaMod::KBDM_MODE
|
||||
}) {
|
||||
if((mask & mod) != mod) continue;
|
||||
|
||||
|
|
|
@ -78,10 +78,6 @@ class AudioSettings;
|
|||
implementations for the various ports of Stella, and always returns a
|
||||
valid object based on the specific port and restrictions on that port.
|
||||
|
||||
As of SDL2, this code is greatly simplified. However, it remains here
|
||||
in case we ever have multiple backend implementations again (should
|
||||
not be necessary since SDL2 covers this nicely).
|
||||
|
||||
@author Stephen Anthony
|
||||
*/
|
||||
class MediaFactory
|
||||
|
@ -181,15 +177,6 @@ class MediaFactory
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool supportsURL()
|
||||
{
|
||||
#if defined(SDL_SUPPORT)
|
||||
return SDLSupportsURL();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool openURL(const string& url)
|
||||
{
|
||||
#if defined(SDL_SUPPORT)
|
||||
|
|
|
@ -33,48 +33,30 @@
|
|||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||
#pragma clang diagnostic ignored "-Wswitch-default"
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(BSPF_WINDOWS)
|
||||
#pragma warning(push, 0)
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Seems to be needed for ppc64le, doesn't hurt other archs
|
||||
* Note that this is a problem in SDL2, which includes <altivec.h>
|
||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1419452
|
||||
*/
|
||||
#undef vector
|
||||
#undef pixel
|
||||
#undef bool
|
||||
|
||||
static inline string SDLVersion()
|
||||
{
|
||||
ostringstream buf;
|
||||
SDL_version ver;
|
||||
SDL_GetVersion(&ver);
|
||||
buf << "SDL " << static_cast<int>(ver.major) << "." << static_cast<int>(ver.minor)
|
||||
<< "." << static_cast<int>(ver.patch);
|
||||
const int ver = SDL_GetVersion();
|
||||
buf << "SDL "
|
||||
<< SDL_VERSIONNUM_MAJOR(ver) << "."
|
||||
<< SDL_VERSIONNUM_MINOR(ver) << "."
|
||||
<< SDL_VERSIONNUM_MICRO(ver);
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
static inline bool SDLSupportsURL()
|
||||
{
|
||||
return SDL_VERSION_ATLEAST(2,0,14);
|
||||
}
|
||||
|
||||
static inline bool SDLOpenURL(const string& url)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2,0,14)
|
||||
return SDL_OpenURL(url.c_str()) == 0;
|
||||
#else
|
||||
cerr << "OpenURL requires at least SDL 2.0.14\n";
|
||||
return false;
|
||||
#endif
|
||||
return SDL_OpenURL(url.c_str());
|
||||
}
|
||||
|
||||
#endif // SDL_LIB_HXX
|
||||
|
|
|
@ -104,7 +104,7 @@ bool SoundSDL::openDevice()
|
|||
|
||||
SDL_AudioSpec desired;
|
||||
desired.freq = myAudioSettings.sampleRate();
|
||||
desired.format = AUDIO_F32SYS;
|
||||
desired.format = SDL_AUDIO_F32;
|
||||
desired.channels = 2;
|
||||
desired.samples = static_cast<Uint16>(myAudioSettings.fragmentSize());
|
||||
desired.callback = callback;
|
||||
|
@ -218,7 +218,12 @@ bool SoundSDL::pause(bool enable)
|
|||
const bool wasPaused = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
SDL_PauseAudioDevice(myDevice, enable ? 1 : 0);
|
||||
if (enable ? 1 : 0) {
|
||||
SDL_PauseAudioDevice(myDevice);
|
||||
}
|
||||
else {
|
||||
SDL_ResumeAudioDevice(myDevice);
|
||||
}
|
||||
myWavHandler.pause(enable);
|
||||
}
|
||||
return wasPaused;
|
||||
|
@ -415,7 +420,7 @@ bool SoundSDL::WavHandlerSDL::play(
|
|||
{
|
||||
if(myBuffer)
|
||||
{
|
||||
SDL_FreeWAV(myBuffer);
|
||||
SDL_free(myBuffer);
|
||||
myBuffer = nullptr;
|
||||
}
|
||||
SDL_zero(mySpec);
|
||||
|
@ -457,7 +462,7 @@ void SoundSDL::WavHandlerSDL::stop()
|
|||
// Clean up
|
||||
myRemaining = 0;
|
||||
SDL_CloseAudioDevice(myDevice); myDevice = 0;
|
||||
SDL_FreeWAV(myBuffer); myBuffer = nullptr;
|
||||
SDL_free(myBuffer); myBuffer = nullptr;
|
||||
}
|
||||
if(myCvtBuffer)
|
||||
{
|
||||
|
@ -537,7 +542,12 @@ SoundSDL::WavHandlerSDL::~WavHandlerSDL()
|
|||
void SoundSDL::WavHandlerSDL::pause(bool state) const
|
||||
{
|
||||
if(myDevice)
|
||||
SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
|
||||
if (state ? 1 : 0) {
|
||||
SDL_PauseAudioDevice(myDevice);
|
||||
}
|
||||
else {
|
||||
SDL_ResumeAudioDevice(myDevice);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -221,16 +221,16 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
|||
KBDK_F23 = 114,
|
||||
KBDK_F24 = 115,
|
||||
KBDK_EXECUTE = 116,
|
||||
KBDK_HELP = 117,
|
||||
KBDK_MENU = 118,
|
||||
KBDK_HELP = 117, /**< AL Integrated Help Center */
|
||||
KBDK_MENU = 118, /**< Menu (show menu) */
|
||||
KBDK_SELECT = 119,
|
||||
KBDK_STOP = 120,
|
||||
KBDK_AGAIN = 121, /**< redo */
|
||||
KBDK_UNDO = 122,
|
||||
KBDK_CUT = 123,
|
||||
KBDK_COPY = 124,
|
||||
KBDK_PASTE = 125,
|
||||
KBDK_FIND = 126,
|
||||
KBDK_STOP = 120, /**< AC Stop */
|
||||
KBDK_AGAIN = 121, /**< AC Redo/Repeat */
|
||||
KBDK_UNDO = 122, /**< AC Undo */
|
||||
KBDK_CUT = 123, /**< AC Cut */
|
||||
KBDK_COPY = 124, /**< AC Copy */
|
||||
KBDK_PASTE = 125, /**< AC Paste */
|
||||
KBDK_FIND = 126, /**< AC Find */
|
||||
KBDK_MUTE = 127,
|
||||
KBDK_VOLUMEUP = 128,
|
||||
KBDK_VOLUMEDOWN = 129,
|
||||
|
@ -261,9 +261,9 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
|||
KBDK_LANG8 = 151, /**< reserved */
|
||||
KBDK_LANG9 = 152, /**< reserved */
|
||||
|
||||
KBDK_ALTERASE = 153, /**< Erase-Eaze */
|
||||
KBDK_ALTERASE = 153, /**< Erase-Eaze */
|
||||
KBDK_SYSREQ = 154,
|
||||
KBDK_CANCEL = 155,
|
||||
KBDK_CANCEL = 155, /**< AC Cancel */
|
||||
KBDK_CLEAR = 156,
|
||||
KBDK_PRIOR = 157,
|
||||
KBDK_RETURN2 = 158,
|
||||
|
@ -330,10 +330,10 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
|||
KBDK_RALT = 230, /**< alt gr, option */
|
||||
KBDK_RGUI = 231, /**< windows, command (apple), meta */
|
||||
|
||||
KBDK_MODE = 257, /**< ALT-GR(aph) key on non-American keyboards
|
||||
* This is like pressing KBDK_RALT + KBDK_RCTRL
|
||||
* on some keyboards
|
||||
*/
|
||||
KBDK_MODE = 257, /**< I'm not sure if this is really not covered
|
||||
* by any of the above, but since there's a
|
||||
* special SDL_KMOD_MODE for it I'm adding it here
|
||||
*/
|
||||
|
||||
/* @} *//* Usage page 0x07 */
|
||||
|
||||
|
@ -341,77 +341,98 @@ enum StellaKey // NOLINT: use 32-bit, even though 16-bit is sufficient
|
|||
* \name Usage page 0x0C
|
||||
*
|
||||
* These values are mapped from usage page 0x0C (USB consumer page).
|
||||
*
|
||||
* There are way more keys in the spec than we can represent in the
|
||||
* current scancode range, so pick the ones that commonly come up in
|
||||
* real world usage.
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
KBDK_AUDIONEXT = 258,
|
||||
KBDK_AUDIOPREV = 259,
|
||||
KBDK_AUDIOSTOP = 260,
|
||||
KBDK_AUDIOPLAY = 261,
|
||||
KBDK_AUDIOMUTE = 262,
|
||||
KBDK_MEDIASELECT = 263,
|
||||
KBDK_WWW = 264,
|
||||
KBDK_MAIL = 265,
|
||||
KBDK_CALCULATOR = 266,
|
||||
KBDK_COMPUTER = 267,
|
||||
KBDK_AC_SEARCH = 268,
|
||||
KBDK_AC_HOME = 269,
|
||||
KBDK_AC_BACK = 270,
|
||||
KBDK_AC_FORWARD = 271,
|
||||
KBDK_AC_STOP = 272,
|
||||
KBDK_AC_REFRESH = 273,
|
||||
KBDK_AC_BOOKMARKS = 274,
|
||||
KBDK_SLEEP = 258, /**< Sleep */
|
||||
KBDK_WAKE = 259, /**< Wake */
|
||||
|
||||
KBDK_CHANNEL_INCREMENT = 260, /**< Channel Increment */
|
||||
KBDK_CHANNEL_DECREMENT = 261, /**< Channel Decrement */
|
||||
|
||||
KBDK_MEDIA_PLAY = 262, /**< Play */
|
||||
KBDK_MEDIA_PAUSE = 263, /**< Pause */
|
||||
KBDK_MEDIA_RECORD = 264, /**< Record */
|
||||
KBDK_MEDIA_FAST_FORWARD = 265, /**< Fast Forward */
|
||||
KBDK_MEDIA_REWIND = 266, /**< Rewind */
|
||||
KBDK_MEDIA_NEXT_TRACK = 267, /**< Next Track */
|
||||
KBDK_MEDIA_PREVIOUS_TRACK = 268, /**< Previous Track */
|
||||
KBDK_MEDIA_STOP = 269, /**< Stop */
|
||||
KBDK_MEDIA_EJECT = 270, /**< Eject */
|
||||
KBDK_MEDIA_PLAY_PAUSE = 271, /**< Play / Pause */
|
||||
KBDK_MEDIA_SELECT = 272, /* Media Select */
|
||||
|
||||
KBDK_AC_NEW = 273, /**< AC New */
|
||||
KBDK_AC_OPEN = 274, /**< AC Open */
|
||||
KBDK_AC_CLOSE = 275, /**< AC Close */
|
||||
KBDK_AC_EXIT = 276, /**< AC Exit */
|
||||
KBDK_AC_SAVE = 277, /**< AC Save */
|
||||
KBDK_AC_PRINT = 278, /**< AC Print */
|
||||
KBDK_AC_PROPERTIES = 279, /**< AC Properties */
|
||||
|
||||
KBDK_AC_SEARCH = 280, /**< AC Search */
|
||||
KBDK_AC_HOME = 281, /**< AC Home */
|
||||
KBDK_AC_BACK = 282, /**< AC Back */
|
||||
KBDK_AC_FORWARD = 283, /**< AC Forward */
|
||||
KBDK_AC_STOP = 284, /**< AC Stop */
|
||||
KBDK_AC_REFRESH = 285, /**< AC Refresh */
|
||||
KBDK_AC_BOOKMARKS = 286, /**< AC Bookmarks */
|
||||
|
||||
/* @} *//* Usage page 0x0C */
|
||||
|
||||
|
||||
/**
|
||||
* \name Walther keys
|
||||
* \name Mobile keys
|
||||
*
|
||||
* These are values that Christian Walther added (for mac keyboard?).
|
||||
* These are values that are often used on mobile phones.
|
||||
*/
|
||||
/* @{ */
|
||||
|
||||
KBDK_BRIGHTNESSDOWN = 275,
|
||||
KBDK_BRIGHTNESSUP = 276,
|
||||
KBDK_DISPLAYSWITCH = 277, /**< display mirroring/dual display
|
||||
switch, video mode switch */
|
||||
KBDK_KBDILLUMTOGGLE = 278,
|
||||
KBDK_KBDILLUMDOWN = 279,
|
||||
KBDK_KBDILLUMUP = 280,
|
||||
KBDK_EJECT = 281,
|
||||
KBDK_SLEEP = 282,
|
||||
KBDK_SOFTLEFT = 287, /**< Usually situated below the display on phones and
|
||||
used as a multi-function feature key for selecting
|
||||
a software defined function shown on the bottom left
|
||||
of the display. */
|
||||
KBDK_SOFTRIGHT = 288, /**< Usually situated below the display on phones and
|
||||
used as a multi-function feature key for selecting
|
||||
a software defined function shown on the bottom right
|
||||
of the display. */
|
||||
KBDK_CALL = 289, /**< Used for accepting phone calls. */
|
||||
KBDK_ENDCALL = 290, /**< Used for rejecting phone calls. */
|
||||
|
||||
KBDK_APP1 = 283,
|
||||
KBDK_APP2 = 284,
|
||||
|
||||
/* @} *//* Walther keys */
|
||||
/* @} *//* Mobile keys */
|
||||
|
||||
/* Add any other keys here. */
|
||||
|
||||
KBDK_LAST = 512 /**< not a key, just marks the number of scancodes
|
||||
for array bounds */
|
||||
KBDK_RESERVED = 400, /**< 400-500 reserved for dynamic keycodes */
|
||||
|
||||
KBDK_COUNT = 512 /**< not a key, just marks the number of scancodes for array bounds */
|
||||
};
|
||||
|
||||
// This comes directly from SDL_keycode.h
|
||||
enum StellaMod: uInt16
|
||||
{
|
||||
KBDM_NONE = 0x0000,
|
||||
KBDM_LSHIFT = 0x0001,
|
||||
KBDM_RSHIFT = 0x0002,
|
||||
KBDM_LCTRL = 0x0040,
|
||||
KBDM_RCTRL = 0x0080,
|
||||
KBDM_LALT = 0x0100,
|
||||
KBDM_RALT = 0x0200,
|
||||
KBDM_LGUI = 0x0400,
|
||||
KBDM_RGUI = 0x0800,
|
||||
KBDM_NUM = 0x1000,
|
||||
KBDM_CAPS = 0x2000,
|
||||
KBDM_MODE = 0x4000,
|
||||
KBDM_RESERVED = 0x8000,
|
||||
KBDM_CTRL = (KBDM_LCTRL|KBDM_RCTRL),
|
||||
KBDM_SHIFT = (KBDM_LSHIFT|KBDM_RSHIFT),
|
||||
KBDM_ALT = (KBDM_LALT|KBDM_RALT),
|
||||
KBDM_GUI = (KBDM_LGUI|KBDM_RGUI)
|
||||
KBDM_NONE = 0x0000U, /**< no modifier is applicable. */
|
||||
KBDM_LSHIFT = 0x0001U, /**< the left Shift key is down. */
|
||||
KBDM_RSHIFT = 0x0002U, /**< the right Shift key is down. */
|
||||
KBDM_LEVEL5 = 0x0004U, /**< the Level 5 Shift key is down. */
|
||||
KBDM_LCTRL = 0x0040U, /**< the left Ctrl (Control) key is down. */
|
||||
KBDM_RCTRL = 0x0080U, /**< the right Ctrl (Control) key is down. */
|
||||
KBDM_LALT = 0x0100U, /**< the left Alt key is down. */
|
||||
KBDM_RALT = 0x0200U, /**< the right Alt key is down. */
|
||||
KBDM_LGUI = 0x0400U, /**< the left GUI key (often the Windows key) is down. */
|
||||
KBDM_RGUI = 0x0800U, /**< the right GUI key (often the Windows key) is down. */
|
||||
KBDM_NUM = 0x1000U, /**< the Num Lock key (may be located on an extended keypad) is down. */
|
||||
KBDM_CAPS = 0x2000U, /**< the Caps Lock key is down. */
|
||||
KBDM_MODE = 0x4000U, /**< the !AltGr key is down. */
|
||||
KBDM_SCROLL = 0x8000U, /**< the Scroll Lock key is down. */
|
||||
KBDM_CTRL = (KBDM_LCTRL | KBDM_RCTRL), /**< Any Ctrl key is down. */
|
||||
KBDM_SHIFT = (KBDM_LSHIFT | KBDM_RSHIFT), /**< Any Shift key is down. */
|
||||
KBDM_ALT = (KBDM_LALT | KBDM_RALT), /**< Any Alt key is down. */
|
||||
KBDM_GUI = (KBDM_LGUI | KBDM_RGUI) /**< Any GUI key is down. */
|
||||
};
|
||||
|
||||
// Test if specified modifier is pressed
|
||||
|
|
|
@ -29,17 +29,17 @@ void VideoModeHandler::setImageSize(const Common::Size& image)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VideoModeHandler::setDisplaySize(const Common::Size& display, Int32 fsIndex)
|
||||
void VideoModeHandler::setDisplaySize(const Common::Size& display, bool fullscreen)
|
||||
{
|
||||
myDisplay = display;
|
||||
myFSIndex = fsIndex;
|
||||
myFullscreen = fullscreen;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const VideoModeHandler::Mode&
|
||||
VideoModeHandler::buildMode(const Settings& settings, bool inTIAMode, Bezel::Info bezelInfo)
|
||||
{
|
||||
const bool windowedRequested = myFSIndex == -1;
|
||||
const bool windowedRequested = !myFullscreen;
|
||||
|
||||
// TIA mode allows zooming at non-integral factors in most cases
|
||||
if(inTIAMode)
|
||||
|
@ -53,7 +53,7 @@ const VideoModeHandler::Mode&
|
|||
// Image and screen (aka window) dimensions are the same
|
||||
// Overscan is not applicable in this mode
|
||||
myMode = Mode(myImage.w, myImage.h,
|
||||
Mode::Stretch::Fill, myFSIndex,
|
||||
Mode::Stretch::Fill, myFullscreen,
|
||||
desc.view(), zoom, bezelInfo);
|
||||
}
|
||||
else
|
||||
|
@ -74,7 +74,7 @@ const VideoModeHandler::Mode&
|
|||
{
|
||||
myMode = Mode(myImage.w, myImage.h,
|
||||
myDisplay.w, myDisplay.h,
|
||||
Mode::Stretch::Preserve, myFSIndex,
|
||||
Mode::Stretch::Preserve, myFullscreen,
|
||||
"Fullscreen: Preserve aspect, no stretch",
|
||||
zoom, overscan, bezelInfo);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ const VideoModeHandler::Mode&
|
|||
{
|
||||
myMode = Mode(myImage.w, myImage.h,
|
||||
myDisplay.w, myDisplay.h,
|
||||
Mode::Stretch::Fill, myFSIndex,
|
||||
Mode::Stretch::Fill, myFullscreen,
|
||||
"Fullscreen: Ignore aspect, full stretch",
|
||||
zoom, overscan, bezelInfo);
|
||||
}
|
||||
|
@ -94,31 +94,31 @@ const VideoModeHandler::Mode&
|
|||
myMode = Mode(myImage.w, myImage.h, Mode::Stretch::None);
|
||||
else
|
||||
myMode = Mode(myImage.w, myImage.h, myDisplay.w, myDisplay.h,
|
||||
Mode::Stretch::None, myFSIndex);
|
||||
Mode::Stretch::None, myFullscreen);
|
||||
}
|
||||
return myMode;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, Stretch smode,
|
||||
Int32 fsindex, string_view desc,
|
||||
bool fullscreen, string_view desc,
|
||||
double zoomLevel, Bezel::Info bezelInfo)
|
||||
: Mode(iw, ih, iw, ih, smode, fsindex, desc, zoomLevel, 1., bezelInfo)
|
||||
: Mode(iw, ih, iw, ih, smode, fullscreen, desc, zoomLevel, 1., bezelInfo)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
||||
Stretch smode, Int32 fsindex, string_view desc,
|
||||
Stretch smode, bool fs, string_view desc,
|
||||
double zoomLevel, double overscan, Bezel::Info bezelInfo)
|
||||
: screenS{sw, sh},
|
||||
stretch{smode},
|
||||
description{desc},
|
||||
zoom{zoomLevel}, //hZoom{zoomLevel}, vZoom{zoomLevel},
|
||||
fsIndex{fsindex}
|
||||
fullscreen{fs}
|
||||
{
|
||||
// Now resize based on windowed/fullscreen mode and stretch factor
|
||||
if(fsIndex != -1) // fullscreen mode
|
||||
if(fullscreen)
|
||||
{
|
||||
switch(stretch)
|
||||
{
|
||||
|
@ -174,9 +174,9 @@ VideoModeHandler::Mode::Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
|||
const uInt32 wx = bezelInfo.window().x() * iw / bezelInfo.window().w();
|
||||
const uInt32 wy = bezelInfo.window().y() * ih / bezelInfo.window().h();
|
||||
const uInt32 bezelW = std::min(screenS.w,
|
||||
static_cast<uInt32>(std::round(iw * bezelInfo.ratioW())));
|
||||
static_cast<uInt32>(std::round(iw * bezelInfo.ratioW())));
|
||||
const uInt32 bezelH = std::min(screenS.h,
|
||||
static_cast<uInt32>(std::round(ih * bezelInfo.ratioH())));
|
||||
static_cast<uInt32>(std::round(ih * bezelInfo.ratioH())));
|
||||
// Center image (no bezel) or move image relative to centered bezel
|
||||
imageR.moveTo(((screenS.w - bezelW) >> 1) + wx, ((screenS.h - bezelH) >> 1) + wy);
|
||||
|
||||
|
|
|
@ -46,14 +46,14 @@ class VideoModeHandler
|
|||
Stretch stretch{Mode::Stretch::None};
|
||||
string description;
|
||||
double zoom{1.};
|
||||
Int32 fsIndex{-1}; // -1 indicates windowed mode
|
||||
bool fullscreen{false}; // false indicates windowed mode
|
||||
|
||||
Mode() = default;
|
||||
Mode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh, Stretch smode,
|
||||
Int32 fsindex = -1, string_view desc = "",
|
||||
bool fullscreen = false, string_view desc = "",
|
||||
double zoomLevel = 1., double overscan = 1.,
|
||||
Bezel::Info bezelInfo = Bezel::Info());
|
||||
Mode(uInt32 iw, uInt32 ih, Stretch smode, Int32 fsindex = -1,
|
||||
Mode(uInt32 iw, uInt32 ih, Stretch smode, bool fullscreen = false,
|
||||
string_view desc = "", double zoomLevel = 1.,
|
||||
Bezel::Info bezelInfo = Bezel::Info());
|
||||
|
||||
|
@ -63,7 +63,7 @@ class VideoModeHandler
|
|||
<< " stretch=" << (vm.stretch == Stretch::Preserve ? "preserve" :
|
||||
vm.stretch == Stretch::Fill ? "fill" : "none")
|
||||
<< " desc=" << vm.description << " zoom=" << vm.zoom
|
||||
<< " fsIndex= " << vm.fsIndex;
|
||||
<< " fullscreen= " << vm.fullscreen;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
@ -84,10 +84,10 @@ class VideoModeHandler
|
|||
Set the size of the display. This could be either the desktop size,
|
||||
or the size of the monitor currently active.
|
||||
|
||||
@param display The dimensions of the enclosing display
|
||||
@param fsIndex Fullscreen mode in use (-1 indicates windowed mode)
|
||||
@param display The dimensions of the enclosing display
|
||||
@param fullscreen Whether to use fullscreen or windowed mode
|
||||
*/
|
||||
void setDisplaySize(const Common::Size& display, Int32 fsIndex = -1);
|
||||
void setDisplaySize(const Common::Size& display, bool fullscreen);
|
||||
|
||||
/**
|
||||
Build a video mode based on the given parameters, assuming that
|
||||
|
@ -103,7 +103,7 @@ class VideoModeHandler
|
|||
|
||||
private:
|
||||
Common::Size myImage, myDisplay;
|
||||
Int32 myFSIndex{-1};
|
||||
bool myFullscreen{false};
|
||||
|
||||
Mode myMode;
|
||||
|
||||
|
|
|
@ -726,16 +726,12 @@ NLOHMANN_JSON_SERIALIZE_ENUM(StellaKey, {
|
|||
{StellaKey::KBDK_RALT, "ralt"},
|
||||
{StellaKey::KBDK_RGUI, "rgui"},
|
||||
{StellaKey::KBDK_MODE, "mode"},
|
||||
{StellaKey::KBDK_AUDIONEXT, "audionext"},
|
||||
{StellaKey::KBDK_AUDIOPREV, "audioprev"},
|
||||
{StellaKey::KBDK_AUDIOSTOP, "audiostop"},
|
||||
{StellaKey::KBDK_AUDIOPLAY, "audioplay"},
|
||||
{StellaKey::KBDK_AUDIOMUTE, "audiomute"},
|
||||
{StellaKey::KBDK_MEDIASELECT, "mediaselect"},
|
||||
{StellaKey::KBDK_WWW, "www"},
|
||||
{StellaKey::KBDK_MAIL, "mail"},
|
||||
{StellaKey::KBDK_CALCULATOR, "calculator"},
|
||||
{StellaKey::KBDK_COMPUTER, "computer"},
|
||||
{StellaKey::KBDK_MEDIA_NEXT_TRACK, "audionext"},
|
||||
{StellaKey::KBDK_MEDIA_PREVIOUS_TRACK, "audioprev"},
|
||||
{StellaKey::KBDK_MEDIA_STOP, "audiostop"},
|
||||
{StellaKey::KBDK_MEDIA_PLAY, "audioplay"},
|
||||
{StellaKey::KBDK_MUTE, "audiomute"},
|
||||
{StellaKey::KBDK_MEDIA_SELECT, "mediaselect"},
|
||||
{StellaKey::KBDK_AC_SEARCH, "ac_search"},
|
||||
{StellaKey::KBDK_AC_HOME, "ac_home"},
|
||||
{StellaKey::KBDK_AC_BACK, "ac_back"},
|
||||
|
@ -743,17 +739,9 @@ NLOHMANN_JSON_SERIALIZE_ENUM(StellaKey, {
|
|||
{StellaKey::KBDK_AC_STOP, "ac_stop"},
|
||||
{StellaKey::KBDK_AC_REFRESH, "ac_refresh"},
|
||||
{StellaKey::KBDK_AC_BOOKMARKS, "ac_bookmarks"},
|
||||
{StellaKey::KBDK_BRIGHTNESSDOWN, "brightnessdown"},
|
||||
{StellaKey::KBDK_BRIGHTNESSUP, "brightnessup"},
|
||||
{StellaKey::KBDK_DISPLAYSWITCH, "displayswitch"},
|
||||
{StellaKey::KBDK_KBDILLUMTOGGLE, "kbdillumtoggle"},
|
||||
{StellaKey::KBDK_KBDILLUMDOWN, "kbdillumdown"},
|
||||
{StellaKey::KBDK_KBDILLUMUP, "kbdillumup"},
|
||||
{StellaKey::KBDK_EJECT, "eject"},
|
||||
{StellaKey::KBDK_MEDIA_EJECT, "eject"},
|
||||
{StellaKey::KBDK_SLEEP, "sleep"},
|
||||
{StellaKey::KBDK_APP1, "app1"},
|
||||
{StellaKey::KBDK_APP2, "app2"},
|
||||
{StellaKey::KBDK_LAST, "last"}
|
||||
{StellaKey::KBDK_COUNT, "last"}
|
||||
})
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(StellaMod, {
|
||||
|
@ -769,7 +757,6 @@ NLOHMANN_JSON_SERIALIZE_ENUM(StellaMod, {
|
|||
{StellaMod::KBDM_NUM, "num"},
|
||||
{StellaMod::KBDM_CAPS, "caps"},
|
||||
{StellaMod::KBDM_MODE, "mode"},
|
||||
{StellaMod::KBDM_RESERVED, "reserved"},
|
||||
{StellaMod::KBDM_CTRL, "ctrl"},
|
||||
{StellaMod::KBDM_SHIFT, "shift"},
|
||||
{StellaMod::KBDM_ALT, "alt"},
|
||||
|
|
|
@ -49,14 +49,17 @@ void BilinearBlitter::reinitialize(
|
|||
myStaticData == staticData
|
||||
);
|
||||
|
||||
myStaticData = staticData;
|
||||
mySrcRect = srcRect;
|
||||
myAttributes = attributes;
|
||||
myAttributes = attributes;
|
||||
myStaticData = staticData;
|
||||
|
||||
myDstRect.x = myFB.scaleX(destRect.x);
|
||||
myDstRect.y = myFB.scaleY(destRect.y);
|
||||
myDstRect.w = myFB.scaleX(destRect.w);
|
||||
myDstRect.h = myFB.scaleY(destRect.h);
|
||||
mySrcRect = srcRect;
|
||||
SDL_RectToFRect(&mySrcRect, &mySrcFRect);
|
||||
|
||||
myDstRect.x = myFB.scaleX(destRect.x);
|
||||
myDstRect.y = myFB.scaleY(destRect.y);
|
||||
myDstRect.w = myFB.scaleX(destRect.w);
|
||||
myDstRect.h = myFB.scaleY(destRect.h);
|
||||
SDL_RectToFRect(&myDstRect, &myDstFRect);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -68,7 +71,9 @@ void BilinearBlitter::free()
|
|||
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
const std::array<SDL_Texture*, 2> textures = { myTexture, mySecondaryTexture };
|
||||
const std::array<SDL_Texture*, 2> textures = {
|
||||
myTexture, mySecondaryTexture
|
||||
};
|
||||
for (SDL_Texture* texture: textures) {
|
||||
if (!texture) continue;
|
||||
|
||||
|
@ -93,10 +98,9 @@ void BilinearBlitter::blit(SDL_Surface& surface)
|
|||
mySecondaryTexture = texture;
|
||||
}
|
||||
|
||||
SDL_RenderCopy(myFB.renderer(), texture, &mySrcRect, &myDstRect);
|
||||
SDL_RenderTexture(myFB.renderer(), texture, &mySrcFRect, &myDstFRect);
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void BilinearBlitter::recreateTexturesIfNecessary()
|
||||
{
|
||||
|
@ -110,16 +114,22 @@ void BilinearBlitter::recreateTexturesIfNecessary()
|
|||
free();
|
||||
}
|
||||
|
||||
const SDL_TextureAccess texAccess = myStaticData == nullptr ? SDL_TEXTUREACCESS_STREAMING : SDL_TEXTUREACCESS_STATIC;
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, myInterpolate ? "1" : "0");
|
||||
const SDL_TextureAccess texAccess = myStaticData == nullptr
|
||||
? SDL_TEXTUREACCESS_STREAMING
|
||||
: SDL_TEXTUREACCESS_STATIC;
|
||||
|
||||
myTexture = SDL_CreateTexture(myFB.renderer(), myFB.pixelFormat().format,
|
||||
texAccess, mySrcRect.w, mySrcRect.h);
|
||||
SDL_SetTextureScaleMode(myTexture, myInterpolate
|
||||
? SDL_SCALEMODE_LINEAR : SDL_SCALEMODE_NEAREST);
|
||||
|
||||
if (myStaticData == nullptr) {
|
||||
mySecondaryTexture = SDL_CreateTexture(myFB.renderer(), myFB.pixelFormat().format,
|
||||
mySecondaryTexture = SDL_CreateTexture(myFB.renderer(),
|
||||
myFB.pixelFormat().format,
|
||||
texAccess, mySrcRect.w, mySrcRect.h);
|
||||
SDL_SetTextureScaleMode(mySecondaryTexture, myInterpolate
|
||||
? SDL_SCALEMODE_LINEAR
|
||||
: SDL_SCALEMODE_NEAREST);
|
||||
} else {
|
||||
mySecondaryTexture = nullptr;
|
||||
SDL_UpdateTexture(myTexture, nullptr, myStaticData->pixels, myStaticData->pitch);
|
||||
|
|
|
@ -46,6 +46,7 @@ class BilinearBlitter : public Blitter {
|
|||
SDL_Texture* myTexture{nullptr};
|
||||
SDL_Texture* mySecondaryTexture{nullptr};
|
||||
SDL_Rect mySrcRect{0, 0, 0, 0}, myDstRect{0, 0, 0, 0};
|
||||
SDL_FRect mySrcFRect{0.F, 0.F, 0.F, 0.F}, myDstFRect{0.F, 0.F, 0.F, 0.F};
|
||||
FBSurface::Attributes myAttributes;
|
||||
|
||||
bool myInterpolate{false};
|
||||
|
|
|
@ -19,6 +19,19 @@
|
|||
#include "ThreadDebugging.hxx"
|
||||
#include "QisBlitter.hxx"
|
||||
|
||||
static void P(const char* str, const SDL_Rect r, const SDL_FRect fr)
|
||||
{
|
||||
cerr << str << ": "
|
||||
<< r.x << "," << r.y << " " << r.w << "x" << r.h << " => "
|
||||
<< fr.x << "," << fr.y << " " << fr.w << "x" << fr.h << '\n';
|
||||
}
|
||||
static void PF(const char* str, const SDL_FRect r, const SDL_FRect fr)
|
||||
{
|
||||
cerr << str << ": "
|
||||
<< r.x << "," << r.y << " " << r.w << "x" << r.h << " => "
|
||||
<< fr.x << "," << fr.y << " " << fr.w << "x" << fr.h << '\n';
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
QisBlitter::QisBlitter(FBBackendSDL& fb)
|
||||
: myFB{fb}
|
||||
|
@ -56,14 +69,17 @@ void QisBlitter::reinitialize(
|
|||
myStaticData == staticData
|
||||
);
|
||||
|
||||
myStaticData = staticData;
|
||||
mySrcRect = srcRect;
|
||||
myAttributes = attributes;
|
||||
myAttributes = attributes;
|
||||
myStaticData = staticData;
|
||||
|
||||
myDstRect.x = myFB.scaleX(destRect.x);
|
||||
myDstRect.y = myFB.scaleY(destRect.y);
|
||||
myDstRect.w = myFB.scaleX(destRect.w);
|
||||
myDstRect.h = myFB.scaleY(destRect.h);
|
||||
mySrcRect = srcRect;
|
||||
SDL_RectToFRect(&mySrcRect, &mySrcFRect);
|
||||
|
||||
myDstRect.x = myFB.scaleX(destRect.x);
|
||||
myDstRect.y = myFB.scaleY(destRect.y);
|
||||
myDstRect.w = myFB.scaleX(destRect.w);
|
||||
myDstRect.h = myFB.scaleY(destRect.h);
|
||||
SDL_RectToFRect(&myDstRect, &myDstFRect);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -76,7 +92,7 @@ void QisBlitter::free()
|
|||
ASSERT_MAIN_THREAD;
|
||||
|
||||
const std::array<SDL_Texture*, 3> textures = {
|
||||
mySrcTexture, myIntermediateTexture, mySecondaryIntermedateTexture
|
||||
mySrcTexture, myIntermediateTexture, mySecondaryIntermediateTexture
|
||||
};
|
||||
for (SDL_Texture* texture: textures) {
|
||||
if (!texture) continue;
|
||||
|
@ -101,15 +117,16 @@ void QisBlitter::blit(SDL_Surface& surface)
|
|||
|
||||
blitToIntermediate();
|
||||
|
||||
myIntermediateTexture = mySecondaryIntermedateTexture;
|
||||
mySecondaryIntermedateTexture = intermediateTexture;
|
||||
myIntermediateTexture = mySecondaryIntermediateTexture;
|
||||
mySecondaryIntermediateTexture = intermediateTexture;
|
||||
|
||||
SDL_Texture* temporary = mySrcTexture;
|
||||
mySrcTexture = mySecondarySrcTexture;
|
||||
mySecondarySrcTexture = temporary;
|
||||
}
|
||||
|
||||
SDL_RenderCopy(myFB.renderer(), intermediateTexture, &myIntermediateRect, &myDstRect);
|
||||
SDL_RenderTexture(myFB.renderer(), intermediateTexture,
|
||||
&myIntermediateFRect, &myDstFRect);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -117,15 +134,16 @@ void QisBlitter::blitToIntermediate()
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
SDL_Rect r = mySrcRect;
|
||||
r.x = r.y = 0;
|
||||
SDL_FRect r{};
|
||||
SDL_RectToFRect(&mySrcRect, &r);
|
||||
r.x = r.y = 0.F;
|
||||
|
||||
SDL_SetRenderTarget(myFB.renderer(), myIntermediateTexture);
|
||||
|
||||
SDL_SetRenderDrawColor(myFB.renderer(), 0, 0, 0, 255);
|
||||
SDL_RenderClear(myFB.renderer());
|
||||
|
||||
SDL_RenderCopy(myFB.renderer(), mySrcTexture, &r, &myIntermediateRect);
|
||||
SDL_RenderTexture(myFB.renderer(), mySrcTexture, &r, &myIntermediateFRect);
|
||||
|
||||
SDL_SetRenderTarget(myFB.renderer(), nullptr);
|
||||
}
|
||||
|
@ -143,36 +161,40 @@ void QisBlitter::recreateTexturesIfNecessary()
|
|||
free();
|
||||
}
|
||||
|
||||
const SDL_TextureAccess texAccess =
|
||||
myStaticData == nullptr ? SDL_TEXTUREACCESS_STREAMING : SDL_TEXTUREACCESS_STATIC;
|
||||
const SDL_TextureAccess texAccess = myStaticData == nullptr
|
||||
? SDL_TEXTUREACCESS_STREAMING
|
||||
: SDL_TEXTUREACCESS_STATIC;
|
||||
|
||||
myIntermediateRect.w = (myDstRect.w / mySrcRect.w) * mySrcRect.w;
|
||||
myIntermediateRect.h = (myDstRect.h / mySrcRect.h) * mySrcRect.h;
|
||||
myIntermediateRect.x = 0;
|
||||
myIntermediateRect.y = 0;
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
|
||||
SDL_RectToFRect(&myIntermediateRect, &myIntermediateFRect);
|
||||
|
||||
mySrcTexture = SDL_CreateTexture(myFB.renderer(), myFB.pixelFormat().format,
|
||||
texAccess, mySrcRect.w, mySrcRect.h);
|
||||
SDL_SetTextureScaleMode(mySrcTexture, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
if (myStaticData == nullptr) {
|
||||
mySecondarySrcTexture = SDL_CreateTexture(myFB.renderer(), myFB.pixelFormat().format,
|
||||
texAccess, mySrcRect.w, mySrcRect.h);
|
||||
mySecondarySrcTexture = SDL_CreateTexture(myFB.renderer(),
|
||||
myFB.pixelFormat().format, texAccess, mySrcRect.w, mySrcRect.h);
|
||||
SDL_SetTextureScaleMode(mySecondarySrcTexture, SDL_SCALEMODE_NEAREST);
|
||||
} else {
|
||||
mySecondarySrcTexture = nullptr;
|
||||
}
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||
|
||||
myIntermediateTexture = SDL_CreateTexture(myFB.renderer(), myFB.pixelFormat().format,
|
||||
SDL_TEXTUREACCESS_TARGET, myIntermediateRect.w, myIntermediateRect.h);
|
||||
SDL_SetTextureScaleMode(myIntermediateTexture, SDL_SCALEMODE_LINEAR);
|
||||
|
||||
if (myStaticData == nullptr) {
|
||||
mySecondaryIntermedateTexture = SDL_CreateTexture(myFB.renderer(), myFB.pixelFormat().format,
|
||||
SDL_TEXTUREACCESS_TARGET, myIntermediateRect.w, myIntermediateRect.h);
|
||||
mySecondaryIntermediateTexture = SDL_CreateTexture(myFB.renderer(),
|
||||
myFB.pixelFormat().format, SDL_TEXTUREACCESS_TARGET,
|
||||
myIntermediateRect.w, myIntermediateRect.h);
|
||||
SDL_SetTextureScaleMode(mySecondaryIntermediateTexture,
|
||||
SDL_SCALEMODE_LINEAR);
|
||||
} else {
|
||||
mySecondaryIntermedateTexture = nullptr;
|
||||
mySecondaryIntermediateTexture = nullptr;
|
||||
SDL_UpdateTexture(mySrcTexture, nullptr, myStaticData->pixels, myStaticData->pitch);
|
||||
|
||||
blitToIntermediate();
|
||||
|
@ -182,7 +204,7 @@ void QisBlitter::recreateTexturesIfNecessary()
|
|||
const auto blendAlpha = static_cast<uInt8>(myAttributes.blendalpha * 2.55);
|
||||
|
||||
const std::array<SDL_Texture*, 2> textures = {
|
||||
myIntermediateTexture, mySecondaryIntermedateTexture
|
||||
myIntermediateTexture, mySecondaryIntermediateTexture
|
||||
};
|
||||
for (SDL_Texture* texture: textures) {
|
||||
if (!texture) continue;
|
||||
|
|
|
@ -49,9 +49,14 @@ class QisBlitter : public Blitter {
|
|||
SDL_Texture* mySrcTexture{nullptr};
|
||||
SDL_Texture* mySecondarySrcTexture{nullptr};
|
||||
SDL_Texture* myIntermediateTexture{nullptr};
|
||||
SDL_Texture* mySecondaryIntermedateTexture{nullptr};
|
||||
SDL_Texture* mySecondaryIntermediateTexture{nullptr};
|
||||
|
||||
SDL_Rect mySrcRect{0, 0, 0, 0}, myIntermediateRect{0, 0, 0, 0}, myDstRect{0, 0, 0, 0};
|
||||
SDL_Rect mySrcRect{0, 0, 0, 0},
|
||||
myIntermediateRect{0, 0, 0, 0},
|
||||
myDstRect{0, 0, 0, 0};
|
||||
SDL_FRect mySrcFRect{0.F, 0.F, 0.F, 0.F},
|
||||
myIntermediateFRect{0.F, 0.F, 0.F, 0.F},
|
||||
myDstFRect{0.F, 0.F, 0.F, 0.F};
|
||||
FBSurface::Attributes myAttributes;
|
||||
|
||||
bool myTexturesAreAllocated{false};
|
||||
|
|
|
@ -191,10 +191,9 @@ class FBBackend
|
|||
This method is called to query the video hardware for the index
|
||||
of the display the current window is displayed on.
|
||||
|
||||
@return The current display index or a negative value if no
|
||||
window is displayed
|
||||
@return The current display id or a 0 if no window is displayed
|
||||
*/
|
||||
virtual Int32 getCurrentDisplayIndex() const = 0;
|
||||
virtual uInt32 getCurrentDisplayID() const = 0;
|
||||
|
||||
/**
|
||||
This method is called to create a surface with the given attributes.
|
||||
|
|
|
@ -135,7 +135,7 @@ int FrameBuffer::displayId(BufferType bufferType) const
|
|||
int display = 0;
|
||||
|
||||
if(bufferType == myBufferType)
|
||||
display = myBackend->getCurrentDisplayIndex();
|
||||
display = myBackend->getCurrentDisplayID();
|
||||
else
|
||||
display = myOSystem.settings().getInt(getDisplayKey(bufferType != BufferType::None
|
||||
? bufferType : myBufferType));
|
||||
|
@ -1096,7 +1096,7 @@ void FrameBuffer::saveCurrentWindowPosition() const
|
|||
if(myBackend)
|
||||
{
|
||||
myOSystem.settings().setValue(
|
||||
getDisplayKey(), myBackend->getCurrentDisplayIndex());
|
||||
getDisplayKey(), myBackend->getCurrentDisplayID());
|
||||
if(myBackend->isCurrentWindowPositioned())
|
||||
myOSystem.settings().setValue(
|
||||
getPositionKey(), myBackend->getCurrentWindowPos());
|
||||
|
@ -1319,12 +1319,12 @@ FBInitStatus FrameBuffer::applyVideoMode()
|
|||
{
|
||||
// Update display size, in case windowed/fullscreen mode has changed
|
||||
const Settings& s = myOSystem.settings();
|
||||
const int display = displayId();
|
||||
const int ID = displayId();
|
||||
|
||||
if(s.getBool("fullscreen"))
|
||||
myVidModeHandler.setDisplaySize(myFullscreenDisplays[display], display);
|
||||
myVidModeHandler.setDisplaySize(myFullscreenDisplays[ID], true);
|
||||
else
|
||||
myVidModeHandler.setDisplaySize(myAbsDesktopSize[display]);
|
||||
myVidModeHandler.setDisplaySize(myAbsDesktopSize[ID], false);
|
||||
|
||||
const bool inTIAMode = myOSystem.eventHandler().inTIAMode();
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ void AboutDialog::handleCommand(CommandSender* sender, int cmd, int data, int id
|
|||
{
|
||||
const string& url = myDesc[id]->getUrl();
|
||||
|
||||
if(url != EmptyString && MediaFactory::supportsURL())
|
||||
if(url != EmptyString)
|
||||
MediaFactory::openURL(url);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ void Dialog::initHelp()
|
|||
_helpWidget->setToolTip("Click or press " + key + " for help.");
|
||||
}
|
||||
|
||||
if(hasHelp() && MediaFactory::supportsURL())
|
||||
if(hasHelp())
|
||||
_helpWidget->clearFlags(Widget::FLAG_INVISIBLE);
|
||||
else
|
||||
_helpWidget->setFlags(Widget::FLAG_INVISIBLE);
|
||||
|
|
|
@ -1378,7 +1378,7 @@ void GameInfoDialog::updateLink()
|
|||
|| startsWithIgnoreCase(link, "https://")
|
||||
|| startsWithIgnoreCase(link, "www.");
|
||||
|
||||
myUrlButton->setEnabled(enable && MediaFactory::supportsURL());
|
||||
myUrlButton->setEnabled(enable);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -64,7 +64,7 @@ HelpDialog::HelpDialog(OSystem& osystem, DialogContainer& parent,
|
|||
myUpdateButton =
|
||||
new ButtonWidget(this, font, xpos, ypos, updButtonWidth, buttonHeight,
|
||||
"Check for Update" + ELLIPSIS, kUpdateCmd);
|
||||
myUpdateButton->setEnabled(MediaFactory::supportsURL());
|
||||
myUpdateButton->setEnabled(true);
|
||||
wid.push_back(myUpdateButton);
|
||||
|
||||
xpos = _w - closeButtonWidth - HBORDER;
|
||||
|
|
|
@ -277,7 +277,7 @@ void LauncherDialog::addPathWidgets(int& ypos)
|
|||
buttonWidth, buttonHeight, helpIcon, kHelpCmd);
|
||||
const string key = instance().eventHandler().getMappingDesc(Event::UIHelp, EventMode::kMenuMode);
|
||||
myHelpButton->setToolTip("Click for help. (" + key + ")");
|
||||
myHelpButton->setEnabled(MediaFactory::supportsURL());
|
||||
myHelpButton->setEnabled(true);
|
||||
wid.push_back(myHelpButton);
|
||||
}
|
||||
ypos += lineHeight + Dialog::vGap() * 2;
|
||||
|
|
|
@ -104,7 +104,7 @@ class FBBackendLIBRETRO : public FBBackend
|
|||
void readPixels(uInt8*, size_t, const Common::Rect&) const override { }
|
||||
bool isCurrentWindowPositioned() const override { return true; }
|
||||
Common::Point getCurrentWindowPos() const override { return Common::Point{}; }
|
||||
Int32 getCurrentDisplayIndex() const override { return 0; }
|
||||
uInt32 getCurrentDisplayID() const override { return 0; }
|
||||
void clear() override { }
|
||||
bool setVideoMode(const VideoModeHandler::Mode&,
|
||||
int, const Common::Point&) override { return true; }
|
||||
|
|
Loading…
Reference in New Issue