479 lines
14 KiB
Text
479 lines
14 KiB
Text
# Copyright 2004-2019 Tom Rothamel <pytom@bishoujo.us>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person
|
|
# obtaining a copy of this software and associated documentation files
|
|
# (the "Software"), to deal in the Software without restriction,
|
|
# including without limitation the rights to use, copy, modify, merge,
|
|
# publish, distribute, sublicense, and/or sell copies of the Software,
|
|
# and to permit persons to whom the Software is furnished to do so,
|
|
# subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be
|
|
# included in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
# This contains code to choose between OpenGL and Software rendering, when
|
|
# a system supports both.
|
|
|
|
init -1500:
|
|
|
|
python hide:
|
|
import os
|
|
store.__dxwebsetup = os.path.join(config.renpy_base, "lib", "windows-i686", "dxwebsetup.exe")
|
|
|
|
python:
|
|
class _SetRenderer(Action):
|
|
"""
|
|
Sets the preferred renderer to one of "auto", "angle", "gl", or
|
|
"sw".
|
|
"""
|
|
|
|
def __init__(self, renderer):
|
|
self.renderer = renderer
|
|
|
|
def __call__(self):
|
|
_preferences.renderer = self.renderer
|
|
renpy.restart_interaction()
|
|
|
|
def get_selected(self):
|
|
return _preferences.renderer == self.renderer
|
|
|
|
# This is displayed to ask the user to choose the renderer he or she
|
|
# wants to use. It takes no parameters, doesn't return anything, and
|
|
# is expected to call _SetRenderer actions and quit when done.
|
|
#
|
|
# This screen can be customized by the creator, provided the actions
|
|
# remain available.
|
|
screen _choose_renderer:
|
|
|
|
frame:
|
|
style_group ""
|
|
|
|
has side "c b":
|
|
spacing gui._scale(10)
|
|
xfill True
|
|
yfill True
|
|
|
|
fixed:
|
|
|
|
vbox:
|
|
|
|
xmaximum 0.48
|
|
|
|
label _("Renderer")
|
|
|
|
null height 10
|
|
|
|
textbutton _("Automatically Choose"):
|
|
action _SetRenderer("auto")
|
|
style_suffix "radio_button"
|
|
|
|
if renpy.renpy.windows:
|
|
textbutton _("Force Angle/DirectX Renderer"):
|
|
action _SetRenderer("angle")
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("Force OpenGL Renderer"):
|
|
action _SetRenderer("gl")
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("Force Software Renderer"):
|
|
action _SetRenderer("sw")
|
|
style_suffix "radio_button"
|
|
|
|
null height 10
|
|
|
|
label _("NPOT")
|
|
|
|
null height 10
|
|
|
|
textbutton _("Enable"):
|
|
action SetField(_preferences, "gl_npot", True)
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("Disable"):
|
|
action SetField(_preferences, "gl_npot", False)
|
|
style_suffix "radio_button"
|
|
|
|
|
|
null height 10
|
|
|
|
label _("Gamepad")
|
|
|
|
null height 10
|
|
|
|
textbutton _("Enable"):
|
|
action SetField(_preferences, "pad_enabled", True)
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("Disable"):
|
|
action SetField(_preferences, "pad_enabled", False)
|
|
style_suffix "radio_button"
|
|
|
|
null height 10
|
|
|
|
textbutton _("Calibrate"):
|
|
action ui.invokesinnewcontext(_gamepad.calibrate)
|
|
xfill True
|
|
|
|
vbox:
|
|
|
|
xmaximum 0.48
|
|
xpos 0.5
|
|
|
|
label _("Powersave")
|
|
|
|
null height 10
|
|
|
|
textbutton _("Enable"):
|
|
action Preference("gl powersave", True)
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("Disable"):
|
|
action Preference("gl powersave", False)
|
|
style_suffix "radio_button"
|
|
|
|
null height 10
|
|
|
|
label _("Framerate")
|
|
|
|
null height 10
|
|
|
|
textbutton _("Screen"):
|
|
action Preference("gl framerate", None)
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("60"):
|
|
action Preference("gl framerate", 60)
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("30"):
|
|
action Preference("gl framerate", 30)
|
|
style_suffix "radio_button"
|
|
|
|
null height 10
|
|
|
|
label _("Tearing")
|
|
|
|
null height 10
|
|
|
|
textbutton _("Enable"):
|
|
action Preference("gl tearing", True)
|
|
style_suffix "radio_button"
|
|
|
|
textbutton _("Disable"):
|
|
action Preference("gl tearing", False)
|
|
style_suffix "radio_button"
|
|
|
|
null height 10
|
|
|
|
vbox:
|
|
|
|
text _("Changes will take effect the next time this program is run.") substitute True
|
|
|
|
null height 10
|
|
|
|
hbox:
|
|
spacing gui._scale(25)
|
|
|
|
textbutton _(u"Quit"):
|
|
action Quit(confirm=False)
|
|
yalign 1.0
|
|
|
|
if not renpy.display.interface.safe_mode:
|
|
textbutton _("Return"):
|
|
action Return(0)
|
|
yalign 1.0
|
|
|
|
|
|
# This is displayed when a display performance problem occurs.
|
|
#
|
|
# `problem` is the kind of problem that is occuring. It can be:
|
|
# - "sw" if the software renderer was selected.
|
|
# - "slow" if the performance test failed.
|
|
# - "fixed" if we're operating w/o shaders.
|
|
# - other things, added in the future.
|
|
#
|
|
# `url` is the url of a web page on renpy.org that will include
|
|
# info on troubleshooting display problems.
|
|
screen _performance_warning:
|
|
|
|
frame:
|
|
style_group ""
|
|
|
|
has vbox
|
|
|
|
label _("Performance Warning")
|
|
|
|
null height 10
|
|
|
|
if problem == "sw":
|
|
text _("This computer is using software rendering.")
|
|
elif problem == "fixed":
|
|
text _("This computer is not using shaders.")
|
|
elif problem == "slow":
|
|
text _("This computer is displaying graphics slowly.")
|
|
else:
|
|
text _("This computer has a problem displaying graphics: [problem].") substitute True
|
|
|
|
null height 10
|
|
|
|
if directx_update:
|
|
text _("Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display. Updating DirectX could fix this problem.")
|
|
else:
|
|
text _("Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display.")
|
|
|
|
if directx_update:
|
|
null height 10
|
|
|
|
textbutton _("Update DirectX"):
|
|
action directx_update
|
|
xfill True
|
|
|
|
null height 10
|
|
|
|
textbutton _("Continue, Show this warning again"):
|
|
action Return(True)
|
|
xfill True
|
|
|
|
textbutton _("Continue, Don't show warning again"):
|
|
action Return(False)
|
|
xfill True
|
|
|
|
null height 10
|
|
|
|
textbutton _("Quit"):
|
|
action Quit(confirm=False)
|
|
xfill True
|
|
|
|
# Used while a directx update is ongoing.
|
|
screen _directx_update:
|
|
|
|
frame:
|
|
style_group ""
|
|
|
|
has vbox
|
|
|
|
label _("Updating DirectX.")
|
|
|
|
null height 10
|
|
|
|
text _("DirectX web setup has been started. It may start minimized in the taskbar. Please follow the prompts to install DirectX.")
|
|
|
|
null height 10
|
|
|
|
text _("{b}Note:{/b} Microsoft's DirectX web setup program will, by default, install the Bing toolbar. If you do not want this toolbar, uncheck the appropriate box.")
|
|
|
|
null height 10
|
|
|
|
text _("When setup finishes, please click below to restart this program.")
|
|
|
|
textbutton _("Restart") action Return(True)
|
|
|
|
|
|
|
|
init -1500 python:
|
|
# The image that we fill the screen with in GL-test mode.
|
|
config.gl_test_image = "black"
|
|
|
|
class __GLTest(renpy.Displayable):
|
|
"""
|
|
This counts the number of times it's been rendered, and
|
|
the number of seconds it's been displayed, and uses them
|
|
to make the decisions as to if OpenGL is working or not.
|
|
"""
|
|
|
|
def __init__(self, frames, fps, timeout):
|
|
super(__GLTest, self).__init__()
|
|
|
|
self.target = 1.0 * frames / fps
|
|
self.frames = frames
|
|
self.timeout = timeout
|
|
|
|
self.times = [ ]
|
|
self.success = False
|
|
|
|
renpy.renpy.display.log.write("- Target is {0} frames in {1} seconds.".format(frames, self.target))
|
|
|
|
def render(self, width, height, st, at):
|
|
rv = renpy.Render(width, height)
|
|
|
|
if self.success:
|
|
return rv
|
|
|
|
self.times.append(st)
|
|
|
|
renpy.redraw(self, 0)
|
|
|
|
renpy.renpy.display.log.write("- Frame drawn at %f seconds." % st)
|
|
|
|
if len(self.times) >= self.frames:
|
|
frames_timing = self.times[-1] - self.times[-self.frames]
|
|
|
|
renpy.renpy.display.log.write("- %f seconds to render %d frames.", frames_timing, self.frames)
|
|
|
|
if frames_timing <= self.target:
|
|
self.success = True
|
|
renpy.timeout(0)
|
|
|
|
return rv
|
|
|
|
def event(self, ev, x, y, st):
|
|
|
|
if self.success:
|
|
return True
|
|
|
|
if st > self.timeout:
|
|
return False
|
|
|
|
renpy.timeout(self.timeout - st)
|
|
|
|
config.performance_test = True
|
|
|
|
def __gl_test():
|
|
|
|
import os
|
|
|
|
# If we've entered safe mode, display the renderer choice screen.
|
|
# This screen will cause us to quit.
|
|
|
|
if _restart:
|
|
return
|
|
|
|
if not config.gl_enable:
|
|
return
|
|
|
|
if renpy.display.interface.safe_mode:
|
|
renpy.call_in_new_context("_choose_renderer")
|
|
|
|
if not config.performance_test:
|
|
return
|
|
|
|
_gl_performance_test()
|
|
|
|
def _gl_performance_test():
|
|
|
|
import os
|
|
|
|
performance_test = os.environ.get("RENPY_PERFORMANCE_TEST", None)
|
|
|
|
if performance_test is not None:
|
|
performance_test = int(performance_test)
|
|
|
|
if performance_test == 0:
|
|
return
|
|
|
|
if not _preferences.performance_test and not performance_test:
|
|
return
|
|
|
|
# Don't bother on android or ios or emscripten - there's nothing the user can do.
|
|
if renpy.mobile:
|
|
return
|
|
|
|
renpy.renpy.display.log.write("Performance test:")
|
|
|
|
# This will cause the screen to start displaying.
|
|
ui.pausebehavior(0)
|
|
ui.interact(suppress_underlay=True, suppress_overlay=True)
|
|
|
|
# The problem we have.
|
|
problem = None
|
|
|
|
renderer_info = renpy.get_renderer_info()
|
|
|
|
if config.gl2 and not renderer_info.get("models", False):
|
|
problem = "fixed"
|
|
|
|
# Software renderer check.
|
|
elif config.renderer != "sw" and renderer_info["renderer"] == "sw":
|
|
problem = "sw"
|
|
|
|
# Speed check.
|
|
if problem is None:
|
|
|
|
# The parameters of the performance test. If we do not hit FPS fps
|
|
# over FRAMES frames before DELAY seconds are up, we fail.
|
|
FRAMES = 5
|
|
FPS = 15
|
|
DELAY = 1.5
|
|
|
|
renpy.transition(Dissolve(DELAY), always=True, force=True)
|
|
ui.add(__GLTest(FRAMES, FPS, DELAY))
|
|
result = ui.interact(suppress_overlay=True, suppress_underlay=True)
|
|
|
|
if not result:
|
|
problem = "slow"
|
|
|
|
# Lack of shaders check.
|
|
if problem is None:
|
|
if not "RENPY_GL_ENVIRON" in os.environ:
|
|
if renderer_info["renderer"] == "gl" and renderer_info["environ"] == "fixed":
|
|
problem = "fixed"
|
|
|
|
if problem is None:
|
|
return
|
|
|
|
if renpy.renpy.windows and os.path.exists(__dxwebsetup):
|
|
directx_update = Jump("_directx_update")
|
|
else:
|
|
directx_update = None
|
|
|
|
# Give the warning message to the user.
|
|
renpy.show_screen("_performance_warning", problem=problem, directx_update=directx_update, _transient=True)
|
|
result = ui.interact(suppress_overlay=True, suppress_underlay=True)
|
|
|
|
|
|
# Store the user's choice, and continue.
|
|
_preferences.performance_test = result
|
|
return
|
|
|
|
|
|
label _gl_test:
|
|
|
|
# Show the test image.
|
|
scene black
|
|
show expression config.gl_test_image
|
|
with None
|
|
|
|
$ __gl_test()
|
|
|
|
# Hide the test image.
|
|
scene black
|
|
|
|
return
|
|
|
|
# We can assume we're on windows here. We're also always restart once we
|
|
# make it here.
|
|
label _directx_update:
|
|
|
|
if renpy.has_label("directx_update"):
|
|
jump expression "directx_update"
|
|
|
|
label _directx_update_main:
|
|
|
|
python hide:
|
|
|
|
# Start dxsetup. We have to go through startfile to ensure that UAC
|
|
# doesn't cause problems.
|
|
import os
|
|
os.startfile(__dxwebsetup)
|
|
|
|
renpy.show_screen("_directx_update")
|
|
ui.interact(suppress_overlay=True, suppress_underlay=True)
|
|
|
|
renpy.quit(relaunch=True)
|
|
|
|
label _choose_renderer:
|
|
scene expression "#000"
|
|
|
|
$ renpy.shown_window()
|
|
$ renpy.show_screen("_choose_renderer", _transient=True)
|
|
$ ui.interact(suppress_overlay=True, suppress_underlay=True)
|
|
return
|