openMSX
SDLVideoSystem.cc
Go to the documentation of this file.
1#include "SDLVideoSystem.hh"
2#include "SDLRasterizer.hh"
3#include "VisibleSurface.hh"
4#include "PostProcessor.hh"
6#include "Reactor.hh"
7#include "Display.hh"
8#include "RenderSettings.hh"
9#include "IntegerSetting.hh"
10#include "EventDistributor.hh"
11#include "VDP.hh"
12#include "V9990.hh"
13#include "unreachable.hh"
14#include <memory>
15
16#include "components.hh"
17#if COMPONENT_LASERDISC
18#include "LaserdiscPlayer.hh"
19#include "LDSDLRasterizer.hh"
20#endif
21
22namespace openmsx {
23
25 : reactor(reactor_)
26 , display(reactor.getDisplay())
27 , renderSettings(reactor.getDisplay().getRenderSettings())
28{
29 screen = std::make_unique<VisibleSurface>(
30 display,
31 reactor.getRTScheduler(), reactor.getEventDistributor(),
32 reactor.getInputEventGenerator(), reactor.getCliComm(),
33 *this);
34
35 snowLayer = screen->createSnowLayer();
36 osdGuiLayer = screen->createOSDGUILayer(display.getOSDGUI());
37 imGuiLayer = screen->createImGUILayer(reactor.getImGuiManager());
38 display.addLayer(*snowLayer);
39 display.addLayer(*osdGuiLayer);
40 display.addLayer(*imGuiLayer);
41
42 renderSettings.getFullScreenSetting().attach(*this);
43 renderSettings.getScaleFactorSetting().attach(*this);
44}
45
47{
48 renderSettings.getScaleFactorSetting().detach(*this);
49 renderSettings.getFullScreenSetting().detach(*this);
50
51 display.removeLayer(*imGuiLayer);
52 display.removeLayer(*osdGuiLayer);
53 display.removeLayer(*snowLayer);
54}
55
56std::unique_ptr<Rasterizer> SDLVideoSystem::createRasterizer(VDP& vdp)
57{
58 assert(renderSettings.getRenderer() == RenderSettings::RendererID::SDLGL_PP);
59 std::string videoSource = (vdp.getName() == "VDP")
60 ? "MSX" // for backwards compatibility
61 : vdp.getName();
62 auto& motherBoard = vdp.getMotherBoard();
63 return std::make_unique<SDLRasterizer>(
64 vdp, display, *screen,
65 std::make_unique<PostProcessor>(
66 motherBoard, display, *screen,
67 videoSource, 640, 240, true));
68}
69
70std::unique_ptr<V9990Rasterizer> SDLVideoSystem::createV9990Rasterizer(
71 V9990& vdp)
72{
73 assert(renderSettings.getRenderer() == RenderSettings::RendererID::SDLGL_PP);
74 std::string videoSource = (vdp.getName() == "Sunrise GFX9000")
75 ? "GFX9000" // for backwards compatibility
76 : vdp.getName();
77 MSXMotherBoard& motherBoard = vdp.getMotherBoard();
78 return std::make_unique<V9990SDLRasterizer>(
79 vdp, display, *screen,
80 std::make_unique<PostProcessor>(
81 motherBoard, display, *screen,
82 videoSource, 1280, 240, true));
83}
84
85#if COMPONENT_LASERDISC
86std::unique_ptr<LDRasterizer> SDLVideoSystem::createLDRasterizer(
88{
89 assert(renderSettings.getRenderer() == RenderSettings::RendererID::SDLGL_PP);
90 std::string videoSource = "Laserdisc"; // TODO handle multiple???
91 MSXMotherBoard& motherBoard = ld.getMotherBoard();
92 return std::make_unique<LDSDLRasterizer>(
93 std::make_unique<PostProcessor>(
94 motherBoard, display, *screen,
95 videoSource, 640, 480, false));
96}
97#endif
98
100{
101 screen->finish();
102}
103
104void SDLVideoSystem::takeScreenShot(const std::string& filename, bool withOsd)
105{
106 if (withOsd) {
107 // we can directly save current content as screenshot
108 screen->saveScreenshot(filename);
109 } else {
110 // we first need to re-render to an off-screen surface
111 // with OSD layers disabled
112 ScopedLayerHider hideOsd(*osdGuiLayer);
113 ScopedLayerHider hideImgui(*imGuiLayer);
114 std::unique_ptr<OutputSurface> surf = screen->createOffScreenSurface();
115 display.repaintImpl(*surf);
116 surf->saveScreenshot(filename);
117 }
118}
119
121{
122 screen->updateWindowTitle();
123}
124
126{
127 int mouseX, mouseY;
128 SDL_GetMouseState(&mouseX, &mouseY);
129 return {mouseX, mouseY};
130}
131
133{
134 return screen.get();
135}
136
138{
139 SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
140}
141
143{
144 return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
145}
146
148{
149 std::string result;
150 if (char* text = SDL_GetClipboardText()) {
151 result = text;
152 SDL_free(text);
153 }
154 return result;
155}
156
158{
159 if (SDL_SetClipboardText(text.c_str()) != 0) {
160 const char* err = SDL_GetError();
161 SDL_ClearError();
162 throw CommandException(err);
163 }
164}
165
166std::optional<gl::ivec2> SDLVideoSystem::getWindowPosition()
167{
168 return screen->getWindowPosition();
169}
170
172{
173 screen->setWindowPosition(pos);
174}
175
177{
178 // With SDL we can simply repaint the display directly.
179 display.repaintImpl();
180}
181
182void SDLVideoSystem::update(const Setting& subject) noexcept
183{
184 if (&subject == &renderSettings.getFullScreenSetting()) {
185 screen->setFullScreen(renderSettings.getFullScreen());
186 } else if (&subject == &renderSettings.getScaleFactorSetting()) {
187 screen->resize();
188 } else {
190 }
191}
192
193bool SDLVideoSystem::signalEvent(const Event& /*event*/)
194{
195 // TODO: Currently window size depends only on scale factor.
196 // Maybe in the future it will be handled differently.
197 //const auto& resizeEvent = get_event<ResizeEvent>(event);
198 //resize(resizeEvent.getX(), resizeEvent.getY());
199 //resize();
200 return false;
201}
202
203} // namespace openmsx
void repaintImpl()
Definition Display.cc:321
OSDGUI & getOSDGUI()
Definition Display.hh:48
void removeLayer(Layer &layer)
Definition Display.cc:389
void addLayer(Layer &layer)
Definition Display.cc:381
MSXMotherBoard & getMotherBoard()
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition MSXDevice.cc:70
virtual const std::string & getName() const
Returns a human-readable name for this device.
Definition MSXDevice.cc:375
A frame buffer where pixels can be written to.
Contains the main loop of openMSX.
Definition Reactor.hh:75
ImGuiManager & getImGuiManager()
Definition Reactor.hh:100
CliComm & getCliComm()
Definition Reactor.cc:323
RTScheduler & getRTScheduler()
Definition Reactor.hh:89
EventDistributor & getEventDistributor()
Definition Reactor.hh:90
InputEventGenerator & getInputEventGenerator()
Definition Reactor.hh:93
BooleanSetting & getFullScreenSetting()
Full screen [on, off].
IntegerSetting & getScaleFactorSetting()
The current scaling factor.
RendererID getRenderer() const
bool getCursorEnabled() override
void setWindowPosition(gl::ivec2 pos) override
void repaint() override
Requests a repaint of the output surface.
void setClipboardText(zstring_view text) override
void showCursor(bool show) override
gl::ivec2 getMouseCoord() override
Returns the current mouse pointer coordinates.
std::unique_ptr< V9990Rasterizer > createV9990Rasterizer(V9990 &vdp) override
Create the V9990 rasterizer selected by the current renderer setting.
~SDLVideoSystem() override
Deactivates this video system.
OutputSurface * getOutputSurface() override
TODO.
std::optional< gl::ivec2 > getWindowPosition() override
SDLVideoSystem(Reactor &reactor)
Activates this video system.
void takeScreenShot(const std::string &filename, bool withOsd) override
Take a screenshot.
void updateWindowTitle() override
Called when the window title string has changed.
std::string getClipboardText() override
void flush() override
Finish pending drawing operations and make them visible to the user.
std::unique_ptr< Rasterizer > createRasterizer(VDP &vdp) override
Create the rasterizer selected by the current renderer setting.
void detach(Observer< T > &observer)
Definition Subject.hh:60
void attach(Observer< T > &observer)
Definition Subject.hh:54
Implementation of the Yamaha V9990 VDP as used in the GFX9000 cartridge by Sunrise.
Definition V9990.hh:35
Unified implementation of MSX Video Display Processors (VDPs).
Definition VDP.hh:66
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr const char * c_str() const
This file implemented 3 utility functions:
Definition Autofire.cc:11
std::variant< KeyUpEvent, KeyDownEvent, MouseMotionEvent, MouseButtonUpEvent, MouseButtonDownEvent, MouseWheelEvent, JoystickAxisMotionEvent, JoystickHatEvent, JoystickButtonUpEvent, JoystickButtonDownEvent, OsdControlReleaseEvent, OsdControlPressEvent, WindowEvent, TextEvent, FileDropEvent, QuitEvent, FinishFrameEvent, CliCommandEvent, GroupEvent, BootEvent, FrameDrawnEvent, BreakEvent, SwitchRendererEvent, TakeReverseSnapshotEvent, AfterTimedEvent, MachineLoadedEvent, MachineActivatedEvent, MachineDeactivatedEvent, MidiInReaderEvent, MidiInWindowsEvent, MidiInCoreMidiEvent, MidiInCoreMidiVirtualEvent, MidiInALSAEvent, Rs232TesterEvent, Rs232NetEvent, ImGuiDelayedActionEvent, ImGuiActiveEvent > Event
Definition Event.hh:445
#define UNREACHABLE