46 virtual string execute(
const vector<string>& tokens);
47 virtual string help(
const vector<string>& tokens)
const;
57 virtual void execute(
const vector<TclObject>& tokens,
59 virtual string help(
const vector<string>& tokens)
const;
67 reactor_.getEventDistributor(), *this,
70 reactor_.getCommandController(), *this))
72 reactor_.getOpenMSXInfoCommand(), *this))
74 reactor_.getCommandController(), *this))
77 reactor.getCommandController()))
79 reactor.getGlobalCommandController(),
80 reactor.getEventDistributor(), *this))
82 , switchInProgress(false)
85 for (
unsigned i = 0; i < NUM_FRAME_DURATIONS; ++i) {
87 frameDurationSum += 20;
104 renderSettings->getRenderer().attach(*
this);
105 renderSettings->getFullScreen().attach(*
this);
106 renderSettings->getScaleFactor().attach(*
this);
107 renderFrozen =
false;
112 renderSettings->getRenderer().detach(*
this);
113 renderSettings->getFullScreen().detach(*
this);
114 renderSettings->getScaleFactor().detach(*
this);
132 PRT_DEBUG(
"Reset video system... DONE!");
134 assert(listeners.empty());
139 assert(!videoSystem.get());
141 assert(!switchInProgress);
142 currentRenderer = renderSettings->getRenderer().getValue();
143 switchInProgress =
true;
149 assert(videoSystem.get());
153 void Display::resetVideoSystem()
168 return *renderSettings;
178 return *commandConsole;
183 assert(count(listeners.begin(), listeners.end(), &listener) == 0);
184 listeners.push_back(&listener);
189 auto it = find(listeners.begin(), listeners.end(), &listener);
190 assert(it != listeners.end());
196 for (
auto& l : layers) {
204 Display::Layers::iterator Display::baseLayer()
208 auto it = layers.end();
210 if (it == layers.begin()) {
223 int Display::signalEvent(
const std::shared_ptr<const Event>& event)
226 auto& ffe = checked_cast<
const FinishFrameEvent&>(*event);
227 if (ffe.needRender()) {
230 std::make_shared<SimpleEvent>(
259 auto& focusEvent = checked_cast<
const FocusEvent&>(*event);
260 ad_printf(
"Setting renderFrozen to %d", !focusEvent.getGain());
261 renderFrozen = !focusEvent.getGain();
266 void Display::setWindowTitle()
271 title += BUILD_FLAVOUR;
275 if (
const HardwareConfig* machine = motherboard->getMachineConfig()) {
276 const XMLElement& config = machine->getConfig();
278 config.getChild(
"info").getChildData(
"manufacturer") +
' ' +
279 config.getChild(
"info").getChildData(
"code");
282 videoSystem->setWindowTitle(title);
285 void Display::update(
const Setting& setting)
287 if (&setting == &renderSettings->getRenderer()) {
288 checkRendererSwitch();
289 }
else if (&setting == &renderSettings->getFullScreen()) {
290 checkRendererSwitch();
291 }
else if (&setting == &renderSettings->getScaleFactor()) {
292 checkRendererSwitch();
298 void Display::checkRendererSwitch()
300 if (switchInProgress) {
307 renderSettings->getRenderer().getValue();
308 if ((newRenderer != currentRenderer) ||
310 currentRenderer = newRenderer;
314 switchInProgress =
true;
316 std::make_shared<SimpleEvent>(
321 void Display::doRendererSwitch()
323 assert(switchInProgress);
325 bool success =
false;
330 }
catch (MSXException& e) {
331 string errorMsg =
"Couldn't activate renderer " +
332 renderSettings->getRenderer().getValueString() +
333 ": " + e.getMessage();
336 errorMsg +=
"\nTrying to switch to SDL renderer instead...";
340 unsigned curval = renderSettings->getScaleFactor().getValue();
341 if (curval == 1)
throw MSXException(e.getMessage() +
" (and I have no other ideas to try...)");
343 renderSettings->getScaleFactor().changeValue(curval - 1);
349 switchInProgress =
false;
352 void Display::doRendererSwitch2()
354 for (
auto& l : listeners) {
355 l->preVideoSystemChange();
362 for (
auto& l : listeners) {
363 l->postVideoSystemChange();
369 if (switchInProgress) {
383 assert(videoSystem.get());
384 if (
OutputSurface* surface = videoSystem->getOutputSurface()) {
386 videoSystem->flush();
392 auto duration = now - prevTimeStamp;
394 frameDurationSum += duration - frameDurations.
removeBack();
400 for (
auto it = baseLayer(); it != layers.end(); ++it) {
402 (*it)->paint(surface);
409 if (alarm->pending()) {
413 alarm->schedule(
unsigned(delta));
418 int z = layer.
getZ();
419 auto it = layers.begin();
420 while (it != layers.end() && (*it)->getZ() < z) {
424 layers.insert(it, &layer);
430 auto it = std::find(layers.begin(), layers.end(), &layer);
431 assert(it != layers.end());
435 void Display::updateZ(
Layer& layer)
448 :
Command(commandController,
"screenshot")
455 bool rawShot =
false;
456 bool withOsd =
false;
457 bool doubleSize =
false;
458 string prefix =
"openmsx";
459 vector<string> arguments;
460 for (
unsigned i = 1; i < tokens.size(); ++i) {
462 if (tokens[i] ==
"--") {
463 arguments.insert(arguments.end(),
464 tokens.begin() + i + 1, tokens.end());
467 if (tokens[i] ==
"-prefix") {
468 if (++i == tokens.size()) {
472 }
else if (tokens[i] ==
"-raw") {
474 }
else if (tokens[i] ==
"-msxonly") {
476 "The -msxonly option has been deprecated and will "
477 "be removed in a future release. Instead, use the "
478 "-raw option for the same effect.");
480 }
else if (tokens[i] ==
"-doublesize") {
482 }
else if (tokens[i] ==
"-with-osd") {
488 arguments.push_back(tokens[i]);
491 if (doubleSize && !rawShot) {
493 "combination with -raw");
495 if (rawShot && withOsd) {
497 "combination with -raw");
501 switch (arguments.size()) {
506 filename = arguments[0];
512 filename,
"screenshots", prefix,
".png");
520 "Failed to take screenshot: " + e.
getMessage());
527 "Current renderer doesn't support taking screenshots.");
529 unsigned height = doubleSize ? 480 : 240;
531 videoLayer->takeRawScreenShot(height, filename);
534 "Failed to take screenshot: " + e.
getMessage());
546 "screenshot Write screenshot to file \"openmsxNNNN.png\"\n"
547 "screenshot <filename> Write screenshot to indicated file\n"
548 "screenshot -prefix foo Write screenshot to file \"fooNNNN.png\"\n"
549 "screenshot -raw 320x240 raw screenshot (of MSX screen only)\n"
550 "screenshot -raw -doublesize 640x480 raw screenshot (of MSX screen only)\n"
551 "screenshot -with-osd Include OSD elements in the screenshot\n"
552 "screenshot -no-sprites Don't include sprites in the screenshot\n";
557 static const char*
const extra[] = {
558 "-prefix",
"-raw",
"-doublesize",
"-with-osd",
"-no-sprites",
576 double fps = 1000000.0 * Display::NUM_FRAME_DURATIONS / display.frameDurationSum;
582 return "Returns the current rendering speed in frames per second.";