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 std::string videoSource = (vdp.getName() == "VDP")
59 ? "MSX" // for backwards compatibility
60 : vdp.getName();
61 auto& motherBoard = vdp.getMotherBoard();
62 switch (renderSettings.getRenderer()) {
64 return std::make_unique<SDLRasterizer>(
65 vdp, display, *screen,
66 std::make_unique<PostProcessor>(
67 motherBoard, display, *screen,
68 videoSource, 640, 240, true));
69 default:
70 UNREACHABLE; return nullptr;
71 }
72}
73
74std::unique_ptr<V9990Rasterizer> SDLVideoSystem::createV9990Rasterizer(
75 V9990& vdp)
76{
77 std::string videoSource = (vdp.getName() == "Sunrise GFX9000")
78 ? "GFX9000" // for backwards compatibility
79 : vdp.getName();
80 MSXMotherBoard& motherBoard = vdp.getMotherBoard();
81 switch (renderSettings.getRenderer()) {
83 return std::make_unique<V9990SDLRasterizer>(
84 vdp, display, *screen,
85 std::make_unique<PostProcessor>(
86 motherBoard, display, *screen,
87 videoSource, 1280, 240, true));
88 default:
89 UNREACHABLE; return nullptr;
90 }
91}
92
93#if COMPONENT_LASERDISC
94std::unique_ptr<LDRasterizer> SDLVideoSystem::createLDRasterizer(
96{
97 std::string videoSource = "Laserdisc"; // TODO handle multiple???
98 MSXMotherBoard& motherBoard = ld.getMotherBoard();
99 switch (renderSettings.getRenderer()) {
101 return std::make_unique<LDSDLRasterizer>(
102 std::make_unique<PostProcessor>(
103 motherBoard, display, *screen,
104 videoSource, 640, 480, false));
105 default:
106 UNREACHABLE; return nullptr;
107 }
108}
109#endif
110
112{
113 screen->finish();
114}
115
116void SDLVideoSystem::takeScreenShot(const std::string& filename, bool withOsd)
117{
118 if (withOsd) {
119 // we can directly save current content as screenshot
120 screen->saveScreenshot(filename);
121 } else {
122 // we first need to re-render to an off-screen surface
123 // with OSD layers disabled
124 ScopedLayerHider hideOsd(*osdGuiLayer);
125 ScopedLayerHider hideImgui(*imGuiLayer);
126 std::unique_ptr<OutputSurface> surf = screen->createOffScreenSurface();
127 display.repaintImpl(*surf);
128 surf->saveScreenshot(filename);
129 }
130}
131
133{
134 screen->updateWindowTitle();
135}
136
138{
139 int mouseX, mouseY;
140 SDL_GetMouseState(&mouseX, &mouseY);
141 return {mouseX, mouseY};
142}
143
145{
146 return screen.get();
147}
148
150{
151 SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
152}
153
155{
156 return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
157}
158
160{
161 std::string result;
162 if (char* text = SDL_GetClipboardText()) {
163 result = text;
164 SDL_free(text);
165 }
166 return result;
167}
168
170{
171 if (SDL_SetClipboardText(text.c_str()) != 0) {
172 const char* err = SDL_GetError();
173 SDL_ClearError();
174 throw CommandException(err);
175 }
176}
177
178std::optional<gl::ivec2> SDLVideoSystem::getWindowPosition()
179{
180 return screen->getWindowPosition();
181}
182
184{
185 screen->setWindowPosition(pos);
186}
187
189{
190 // With SDL we can simply repaint the display directly.
191 display.repaintImpl();
192}
193
194void SDLVideoSystem::update(const Setting& subject) noexcept
195{
196 if (&subject == &renderSettings.getFullScreenSetting()) {
197 screen->setFullScreen(renderSettings.getFullScreen());
198 } else if (&subject == &renderSettings.getScaleFactorSetting()) {
199 screen->resize();
200 } else {
202 }
203}
204
205int SDLVideoSystem::signalEvent(const Event& /*event*/)
206{
207 // TODO: Currently window size depends only on scale factor.
208 // Maybe in the future it will be handled differently.
209 //const auto& resizeEvent = get_event<ResizeEvent>(event);
210 //resize(resizeEvent.getX(), resizeEvent.getY());
211 //resize();
212 return 0;
213}
214
215} // namespace openmsx
void repaintImpl()
Definition Display.cc:328
OSDGUI & getOSDGUI()
Definition Display.hh:44
void removeLayer(Layer &layer)
Definition Display.cc:396
void addLayer(Layer &layer)
Definition Display.cc:388
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:72
ImGuiManager & getImGuiManager()
Definition Reactor.hh:96
CliComm & getCliComm()
Definition Reactor.cc:324
RTScheduler & getRTScheduler()
Definition Reactor.hh:85
EventDistributor & getEventDistributor()
Definition Reactor.hh:86
InputEventGenerator & getInputEventGenerator()
Definition Reactor.hh:89
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:56
void attach(Observer< T > &observer)
Definition Subject.hh:50
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:64
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:9
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:454
#define UNREACHABLE