diff options
Diffstat (limited to 'unrpyc/renpy/display/video.py')
-rw-r--r-- | unrpyc/renpy/display/video.py | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/unrpyc/renpy/display/video.py b/unrpyc/renpy/display/video.py new file mode 100644 index 0000000..5451e89 --- /dev/null +++ b/unrpyc/renpy/display/video.py @@ -0,0 +1,234 @@ +# Copyright 2004-2013 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. + +import renpy.display +import renpy.audio + +# The movie displayable that's currently being shown on the screen. +current_movie = None + +# True if the movie that is currently displaying is in fullscreen mode, +# False if it's a smaller size. +fullscreen = False + +# The size of a Movie object that hasn't had an explicit size set. +default_size = (400, 300) + +# The file we allocated the surface for. +surface_file = None + +# The surface to display the movie on, if not fullscreen. +surface = None + +def movie_stop(clear=True, only_fullscreen=False): + """ + Stops the currently playing movie. + """ + + if (not fullscreen) and only_fullscreen: + return + + renpy.audio.music.stop(channel='movie') + + +def movie_start(filename, size=None, loops=0): + """ + This starts a movie playing. + """ + + if renpy.game.less_updates: + return + + global default_size + + if size is not None: + default_size = size + + filename = [ filename ] + + if loops == -1: + loop = True + else: + loop = False + filename = filename * (loops + 1) + + renpy.audio.music.play(filename, channel='movie', loop=loop) + +movie_start_fullscreen = movie_start +movie_start_displayable = movie_start + +def early_interact(): + """ + Called early in the interact process, to clear out the fullscreen + flag. + """ + + global fullscreen + global current_movie + + fullscreen = True + current_movie = None + + +def interact(): + """ + This is called each time the screen is redrawn. It helps us decide if + the movie should be displayed fullscreen or not. + """ + + global surface + global surface_file + + if not renpy.audio.music.get_playing("movie"): + surface = None + surface_file = None + return False + + if fullscreen: + return True + else: + return False + +def get_movie_texture(): + """ + Gets a movie texture we can draw to the screen. + """ + + global surface + global surface_file + + playing = renpy.audio.music.get_playing("movie") + + pss = renpy.audio.audio.pss + + if pss: + size = pss.movie_size() + else: + size = (64, 64) + + if (surface is None) or (surface.get_size() != size) or (surface_file != playing): + surface = renpy.display.pgrender.surface(size, False) + surface_file = playing + surface.fill((0, 0, 0, 255)) + + tex = None + + if playing is not None: + renpy.display.render.mutated_surface(surface) + tex = renpy.display.draw.load_texture(surface, True) + + return tex + + +def render_movie(width, height): + tex = get_movie_texture() + + if tex is None: + return None + + sw, sh = tex.get_size() + + scale = min(1.0 * width / sw, 1.0 * height / sh) + + dw = scale * sw + dh = scale * sh + + rv = renpy.display.render.Render(width, height, opaque=True) + rv.forward = renpy.display.render.Matrix2D(1.0 / scale, 0.0, 0.0, 1.0 / scale) + rv.reverse = renpy.display.render.Matrix2D(scale, 0.0, 0.0, scale) + rv.blit(tex, (int((width - dw) / 2), int((height - dh) / 2))) + + return rv + +class Movie(renpy.display.core.Displayable): + """ + This is a displayable that shows the current movie. + """ + + fullscreen = False + + def __init__(self, fps=24, size=None, **properties): + """ + @param fps: The framerate that the movie should be shown at. + """ + super(Movie, self).__init__(**properties) + self.size = size + + def render(self, width, height, st, at): + + size = self.size + + if size is None: + size = default_size + + width, height = size + + rv = render_movie(width, height) + + if rv is None: + rv = renpy.display.render.Render(0, 0) + + # Usually we get redrawn when the frame is ready - but we want + # the movie to disappear if it's ended, or if it hasn't started + # yet. + renpy.display.render.redraw(self, 0.1) + + return rv + + + def per_interact(self): + global fullscreen + fullscreen = False + + global current_movie + current_movie = self + + +def playing(): + return renpy.audio.music.get_playing("movie") + +def frequent(): + """ + Called to update the video playback. Returns true if a video refresh is + needed, false otherwise. + """ + + if not playing(): + return 0 + + pss = renpy.audio.audio.pss + + if pss.needs_alloc(): + + if renpy.display.video.fullscreen and renpy.display.draw.fullscreen_surface: + surf = renpy.display.draw.fullscreen_surface + else: + get_movie_texture() + surf = renpy.display.scale.real(surface) + + pss.alloc_event(surf) + + rv = pss.refresh_event() + + if rv and current_movie is not None: + renpy.display.render.redraw(current_movie, 0) + + return rv |