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 "imgui.h"
14#include "unreachable.hh"
15#include <memory>
16
17#include "components.hh"
18#if COMPONENT_LASERDISC
19#include "LaserdiscPlayer.hh"
20#include "LDSDLRasterizer.hh"
21#endif
22
23namespace openmsx {
24
26 : reactor(reactor_)
27 , display(reactor.getDisplay())
28 , renderSettings(reactor.getDisplay().getRenderSettings())
29{
30 screen = std::make_unique<VisibleSurface>(
31 display,
32 reactor.getRTScheduler(), reactor.getEventDistributor(),
33 reactor.getInputEventGenerator(), reactor.getCliComm(),
34 *this);
35
36 snowLayer = screen->createSnowLayer();
37 osdGuiLayer = screen->createOSDGUILayer(display.getOSDGUI());
38 imGuiLayer = screen->createImGUILayer(reactor.getImGuiManager());
39 display.addLayer(*snowLayer);
40 display.addLayer(*osdGuiLayer);
41 display.addLayer(*imGuiLayer);
42
43 renderSettings.getFullScreenSetting().attach(*this);
44 renderSettings.getScaleFactorSetting().attach(*this);
45}
46
48{
49 renderSettings.getScaleFactorSetting().detach(*this);
50 renderSettings.getFullScreenSetting().detach(*this);
51
52 display.removeLayer(*imGuiLayer);
53 display.removeLayer(*osdGuiLayer);
54 display.removeLayer(*snowLayer);
55}
56
57std::unique_ptr<Rasterizer> SDLVideoSystem::createRasterizer(VDP& vdp)
58{
59 assert(renderSettings.getRenderer() == RenderSettings::RendererID::SDLGL_PP);
60 std::string videoSource = (vdp.getName() == "VDP")
61 ? "MSX" // for backwards compatibility
62 : vdp.getName();
63 auto& motherBoard = vdp.getMotherBoard();
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}
70
71std::unique_ptr<V9990Rasterizer> SDLVideoSystem::createV9990Rasterizer(
72 V9990& vdp)
73{
74 assert(renderSettings.getRenderer() == RenderSettings::RendererID::SDLGL_PP);
75 std::string videoSource = (vdp.getName() == "Sunrise GFX9000")
76 ? "GFX9000" // for backwards compatibility
77 : vdp.getName();
78 MSXMotherBoard& motherBoard = vdp.getMotherBoard();
79 return std::make_unique<V9990SDLRasterizer>(
80 vdp, display, *screen,
81 std::make_unique<PostProcessor>(
82 motherBoard, display, *screen,
83 videoSource, 1280, 240, true));
84}
85
86#if COMPONENT_LASERDISC
87std::unique_ptr<LDRasterizer> SDLVideoSystem::createLDRasterizer(
89{
90 assert(renderSettings.getRenderer() == RenderSettings::RendererID::SDLGL_PP);
91 std::string videoSource = "Laserdisc"; // TODO handle multiple???
92 MSXMotherBoard& motherBoard = ld.getMotherBoard();
93 return std::make_unique<LDSDLRasterizer>(
94 std::make_unique<PostProcessor>(
95 motherBoard, display, *screen,
96 videoSource, 640, 480, false));
97}
98#endif
99
101{
102 screen->finish();
103}
104
105void SDLVideoSystem::takeScreenShot(const std::string& filename, bool withOsd)
106{
107 if (withOsd) {
108 // we can directly save current content as screenshot
109 screen->saveScreenshot(filename);
110 } else {
111 // we first need to re-render to an off-screen surface
112 // with OSD layers disabled
113 ScopedLayerHider hideOsd(*osdGuiLayer);
114 ScopedLayerHider hideImgui(*imGuiLayer);
115 std::unique_ptr<OutputSurface> surf = screen->createOffScreenSurface();
116 display.repaintImpl(*surf);
117 surf->saveScreenshot(filename);
118 }
119}
120
122{
123 screen->updateWindowTitle();
124}
125
127{
128 int mouseX, mouseY;
129 SDL_GetMouseState(&mouseX, &mouseY);
130 return {mouseX, mouseY};
131}
132
134{
135 return screen.get();
136}
137
139{
140 SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
141 if (show) {
142 ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
143 } else {
144 ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
145 }
146}
147
149{
150 return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
151}
152
154{
155 std::string result;
156 if (char* text = SDL_GetClipboardText()) {
157 result = text;
158 SDL_free(text);
159 }
160 return result;
161}
162
164{
165 if (SDL_SetClipboardText(text.c_str()) != 0) {
166 const char* err = SDL_GetError();
167 SDL_ClearError();
168 throw CommandException(err);
169 }
170}
171
172std::optional<gl::ivec2> SDLVideoSystem::getWindowPosition()
173{
174 return screen->getWindowPosition();
175}
176
178{
179 screen->setWindowPosition(pos);
180}
181
183{
184 // With SDL we can simply repaint the display directly.
185 display.repaintImpl();
186}
187
188void SDLVideoSystem::update(const Setting& subject) noexcept
189{
190 if (&subject == &renderSettings.getFullScreenSetting()) {
191 screen->setFullScreen(renderSettings.getFullScreen());
192 } else if (&subject == &renderSettings.getScaleFactorSetting()) {
193 screen->resize();
194 } else {
196 }
197}
198
199bool SDLVideoSystem::signalEvent(const Event& /*event*/)
200{
201 // TODO: Currently window size depends only on scale factor.
202 // Maybe in the future it will be handled differently.
203 //const auto& resizeEvent = get_event<ResizeEvent>(event);
204 //resize(resizeEvent.getX(), resizeEvent.getY());
205 //resize();
206 return false;
207}
208
209} // namespace openmsx
void repaintImpl()
Definition Display.cc:329
OSDGUI & getOSDGUI()
Definition Display.hh:47
void removeLayer(Layer &layer)
Definition Display.cc:397
void addLayer(Layer &layer)
Definition Display.cc:389
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:99
CliComm & getCliComm()
Definition Reactor.cc:323
RTScheduler & getRTScheduler()
Definition Reactor.hh:88
EventDistributor & getEventDistributor()
Definition Reactor.hh:89
InputEventGenerator & getInputEventGenerator()
Definition Reactor.hh:92
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:67
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