mirror of https://github.com/stella-emu/stella.git
Merge branch 'feature/fix-surfaces'
This commit is contained in:
commit
982e7d18a6
|
@ -200,17 +200,10 @@ void FBSurfaceSDL2::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||||
SDL_FillRect(mySurface, &tmp, 0);
|
SDL_FillRect(mySurface, &tmp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void FBSurfaceSDL2::free()
|
|
||||||
{
|
|
||||||
myBlitter.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::reload()
|
void FBSurfaceSDL2::reload()
|
||||||
{
|
{
|
||||||
free();
|
reinitializeBlitter(true);
|
||||||
reinitializeBlitter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -221,8 +214,6 @@ void FBSurfaceSDL2::resize(uInt32 width, uInt32 height)
|
||||||
if(mySurface)
|
if(mySurface)
|
||||||
SDL_FreeSurface(mySurface);
|
SDL_FreeSurface(mySurface);
|
||||||
|
|
||||||
free();
|
|
||||||
|
|
||||||
// NOTE: Currently, a resize changes a 'static' surface to 'streaming'
|
// NOTE: Currently, a resize changes a 'static' surface to 'streaming'
|
||||||
// No code currently does this, but we should at least check for it
|
// No code currently does this, but we should at least check for it
|
||||||
if(myIsStatic)
|
if(myIsStatic)
|
||||||
|
@ -260,12 +251,15 @@ void FBSurfaceSDL2::createSurface(uInt32 width, uInt32 height,
|
||||||
if(myIsStatic)
|
if(myIsStatic)
|
||||||
SDL_memcpy(mySurface->pixels, data, mySurface->w * mySurface->h * 4);
|
SDL_memcpy(mySurface->pixels, data, mySurface->w * mySurface->h * 4);
|
||||||
|
|
||||||
reinitializeBlitter();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FBSurfaceSDL2::reinitializeBlitter()
|
void FBSurfaceSDL2::reinitializeBlitter(bool force)
|
||||||
{
|
{
|
||||||
|
if (force)
|
||||||
|
myBlitter.reset();
|
||||||
|
|
||||||
if (!myBlitter && myBackend.isInitialized())
|
if (!myBlitter && myBackend.isInitialized())
|
||||||
myBlitter = BlitterFactory::createBlitter(
|
myBlitter = BlitterFactory::createBlitter(
|
||||||
myBackend, scalingAlgorithm(myInterpolationMode));
|
myBackend, scalingAlgorithm(myInterpolationMode));
|
||||||
|
|
|
@ -60,7 +60,6 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
void invalidate() override;
|
void invalidate() override;
|
||||||
void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) override;
|
void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) override;
|
||||||
|
|
||||||
void free() override;
|
|
||||||
void reload() override;
|
void reload() override;
|
||||||
void resize(uInt32 width, uInt32 height) override;
|
void resize(uInt32 width, uInt32 height) override;
|
||||||
|
|
||||||
|
@ -109,7 +108,7 @@ class FBSurfaceSDL2 : public FBSurface
|
||||||
|
|
||||||
void createSurface(uInt32 width, uInt32 height, const uInt32* data);
|
void createSurface(uInt32 width, uInt32 height, const uInt32* data);
|
||||||
|
|
||||||
void reinitializeBlitter();
|
void reinitializeBlitter(bool force = false);
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
FBSurfaceSDL2() = delete;
|
FBSurfaceSDL2() = delete;
|
||||||
|
|
|
@ -350,16 +350,8 @@ class FBSurface
|
||||||
*/
|
*/
|
||||||
virtual void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) = 0;
|
virtual void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
This method should be called to free any resources being used by
|
|
||||||
the surface.
|
|
||||||
*/
|
|
||||||
virtual void free() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This method should be called to reload the surface data/state.
|
This method should be called to reload the surface data/state.
|
||||||
It will normally be called after free().
|
|
||||||
*/
|
*/
|
||||||
virtual void reload() = 0;
|
virtual void reload() = 0;
|
||||||
|
|
||||||
|
|
|
@ -67,11 +67,6 @@ FrameBuffer::FrameBuffer(OSystem& osystem)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
FrameBuffer::~FrameBuffer()
|
FrameBuffer::~FrameBuffer()
|
||||||
{
|
{
|
||||||
// Make sure to free surfaces/textures before destroying the backend itself
|
|
||||||
// Most platforms are fine with doing this in either order, but it seems
|
|
||||||
// that OpenBSD in particular crashes when attempting to destroy textures
|
|
||||||
// *after* the renderer is already destroyed
|
|
||||||
freeSurfaces();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -256,21 +251,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
|
||||||
return FBInitStatus::FailTooLarge;
|
return FBInitStatus::FailTooLarge;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize video mode handler, so it can know what video modes are
|
#ifdef GUI_SUPPORT // TODO: put message stuff in its own class
|
||||||
// appropriate for the requested image size
|
|
||||||
myVidModeHandler.setImageSize(size);
|
|
||||||
|
|
||||||
// Always save, maybe only the mode of the window has changed
|
|
||||||
saveCurrentWindowPosition();
|
|
||||||
myBufferType = type;
|
|
||||||
|
|
||||||
// Initialize video subsystem
|
|
||||||
string pre_about = myBackend->about();
|
|
||||||
FBInitStatus status = applyVideoMode();
|
|
||||||
if(status != FBInitStatus::Success)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
#ifdef GUI_SUPPORT
|
|
||||||
// Erase any messages from a previous run
|
// Erase any messages from a previous run
|
||||||
myMsg.enabled = false;
|
myMsg.enabled = false;
|
||||||
|
|
||||||
|
@ -297,6 +278,20 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize video mode handler, so it can know what video modes are
|
||||||
|
// appropriate for the requested image size
|
||||||
|
myVidModeHandler.setImageSize(size);
|
||||||
|
|
||||||
|
// Always save, maybe only the mode of the window has changed
|
||||||
|
saveCurrentWindowPosition();
|
||||||
|
myBufferType = type;
|
||||||
|
|
||||||
|
// Initialize video subsystem
|
||||||
|
string pre_about = myBackend->about();
|
||||||
|
FBInitStatus status = applyVideoMode();
|
||||||
|
if(status != FBInitStatus::Success)
|
||||||
|
return status;
|
||||||
|
|
||||||
// Print initial usage message, but only print it later if the status has changed
|
// Print initial usage message, but only print it later if the status has changed
|
||||||
if(myInitializedCount == 1)
|
if(myInitializedCount == 1)
|
||||||
{
|
{
|
||||||
|
@ -553,6 +548,7 @@ void FrameBuffer::updateInEmulationMode(float framesPerSecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GUI_SUPPORT
|
#ifdef GUI_SUPPORT
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FrameBuffer::createMessage(const string& message, MessagePosition position, bool force)
|
void FrameBuffer::createMessage(const string& message, MessagePosition position, bool force)
|
||||||
{
|
{
|
||||||
// Only show messages if they've been enabled
|
// Only show messages if they've been enabled
|
||||||
|
@ -866,42 +862,63 @@ void FrameBuffer::setPauseDelay()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
shared_ptr<FBSurface> FrameBuffer::allocateSurface(
|
unique_ptr<FBSurface> FrameBuffer::allocateSurface(
|
||||||
int w, int h, ScalingInterpolation inter, const uInt32* data
|
int w, int h, ScalingInterpolation inter, const uInt32* data)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// Add new surface to the list
|
return myBackend->createSurface(w, h, inter, data);
|
||||||
mySurfaceList.push_back(myBackend->createSurface(w, h, inter, data));
|
|
||||||
|
|
||||||
// And return a pointer to it (pointer should be treated read-only)
|
|
||||||
return mySurfaceList.at(mySurfaceList.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void FrameBuffer::freeSurfaces()
|
|
||||||
{
|
|
||||||
for(auto& s: mySurfaceList)
|
|
||||||
s->free();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void FrameBuffer::reloadSurfaces()
|
|
||||||
{
|
|
||||||
for(auto& s: mySurfaceList)
|
|
||||||
s->reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void FrameBuffer::resetSurfaces()
|
void FrameBuffer::resetSurfaces()
|
||||||
{
|
{
|
||||||
// Free all resources for each surface, then reload them
|
switch(myOSystem.eventHandler().state())
|
||||||
// Due to possible timing and/or synchronization issues, all free()'s
|
{
|
||||||
// are done first, then all reload()'s
|
case EventHandlerState::NONE:
|
||||||
// Any derived FrameBuffer classes that call this method should be
|
case EventHandlerState::EMULATION:
|
||||||
// aware of these restrictions, and act accordingly
|
case EventHandlerState::PAUSE:
|
||||||
|
case EventHandlerState::PLAYBACK:
|
||||||
|
#ifdef GUI_SUPPORT
|
||||||
|
myMsg.surface->reload();
|
||||||
|
myStatsMsg.surface->reload();
|
||||||
|
#endif
|
||||||
|
myTIASurface->resetSurfaces();
|
||||||
|
break;
|
||||||
|
|
||||||
freeSurfaces();
|
#ifdef GUI_SUPPORT
|
||||||
reloadSurfaces();
|
case EventHandlerState::OPTIONSMENU:
|
||||||
|
myOSystem.menu().resetSurfaces();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandlerState::CMDMENU:
|
||||||
|
myOSystem.commandMenu().resetSurfaces();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandlerState::HIGHSCORESMENU:
|
||||||
|
myOSystem.highscoresMenu().resetSurfaces();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandlerState::MESSAGEMENU:
|
||||||
|
myOSystem.messageMenu().resetSurfaces();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandlerState::TIMEMACHINE:
|
||||||
|
myOSystem.timeMachine().resetSurfaces();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandlerState::LAUNCHER:
|
||||||
|
myOSystem.launcher().resetSurfaces();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUGGER_SUPPORT
|
||||||
|
case EventHandlerState::DEBUGGER:
|
||||||
|
myOSystem.debugger().resetSurfaces();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
update(UpdateMode::REDRAW); // force full update
|
update(UpdateMode::REDRAW); // force full update
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ class FrameBuffer
|
||||||
|
|
||||||
@return A pointer to a valid surface object, or nullptr
|
@return A pointer to a valid surface object, or nullptr
|
||||||
*/
|
*/
|
||||||
shared_ptr<FBSurface> allocateSurface(
|
unique_ptr<FBSurface> allocateSurface(
|
||||||
int w,
|
int w,
|
||||||
int h,
|
int h,
|
||||||
ScalingInterpolation inter = ScalingInterpolation::none,
|
ScalingInterpolation inter = ScalingInterpolation::none,
|
||||||
|
@ -384,16 +384,6 @@ class FrameBuffer
|
||||||
string getDisplayKey() const;
|
string getDisplayKey() const;
|
||||||
void saveCurrentWindowPosition() const;
|
void saveCurrentWindowPosition() const;
|
||||||
|
|
||||||
/**
|
|
||||||
Calls 'free()' on all surfaces that the framebuffer knows about.
|
|
||||||
*/
|
|
||||||
void freeSurfaces();
|
|
||||||
|
|
||||||
/**
|
|
||||||
Calls 'reload()' on all surfaces that the framebuffer knows about.
|
|
||||||
*/
|
|
||||||
void reloadSurfaces();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Frees and reloads all surfaces that the framebuffer knows about.
|
Frees and reloads all surfaces that the framebuffer knows about.
|
||||||
*/
|
*/
|
||||||
|
@ -520,7 +510,7 @@ class FrameBuffer
|
||||||
int x{0}, y{0}, w{0}, h{0};
|
int x{0}, y{0}, w{0}, h{0};
|
||||||
MessagePosition position{MessagePosition::BottomCenter};
|
MessagePosition position{MessagePosition::BottomCenter};
|
||||||
ColorId color{kNone};
|
ColorId color{kNone};
|
||||||
shared_ptr<FBSurface> surface;
|
unique_ptr<FBSurface> surface;
|
||||||
bool enabled{false};
|
bool enabled{false};
|
||||||
bool dirty{false};
|
bool dirty{false};
|
||||||
bool showGauge{false};
|
bool showGauge{false};
|
||||||
|
@ -541,9 +531,6 @@ class FrameBuffer
|
||||||
// Maximum TIA zoom level that can be used for this framebuffer
|
// Maximum TIA zoom level that can be used for this framebuffer
|
||||||
float myTIAMaxZoom{1.F};
|
float myTIAMaxZoom{1.F};
|
||||||
|
|
||||||
// Holds a reference to all the surfaces that have been created
|
|
||||||
vector<shared_ptr<FBSurface>> mySurfaceList;
|
|
||||||
|
|
||||||
// Maximum message width [chars]
|
// Maximum message width [chars]
|
||||||
static constexpr int MESSAGE_WIDTH = 56;
|
static constexpr int MESSAGE_WIDTH = 56;
|
||||||
// Maximum gauge bar width [chars]
|
// Maximum gauge bar width [chars]
|
||||||
|
|
|
@ -541,3 +541,12 @@ bool TIASurface::correctAspect() const
|
||||||
{
|
{
|
||||||
return myOSystem.settings().getBool("tia.correct_aspect");
|
return myOSystem.settings().getBool("tia.correct_aspect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void TIASurface::resetSurfaces()
|
||||||
|
{
|
||||||
|
myTiaSurface->reload();
|
||||||
|
mySLineSurface->reload();
|
||||||
|
myBaseTiaSurface->reload();
|
||||||
|
myShadeSurface->reload();
|
||||||
|
}
|
||||||
|
|
|
@ -183,6 +183,11 @@ class TIASurface
|
||||||
*/
|
*/
|
||||||
void updateSurfaceSettings();
|
void updateSurfaceSettings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Issue a 'reload' to each surface.
|
||||||
|
*/
|
||||||
|
void resetSurfaces();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
Average current calculated buffer's pixel with previous calculated buffer's pixel (50:50).
|
Average current calculated buffer's pixel with previous calculated buffer's pixel (50:50).
|
||||||
|
@ -208,7 +213,7 @@ class TIASurface
|
||||||
FrameBuffer& myFB;
|
FrameBuffer& myFB;
|
||||||
TIA* myTIA{nullptr};
|
TIA* myTIA{nullptr};
|
||||||
|
|
||||||
shared_ptr<FBSurface> myTiaSurface, mySLineSurface, myBaseTiaSurface, myShadeSurface;
|
unique_ptr<FBSurface> myTiaSurface, mySLineSurface, myBaseTiaSurface, myShadeSurface;
|
||||||
|
|
||||||
// NTSC object to use in TIA rendering mode
|
// NTSC object to use in TIA rendering mode
|
||||||
NTSCFilter myNTSCFilter;
|
NTSCFilter myNTSCFilter;
|
||||||
|
|
|
@ -583,7 +583,6 @@ void ContextMenu::setArrows()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void ContextMenu::drawDialog()
|
void ContextMenu::drawDialog()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Normally we add widgets and let Dialog::draw() take care of this
|
// Normally we add widgets and let Dialog::draw() take care of this
|
||||||
// logic. But for some reason, this Dialog was written differently
|
// logic. But for some reason, this Dialog was written differently
|
||||||
// by the ScummVM guys, so I'm not going to mess with it.
|
// by the ScummVM guys, so I'm not going to mess with it.
|
||||||
|
|
|
@ -50,23 +50,12 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
|
||||||
const string& title, int x, int y, int w, int h)
|
const string& title, int x, int y, int w, int h)
|
||||||
: GuiObject(instance, parent, *this, x, y, w, h),
|
: GuiObject(instance, parent, *this, x, y, w, h),
|
||||||
_font{font},
|
_font{font},
|
||||||
_title{title}
|
_title{title},
|
||||||
|
_renderCallback{[]() { return; }}
|
||||||
{
|
{
|
||||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG;
|
_flags = Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG;
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
|
|
||||||
// Create shading surface
|
|
||||||
uInt32 data = 0xff000000;
|
|
||||||
|
|
||||||
_shadeSurface = instance.frameBuffer().allocateSurface(
|
|
||||||
1, 1, ScalingInterpolation::sharp, &data);
|
|
||||||
|
|
||||||
FBSurface::Attributes& attr = _shadeSurface->attributes();
|
|
||||||
|
|
||||||
attr.blending = true;
|
|
||||||
attr.blendalpha = 25; // darken background dialogs by 25%
|
|
||||||
_shadeSurface->applyAttributes();
|
|
||||||
|
|
||||||
_toolTip = make_unique<ToolTip>(*this, font);
|
_toolTip = make_unique<ToolTip>(*this, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +162,12 @@ void Dialog::setDirtyChain()
|
||||||
_dirtyChain = true;
|
_dirtyChain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Dialog::resetSurfaces()
|
||||||
|
{
|
||||||
|
_surface->reload();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Dialog::tick()
|
void Dialog::tick()
|
||||||
{
|
{
|
||||||
|
@ -251,11 +246,7 @@ void Dialog::render()
|
||||||
// Update dialog surface; also render any extra surfaces
|
// Update dialog surface; also render any extra surfaces
|
||||||
// Extra surfaces must be rendered afterwards, so they are drawn on top
|
// Extra surfaces must be rendered afterwards, so they are drawn on top
|
||||||
if(_surface->render())
|
if(_surface->render())
|
||||||
{
|
_renderCallback();
|
||||||
mySurfaceStack.applyAll([](shared_ptr<FBSurface>& surface) {
|
|
||||||
surface->render();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// A dialog is still on top if a non-shading dialog (e.g. ContextMenu)
|
// A dialog is still on top if a non-shading dialog (e.g. ContextMenu)
|
||||||
// is opended above it.
|
// is opended above it.
|
||||||
|
@ -265,6 +256,20 @@ void Dialog::render()
|
||||||
|
|
||||||
if(!onTop)
|
if(!onTop)
|
||||||
{
|
{
|
||||||
|
if(_shadeSurface == nullptr)
|
||||||
|
{
|
||||||
|
// Create shading surface
|
||||||
|
uInt32 data = 0xff000000;
|
||||||
|
|
||||||
|
_shadeSurface = instance().frameBuffer().allocateSurface(
|
||||||
|
1, 1, ScalingInterpolation::sharp, &data);
|
||||||
|
|
||||||
|
FBSurface::Attributes& attr = _shadeSurface->attributes();
|
||||||
|
|
||||||
|
attr.blending = true;
|
||||||
|
attr.blendalpha = 25; // darken background dialogs by 25%
|
||||||
|
_shadeSurface->applyAttributes();
|
||||||
|
}
|
||||||
_shadeSurface->setDstRect(_surface->dstRect());
|
_shadeSurface->setDstRect(_surface->dstRect());
|
||||||
_shadeSurface->render();
|
_shadeSurface->render();
|
||||||
}
|
}
|
||||||
|
@ -418,9 +423,9 @@ void Dialog::buildCurrentFocusList(int tabID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Dialog::addSurface(const shared_ptr<FBSurface>& surface)
|
void Dialog::addRenderCallback(const std::function<void()>& callback)
|
||||||
{
|
{
|
||||||
mySurfaceStack.push(surface);
|
_renderCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -28,7 +28,6 @@ class TabWidget;
|
||||||
class CommandSender;
|
class CommandSender;
|
||||||
class ToolTip;
|
class ToolTip;
|
||||||
|
|
||||||
#include "Stack.hxx"
|
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
#include "GuiObject.hxx"
|
#include "GuiObject.hxx"
|
||||||
#include "StellaKeys.hxx"
|
#include "StellaKeys.hxx"
|
||||||
|
@ -45,6 +44,8 @@ class Dialog : public GuiObject
|
||||||
friend class DialogContainer;
|
friend class DialogContainer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using RenderCallback = std::function<void()>;
|
||||||
|
|
||||||
Dialog(OSystem& instance, DialogContainer& parent,
|
Dialog(OSystem& instance, DialogContainer& parent,
|
||||||
int x = 0, int y = 0, int w = 0, int h = 0);
|
int x = 0, int y = 0, int w = 0, int h = 0);
|
||||||
Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font,
|
Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font,
|
||||||
|
@ -62,6 +63,8 @@ class Dialog : public GuiObject
|
||||||
virtual void saveConfig() { }
|
virtual void saveConfig() { }
|
||||||
virtual void setDefaults() { }
|
virtual void setDefaults() { }
|
||||||
|
|
||||||
|
virtual void resetSurfaces();
|
||||||
|
|
||||||
void setDirty() override;
|
void setDirty() override;
|
||||||
void setDirtyChain() override;
|
void setDirtyChain() override;
|
||||||
void redraw(bool force = false);
|
void redraw(bool force = false);
|
||||||
|
@ -85,12 +88,11 @@ class Dialog : public GuiObject
|
||||||
FBSurface& surface() const { return *_surface; }
|
FBSurface& surface() const { return *_surface; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds a surface to this dialog, which is rendered on top of the
|
This method is called each time the main Dialog::render is called.
|
||||||
base surface whenever the base surface is re-rendered. Since
|
It is called *after* the dialog has been rendered, so it can be
|
||||||
the surface render() call will always occur in such a case, the
|
used to render another surface on top of it, among other things.
|
||||||
surface should call setVisible() to enable/disable its output.
|
|
||||||
*/
|
*/
|
||||||
void addSurface(const shared_ptr<FBSurface>& surface);
|
void addRenderCallback(const RenderCallback& callback);
|
||||||
|
|
||||||
void setTitle(const string& title);
|
void setTitle(const string& title);
|
||||||
bool hasTitle() { return !_title.empty(); }
|
bool hasTitle() { return !_title.empty(); }
|
||||||
|
@ -220,8 +222,6 @@ class Dialog : public GuiObject
|
||||||
int _layer{0};
|
int _layer{0};
|
||||||
unique_ptr<ToolTip> _toolTip;
|
unique_ptr<ToolTip> _toolTip;
|
||||||
|
|
||||||
Common::FixedStack<shared_ptr<FBSurface>> mySurfaceStack;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Focus {
|
struct Focus {
|
||||||
Widget* widget{nullptr};
|
Widget* widget{nullptr};
|
||||||
|
@ -248,13 +248,15 @@ class Dialog : public GuiObject
|
||||||
TabFocusList _myTabList; // focus for each tab (if any)
|
TabFocusList _myTabList; // focus for each tab (if any)
|
||||||
|
|
||||||
WidgetArray _buttonGroup;
|
WidgetArray _buttonGroup;
|
||||||
shared_ptr<FBSurface> _surface;
|
unique_ptr<FBSurface> _surface;
|
||||||
shared_ptr<FBSurface> _shadeSurface;
|
unique_ptr<FBSurface> _shadeSurface;
|
||||||
|
|
||||||
int _tabID{0};
|
int _tabID{0};
|
||||||
uInt32 _max_w{0}; // maximum wanted width
|
uInt32 _max_w{0}; // maximum wanted width
|
||||||
uInt32 _max_h{0}; // maximum wanted height
|
uInt32 _max_h{0}; // maximum wanted height
|
||||||
|
|
||||||
|
RenderCallback _renderCallback;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Dialog() = delete;
|
Dialog() = delete;
|
||||||
|
|
|
@ -199,6 +199,14 @@ void DialogContainer::reStack()
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DialogContainer::resetSurfaces()
|
||||||
|
{
|
||||||
|
myDialogStack.applyAll([&](Dialog*& d) {
|
||||||
|
d->resetSurfaces();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DialogContainer::handleTextEvent(char text)
|
void DialogContainer::handleTextEvent(char text)
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,6 +150,13 @@ class DialogContainer
|
||||||
*/
|
*/
|
||||||
void reStack();
|
void reStack();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Issue a 'reload' event to each dialog surface in the stack. This
|
||||||
|
is typically used when interpolation or attributes for a dialog
|
||||||
|
have changed.
|
||||||
|
*/
|
||||||
|
void resetSurfaces();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Inform the container that it should resize according to the current
|
Inform the container that it should resize according to the current
|
||||||
screen dimensions. We make this virtual, since the container may or
|
screen dimensions. We make this virtual, since the container may or
|
||||||
|
|
|
@ -40,9 +40,6 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
_bgcolorlo = kDlgColor;
|
_bgcolorlo = kDlgColor;
|
||||||
_textcolor = kTextColor;
|
_textcolor = kTextColor;
|
||||||
_textcolorhi = kTextColor;
|
_textcolorhi = kTextColor;
|
||||||
|
|
||||||
// add mouse context menu
|
|
||||||
myMouseMenu = make_unique<ContextMenu>(this, font, EmptyVarList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -143,7 +140,7 @@ int EditableWidget::toCaretPos(int x) const
|
||||||
void EditableWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
void EditableWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
||||||
{
|
{
|
||||||
// Grab right mouse button for context menu, send left to base class
|
// Grab right mouse button for context menu, send left to base class
|
||||||
if(b == MouseButton::RIGHT && isEnabled() && !myMouseMenu->isVisible())
|
if(b == MouseButton::RIGHT && isEnabled() && !mouseMenu().isVisible())
|
||||||
{
|
{
|
||||||
VariantList items;
|
VariantList items;
|
||||||
#ifndef BSPF_MACOS
|
#ifndef BSPF_MACOS
|
||||||
|
@ -159,10 +156,10 @@ void EditableWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount
|
||||||
if(isEditable())
|
if(isEditable())
|
||||||
VarList::push_back(items, " Paste Cmd+V ", "paste");
|
VarList::push_back(items, " Paste Cmd+V ", "paste");
|
||||||
#endif
|
#endif
|
||||||
myMouseMenu->addItems(items);
|
mouseMenu().addItems(items);
|
||||||
|
|
||||||
// Add menu at current x,y mouse location
|
// Add menu at current x,y mouse location
|
||||||
myMouseMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect());
|
mouseMenu().show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(b == MouseButton::LEFT && isEnabled())
|
else if(b == MouseButton::LEFT && isEnabled())
|
||||||
|
@ -179,6 +176,16 @@ void EditableWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount
|
||||||
Widget::handleMouseDown(x, y, b, clickCount);
|
Widget::handleMouseDown(x, y, b, clickCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
ContextMenu& EditableWidget::mouseMenu()
|
||||||
|
{
|
||||||
|
// add mouse context menu
|
||||||
|
if(myMouseMenu == nullptr)
|
||||||
|
myMouseMenu = make_unique<ContextMenu>(this, _font, EmptyVarList);
|
||||||
|
|
||||||
|
return *myMouseMenu;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void EditableWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
|
void EditableWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +212,7 @@ void EditableWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
||||||
{
|
{
|
||||||
if(cmd == ContextMenu::kItemSelectedCmd)
|
if(cmd == ContextMenu::kItemSelectedCmd)
|
||||||
{
|
{
|
||||||
const string& rmb = myMouseMenu->getSelectedTag().toString();
|
const string& rmb = mouseMenu().getSelectedTag().toString();
|
||||||
|
|
||||||
if(rmb == "cut")
|
if(rmb == "cut")
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,6 +117,8 @@ class EditableWidget : public Widget, public CommandSender
|
||||||
// internal buffer
|
// internal buffer
|
||||||
bool tryInsertChar(char c, int pos);
|
bool tryInsertChar(char c, int pos);
|
||||||
|
|
||||||
|
ContextMenu& mouseMenu();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unique_ptr<ContextMenu> myMouseMenu;
|
unique_ptr<ContextMenu> myMouseMenu;
|
||||||
bool _isDragging{false};
|
bool _isDragging{false};
|
||||||
|
|
|
@ -128,7 +128,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
addFocusWidget(myComboButton);
|
addFocusWidget(myComboButton);
|
||||||
|
|
||||||
VariantList combolist = instance().eventHandler().getComboList(mode);
|
VariantList combolist = instance().eventHandler().getComboList(mode);
|
||||||
myComboDialog = new ComboDialog(boss, font, combolist);
|
myComboDialog = make_unique<ComboDialog>(boss, font, combolist);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show message for currently selected event
|
// Show message for currently selected event
|
||||||
|
|
|
@ -90,7 +90,7 @@ class EventMappingWidget : public Widget, public CommandSender
|
||||||
StringListWidget* myActionsList{nullptr};
|
StringListWidget* myActionsList{nullptr};
|
||||||
EditTextWidget* myKeyMapping{nullptr};
|
EditTextWidget* myKeyMapping{nullptr};
|
||||||
|
|
||||||
ComboDialog* myComboDialog{nullptr};
|
unique_ptr<ComboDialog> myComboDialog;
|
||||||
|
|
||||||
// Since this widget can be used for different collections of events,
|
// Since this widget can be used for different collections of events,
|
||||||
// we need to specify exactly which group of events we are remapping
|
// we need to specify exactly which group of events we are remapping
|
||||||
|
|
|
@ -295,9 +295,6 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
|
|
||||||
addToFocusList(wid);
|
addToFocusList(wid);
|
||||||
|
|
||||||
// Create (empty) context menu for ROM list options
|
|
||||||
myMenu = make_unique<ContextMenu>(this, _font, EmptyVarList);
|
|
||||||
|
|
||||||
// since we cannot know how many files there are, use are really high value here
|
// since we cannot know how many files there are, use are really high value here
|
||||||
myList->progress().setRange(0, 50000, 5);
|
myList->progress().setRange(0, 50000, 5);
|
||||||
myList->progress().setMessage(" Filtering files" + ELLIPSIS + " ");
|
myList->progress().setMessage(" Filtering files" + ELLIPSIS + " ");
|
||||||
|
@ -353,6 +350,15 @@ void LauncherDialog::reload()
|
||||||
myPendingReload = false;
|
myPendingReload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void LauncherDialog::resetSurfaces()
|
||||||
|
{
|
||||||
|
if(myRomInfoWidget)
|
||||||
|
myRomInfoWidget->resetSurfaces();
|
||||||
|
|
||||||
|
Dialog::resetSurfaces();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::tick()
|
void LauncherDialog::tick()
|
||||||
{
|
{
|
||||||
|
@ -608,7 +614,7 @@ void LauncherDialog::loadRomInfo()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::handleContextMenu()
|
void LauncherDialog::handleContextMenu()
|
||||||
{
|
{
|
||||||
const string& cmd = myMenu->getSelectedTag().toString();
|
const string& cmd = menu().getSelectedTag().toString();
|
||||||
|
|
||||||
if(cmd == "override")
|
if(cmd == "override")
|
||||||
openGlobalProps();
|
openGlobalProps();
|
||||||
|
@ -618,6 +624,17 @@ void LauncherDialog::handleContextMenu()
|
||||||
openHighScores();
|
openHighScores();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
ContextMenu& LauncherDialog::menu()
|
||||||
|
{
|
||||||
|
if(myMenu == nullptr)
|
||||||
|
// Create (empty) context menu for ROM list options
|
||||||
|
myMenu = make_unique<ContextMenu>(this, _font, EmptyVarList);
|
||||||
|
|
||||||
|
|
||||||
|
return *myMenu;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::showOnlyROMs(bool state)
|
void LauncherDialog::showOnlyROMs(bool state)
|
||||||
{
|
{
|
||||||
|
@ -752,10 +769,10 @@ void LauncherDialog::handleMouseDown(int x, int y, MouseButton b, int clickCount
|
||||||
if(instance().highScores().enabled())
|
if(instance().highScores().enabled())
|
||||||
VarList::push_back(items, " High scores" + ELLIPSIS + " Ctrl+H", "highscores");
|
VarList::push_back(items, " High scores" + ELLIPSIS + " Ctrl+H", "highscores");
|
||||||
VarList::push_back(items, " Reload listing Ctrl+R ", "reload");
|
VarList::push_back(items, " Reload listing Ctrl+R ", "reload");
|
||||||
myMenu->addItems(items);
|
menu().addItems(items);
|
||||||
|
|
||||||
// Add menu at current x,y mouse location
|
// Add menu at current x,y mouse location
|
||||||
myMenu->show(x + getAbsX(), y + getAbsY(), surface().dstRect());
|
menu().show(x + getAbsX(), y + getAbsY(), surface().dstRect());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Dialog::handleMouseDown(x, y, b, clickCount);
|
Dialog::handleMouseDown(x, y, b, clickCount);
|
||||||
|
|
|
@ -108,6 +108,7 @@ class LauncherDialog : public Dialog
|
||||||
|
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
void saveConfig() override;
|
void saveConfig() override;
|
||||||
|
void resetSurfaces() override;
|
||||||
void updateUI();
|
void updateUI();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,6 +158,8 @@ class LauncherDialog : public Dialog
|
||||||
void openHighScores();
|
void openHighScores();
|
||||||
void openWhatsNew();
|
void openWhatsNew();
|
||||||
|
|
||||||
|
ContextMenu& menu();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unique_ptr<Dialog> myDialog;
|
unique_ptr<Dialog> myDialog;
|
||||||
unique_ptr<ContextMenu> myMenu;
|
unique_ptr<ContextMenu> myMenu;
|
||||||
|
|
|
@ -94,7 +94,11 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
|
||||||
myAvail.w, myAvail.h, ScalingInterpolation::blur);
|
myAvail.w, myAvail.h, ScalingInterpolation::blur);
|
||||||
mySurface->applyAttributes();
|
mySurface->applyAttributes();
|
||||||
|
|
||||||
dialog().addSurface(mySurface);
|
dialog().addRenderCallback([this]() {
|
||||||
|
if(mySurfaceIsValid)
|
||||||
|
mySurface->render();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize to empty properties entry
|
// Initialize to empty properties entry
|
||||||
|
@ -169,6 +173,13 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void RomInfoWidget::resetSurfaces()
|
||||||
|
{
|
||||||
|
if(mySurface)
|
||||||
|
mySurface->reload();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PNG_SUPPORT
|
#ifdef PNG_SUPPORT
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool RomInfoWidget::loadPng(const string& filename)
|
bool RomInfoWidget::loadPng(const string& filename)
|
||||||
|
|
|
@ -39,6 +39,8 @@ class RomInfoWidget : public Widget
|
||||||
void clearProperties();
|
void clearProperties();
|
||||||
void reloadProperties(const FilesystemNode& node);
|
void reloadProperties(const FilesystemNode& node);
|
||||||
|
|
||||||
|
void resetSurfaces();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void drawWidget(bool hilite) override;
|
void drawWidget(bool hilite) override;
|
||||||
|
|
||||||
|
@ -50,7 +52,7 @@ class RomInfoWidget : public Widget
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Surface pointer holding the PNG image
|
// Surface pointer holding the PNG image
|
||||||
shared_ptr<FBSurface> mySurface;
|
unique_ptr<FBSurface> mySurface;
|
||||||
|
|
||||||
// Whether the surface should be redrawn by drawWidget()
|
// Whether the surface should be redrawn by drawWidget()
|
||||||
bool mySurfaceIsValid{false};
|
bool mySurfaceIsValid{false};
|
||||||
|
|
|
@ -47,15 +47,13 @@ void ToolTip::setFont(const GUI::Font& font)
|
||||||
myWidth = fontWidth * MAX_COLUMNS + myTextXOfs * 2;
|
myWidth = fontWidth * MAX_COLUMNS + myTextXOfs * 2;
|
||||||
myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2;
|
myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2;
|
||||||
|
|
||||||
|
// unallocate
|
||||||
if(mySurface != nullptr)
|
if(mySurface != nullptr)
|
||||||
{
|
mySurface.reset();
|
||||||
// TODO: unallocate
|
|
||||||
mySurface = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
shared_ptr<FBSurface> ToolTip::surface()
|
const unique_ptr<FBSurface>& ToolTip::surface()
|
||||||
{
|
{
|
||||||
if(mySurface == nullptr)
|
if(mySurface == nullptr)
|
||||||
mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight);
|
mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight);
|
||||||
|
|
|
@ -76,7 +76,7 @@ class ToolTip
|
||||||
/**
|
/**
|
||||||
Allocate surface if required and return it
|
Allocate surface if required and return it
|
||||||
*/
|
*/
|
||||||
shared_ptr<FBSurface> surface();
|
const unique_ptr<FBSurface>& surface();
|
||||||
|
|
||||||
void show(const string& tip);
|
void show(const string& tip);
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ class ToolTip
|
||||||
uInt32 myTextYOfs{0};
|
uInt32 myTextYOfs{0};
|
||||||
bool myTipShown{false};
|
bool myTipShown{false};
|
||||||
uInt32 myScale{1};
|
uInt32 myScale{1};
|
||||||
shared_ptr<FBSurface> mySurface;
|
unique_ptr<FBSurface> mySurface;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,7 +55,6 @@ class FBSurfaceLIBRETRO : public FBSurface
|
||||||
bool render() override { return true; }
|
bool render() override { return true; }
|
||||||
void invalidate() override { }
|
void invalidate() override { }
|
||||||
void invalidateRect(uInt32, uInt32, uInt32, uInt32) override { }
|
void invalidateRect(uInt32, uInt32, uInt32, uInt32) override { }
|
||||||
void free() override { }
|
|
||||||
void reload() override { }
|
void reload() override { }
|
||||||
void resize(uInt32 width, uInt32 height) override { }
|
void resize(uInt32 width, uInt32 height) override { }
|
||||||
void setScalingInterpolation(ScalingInterpolation) override { }
|
void setScalingInterpolation(ScalingInterpolation) override { }
|
||||||
|
|
Loading…
Reference in New Issue