From 718936110b9511631fa1f4396be992752bf8b719 Mon Sep 17 00:00:00 2001 From: Alex Xu Date: Thu, 22 Aug 2013 22:45:26 -0400 Subject: include renpy --- unrpyc/renpy/display/module.py | 275 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 unrpyc/renpy/display/module.py (limited to 'unrpyc/renpy/display/module.py') diff --git a/unrpyc/renpy/display/module.py b/unrpyc/renpy/display/module.py new file mode 100644 index 0000000..1bf66e0 --- /dev/null +++ b/unrpyc/renpy/display/module.py @@ -0,0 +1,275 @@ +# Copyright 2004-2013 Tom Rothamel +# +# 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 file mediates access to the _renpy module, which is a C module that +# allows us to enhance the feature set of pygame in a renpy specific way. + +VERSION = (6, 12, 0) + +import renpy.display +import pygame; pygame # prevents pyflakes warning. + +import sys + +try: + import _renpy + version = _renpy.version() + + if version != VERSION: + print("Found Ren'Py module version %s, while expecting %s." % ( + ".".join(str(i) for i in version), + ".".join(str(i) for i in VERSION), + )) + + print("Trying to run anyway, but you should expect errors.", file=sys.stderr) + +except: + print("The _renpy module was not found. Please read module/README.txt for", file=sys.stderr) + print("more information.", file=sys.stderr) + + sys.exit(-1) + +def convert_and_call(function, src, dst, *args): + """ + This calls the function with the source and destination + surface. The surfaces must have the same alpha. + + If the surfaces are not 24 or 32 bits per pixel, or don't have the + same format, they are converted and then converted back. + """ + + # Now that all surfaces are 32bpp, this function doesn't do much + # of anything anymore. + + if (dst.get_masks()[3] != 0) != (src.get_masks()[3] != 0): + raise Exception("Surface alphas do not match.") + + function(src, dst, *args) + + +def pixellate(src, dst, avgwidth, avgheight, outwidth, outheight): + """ + This pixellates the source surface. First, every pixel in the + source surface is projected onto a virtual surface, such that + the average value of every avgwidth x avgheight pixels becomes + one virtual pixel. It then gets projected back onto the + destination surface at a ratio of one virtual pixel to every + outwidth x outheight destination pixels. + + If either src or dst is not a 24 or 32 bit surface, they are + converted... but that may be a significant performance hit. + + The two surfaces must either have the same alpha or no alpha. + """ + + convert_and_call(_renpy.pixellate, + src, dst, + avgwidth, avgheight, + outwidth, outheight) + + +def scale(s, size): + """ + Scales down the supplied pygame surface by the given X and Y + factors. + + Always works, but may not be high quality. + """ + + d = renpy.display.pgrender.surface(size, True) + + bilinear_scale(s, d) + + return d + + +# What we have here are a pair of tables mapping masks to byte offsets +# for 24 and 32 bpp modes. We represent 0xff000000 as positive and negative +# numbers so that it doesn't yield a warning, and so that it works on +# 32 and 64 bit platforms. +if sys.byteorder == 'big': + bo32 = { 255 : 3, 65280 : 2, 16711680 : 1, 4278190080 : 0, -16777216 : 0, } +else: + bo32 = { 255 : 0, 65280 : 1, 16711680 : 2, 4278190080 : 3, -16777216 : 3, } + +bo_cache = None + +def byte_offset(src): + """ + Given the surface src, returns a 4-tuple giving the byte offsets + for the red, green, blue, and alpha components of the pixels in + the surface. If a component doesn't exist, None is returned. + """ + + global bo_cache + + if bo_cache is None: + bo_cache = [ bo32[i] for i in src.get_masks() ] + + return bo_cache + +def endian_order(src, r, g, b, a): + + if bo_cache is None: + byte_offset(src) + + rv = [ a, a, a, a ] + + for i, index_i in zip((r, g, b, a), bo_cache): + rv[index_i] = i + + return rv + + + +def linmap(src, dst, rmap, gmap, bmap, amap): + """ + This maps the colors between two surfaces. The various map + parameters should be fixed-point integers, with 1.0 == 256. + """ + + convert_and_call(_renpy.linmap, + src, dst, + *endian_order(dst, rmap, gmap, bmap, amap)) + + +save_png = _renpy.save_png + +def map(src, dst, rmap, gmap, bmap, amap): #@ReservedAssignment + """ + This maps the colors between two surfaces. The various map + parameters must be 256 character long strings, with the value + of a character at a given offset being what a particular pixel + component value is mapped to. + """ + + convert_and_call(_renpy.map, + src, dst, + *endian_order(dst, rmap, gmap, bmap, amap)) + + + +def twomap(src, dst, white, black): + """ + Given colors for white and black, linearly maps things + appropriately, taking the alpha channel from white. + """ + + wr = white[0] + wg = white[1] + wb = white[2] + wa = white[3] + + br = black[0] + bg = black[1] + bb = black[2] + + ramp = renpy.display.im.ramp + + if br == 0 and bg == 0 and bb == 0: + linmap(src, dst, + wr + 1, + wg + 1, + wb + 1, + wa + 1) + else: + list(map(src, dst, + ramp(br, wr), + ramp(bg, wg), + ramp(bb, wb), + ramp(0, wa))) + + +def alpha_munge(src, dst, amap): + """ + This samples the red channel from src, maps it through amap, and + place it into the alpha channel of amap. + """ + + if src.get_size() != dst.get_size(): + return + + red = byte_offset(src)[0] + alpha = byte_offset(dst)[3] + + if red is not None and alpha is not None: + _renpy.alpha_munge(src, dst, red, alpha, amap) + + +def bilinear_scale(src, dst, sx=0, sy=0, sw=None, sh=None, dx=0, dy=0, dw=None, dh=None, precise=0): + + if sw is None: + sw, sh = src.get_size() + if dw is None: + dw, dh = dst.get_size() + + while True: + + if sw <= dw * 2 and sh <= dh * 2: + break + + nsw = max(sw / 2, dw) + nsh = max(sh / 2, dh) + + nsrc = renpy.display.pgrender.surface((nsw, nsh), src.get_masks()[3]) + + _renpy.bilinear(src, nsrc, sx, sy, sw, sh, precise=precise) + + sx = 0 + sy = 0 + sw = nsw + sh = nsh + src = nsrc + + _renpy.bilinear(src, dst, sx, sy, sw, sh, dx, dy, dw, dh, precise=precise) + + +transform = _renpy.transform + +# Note: Blend requires all surfaces to be the same size. +blend = _renpy.blend + +def imageblend(a, b, dst, img, amap): + alpha = byte_offset(img)[3] + _renpy.imageblend(a, b, dst, img, alpha, amap) + + +def colormatrix(src, dst, matrix): + c = [ matrix[0:5], matrix[5:10], matrix[10:15], matrix[15:20] ] + offs = byte_offset(src) + + o = [ None ] * 4 + for i in range(0, 4): + o[offs[i]] = i + + _renpy.colormatrix(src, dst, + c[o[0]][o[0]], c[o[0]][o[1]], c[o[0]][o[2]], c[o[0]][o[3]], c[o[0]][4], + c[o[1]][o[0]], c[o[1]][o[1]], c[o[1]][o[2]], c[o[1]][o[3]], c[o[1]][4], + c[o[2]][o[0]], c[o[2]][o[1]], c[o[2]][o[2]], c[o[2]][o[3]], c[o[2]][4], + c[o[3]][o[0]], c[o[3]][o[1]], c[o[3]][o[2]], c[o[3]][o[3]], c[o[3]][4]) + + +def subpixel(src, dst, x, y): + + shift = src.get_shifts()[3] + _renpy.subpixel(src, dst, x, y, shift) + + -- cgit v1.2.3-54-g00ecf