Compare commits
187 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 375af0cccd | |||
| 8ae8e887f5 | |||
| 201b6432c4 | |||
| fc10bbf6b6 | |||
| 1c82c71aea | |||
| a59abd3135 | |||
| a51633b511 | |||
| 2b40d265f9 | |||
| 734b5b02f8 | |||
| 4120434e5a | |||
| 6d9c4dc6d9 | |||
| ce94a1360a | |||
| 27a61f4faf | |||
| 36f50a482b | |||
| 28d681b29b | |||
| ddb53bfce1 | |||
| 81414254f9 | |||
| 4af4481a17 | |||
| f1cff045e1 | |||
| f75f0ccb14 | |||
| 01f82aaf4c | |||
| 8b294e05ad | |||
| 5b2fcb85e5 | |||
| fb1d38dc3a | |||
| 5cc6a8d75a | |||
| fbe2a03933 | |||
| 915bccf099 | |||
| 0943e368e7 | |||
| d35c6e190c | |||
| 1025ad5a6a | |||
| fd74541318 | |||
| 821db477ae | |||
| ed66034930 | |||
| a9c91378fd | |||
| 1dc58f2ed1 | |||
| ae916e2a59 | |||
| f3af72e67e | |||
| 939c2121b7 | |||
| 46699bfc1e | |||
| 63d381d5a6 | |||
| c608d18684 | |||
| c31f61e7b6 | |||
| 9912c15c04 | |||
| 651653593c | |||
| 85858974b8 | |||
| a265fbb797 | |||
| e353ea2d56 | |||
| 6f91db067a | |||
| 8ed51cc810 | |||
| f256f174f9 | |||
| 49d3796378 | |||
| bfb6a18527 | |||
| 2960220a74 | |||
| c6605f1742 | |||
| cebffcfee1 | |||
| 006cdb8c3b | |||
| 374e0697bf | |||
| f988878424 | |||
| e59b252dce | |||
| b2747914d8 | |||
| 41aeb625f3 | |||
| 4cfa8aa06c | |||
| 8cb4a4e3b9 | |||
| 9a84c9715f | |||
| 38538f1d9a | |||
| 6a42b2a107 | |||
| 486790b810 | |||
| 0e538e2261 | |||
| 9042fcca55 | |||
| 040035adbc | |||
| d72097de18 | |||
| d9771bdade | |||
| 07ca905373 | |||
| ccd0d45a67 | |||
| 15a15870e7 | |||
| 28108c7796 | |||
| 171f388120 | |||
| bc50f171db | |||
| ea4c955f1f | |||
| 27524457d0 | |||
| 01fe67cfa9 | |||
| f4d493465d | |||
| 33cbe44390 | |||
| 5214f08d1a | |||
| 608fc986c4 | |||
| 779a96f97f | |||
| faf48246d7 | |||
| 81ec2a6c35 | |||
| 803423f12b | |||
| b384ee0381 | |||
| b8862d6b24 | |||
| dbfa4ed46d | |||
| d9eb999775 | |||
| b4a9ca3f87 | |||
| d087c86d1a | |||
| 0cfc7b25a6 | |||
| 8f3c9bd2ba | |||
| 91c79cdac9 | |||
| 20e4e110ce | |||
| 870d7ffe2c | |||
| 6ff88c914d | |||
| 2a2078517f | |||
| c09f697293 | |||
| a9e273a13d | |||
| 592665aa9a | |||
| 3745788f06 | |||
| 52b09d8f4c | |||
| 32f25cdcec | |||
| 6f022a9b6a | |||
| eea6970929 | |||
| 35ecfd279f | |||
| 1f5c610843 | |||
| 05f4c52c33 | |||
| 326f773e75 | |||
| 2079b518a2 | |||
| 70ed15e5ac | |||
| f1d7fe0c73 | |||
| 08e4b9bafc | |||
| 56a0212316 | |||
| 5df6506191 | |||
| 39779be980 | |||
| bdacdddf14 | |||
| 4b32337ef3 | |||
| 4897d5b7a9 | |||
| 6daa64facd | |||
| 07651e414d | |||
| 7e1e76f0d8 | |||
| b91a5d1a16 | |||
| 39b0646f24 | |||
| ea6406f144 | |||
| 7ed3f3fbad | |||
| cacb4ac40e | |||
| 9503744631 | |||
| 58dfd5dbfa | |||
| 60d5507184 | |||
| 5641cec146 | |||
| dd455e3d14 | |||
| 6876697f74 | |||
| 4373cab8cf | |||
| eeccb5833b | |||
| 790dad0330 | |||
| 078a38af5d | |||
| 8c186d2eb1 | |||
| 81b94b27e0 | |||
| 17e8616e8c | |||
| 50b0dc3c5e | |||
| 9e217e722f | |||
| f466b44b66 | |||
| 34e0fc7cba | |||
| bb88a7bb95 | |||
| 71ba444e62 | |||
| 3e0baee463 | |||
| a0064f5511 | |||
| e7ce23f377 | |||
| 9c6d93968c | |||
| e4b29d58f4 | |||
| a48b87a0d6 | |||
| 763515a937 | |||
| 46a8242e51 | |||
| efa8d66d3d | |||
| b7c71bb3b8 | |||
| aca5438b5a | |||
| e7eb23ab5e | |||
| 05dd8bfcc7 | |||
| 2c299ab079 | |||
| 62acff5c75 | |||
| 316d146893 | |||
| e69fee2108 | |||
| 8fe6e1cf20 | |||
| 6fcf7dbbba | |||
| f55c5f0ce5 | |||
| aaf8369421 | |||
| 8e26c7730c | |||
| 556ca0611a | |||
| e2e78c175b | |||
| 7b8033e6b2 | |||
| d602645fee | |||
| f8ac9c9e83 | |||
| 98c90f8ab3 | |||
| 16bb21ee62 | |||
| 46bfec93d4 | |||
| 00e1ecf37d | |||
| a3e7b290fb | |||
| 27ce59963f | |||
| 54e3a97447 | |||
| f886f710b7 | |||
| a895e1dc6c |
@@ -49,7 +49,6 @@ renpygame-1.2.zip
|
||||
speedtest
|
||||
styles.txt
|
||||
renpygame-demo/game/saves
|
||||
./lib
|
||||
Lucy Sprites.zip
|
||||
translate
|
||||
close_bugs.py
|
||||
@@ -58,3 +57,13 @@ scite-6.10.zip
|
||||
scite-renpy-20090803.zip
|
||||
module/cython.sh
|
||||
old_demo
|
||||
opengl.txt
|
||||
Microsoft.VC90.CRT.manifest
|
||||
console.exe
|
||||
msvcr90.dll
|
||||
python26.dll
|
||||
renpy.exe
|
||||
lib/windows-x86
|
||||
sphinx/source/inc/*
|
||||
doc/*
|
||||
updates/prerelease
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
License
|
||||
=======
|
||||
|
||||
Ren'Py itself is covered by the terms of the following (MIT) license:
|
||||
Most of Ren'Py is covered by the terms of the following (MIT) license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
@@ -23,13 +23,15 @@ Ren'Py itself is covered by the terms of the following (MIT) license:
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Portions of Ren'Py are derived from code that is copyright using the
|
||||
Lesser GNU Public License, so Ren'Py games must be distributed in a
|
||||
manner that satisfies the LGPL.
|
||||
|
||||
Please see each individual source file for a list of copyright
|
||||
holders. The artwork in the demo is released by various copyright
|
||||
holders, under the same terms.
|
||||
|
||||
The Ren'Py module, the Ren'Py windows binaries, and the various Ren'Py
|
||||
launchers may contain code taken from the following projects:
|
||||
Ren'Py binaries include code from the following projects:
|
||||
|
||||
* Python (Python License)
|
||||
* Pygame (LGPL)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
dist/Microsoft.VC90.CRT.manifest
|
||||
@@ -5,6 +5,8 @@ if [ "x$1" = "x" ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
rsync -av updates tom@onegeek.org:/home/tom/WWW.update/renpy/
|
||||
|
||||
mkdir ~/ab/website/renpy/dl/$1
|
||||
cp dists/renpy-$1-* ~/ab/website/renpy/dl/$1
|
||||
cp CHANGELOG.txt ~/ab/website/renpy/dl/$1
|
||||
|
||||
@@ -6,15 +6,29 @@ import py2exe
|
||||
import sys
|
||||
import zipfile
|
||||
import traceback
|
||||
import os
|
||||
|
||||
# The pythonpath on my system.
|
||||
sys.path.insert(0, 'c:\\msys\\1.0\\newbuild\\install\\bin')
|
||||
sys.path.insert(0, 'c:\\msys\\1.0\\newbuild\\install\\python')
|
||||
|
||||
def move_from_dist(fn):
|
||||
"""
|
||||
Moves the file `fn` from the dist directory to the main
|
||||
directory. (This means we don't need symlinks on windows.)
|
||||
"""
|
||||
|
||||
if os.path.isdir(fn):
|
||||
shutil.rmtree(fn)
|
||||
elif os.path.exists(fn):
|
||||
os.unlink(fn)
|
||||
|
||||
os.rename("dist/" + fn, fn)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
sys.argv[1:] = [ 'py2exe', '--bundle', '2', '-a', '--dll-excludes', 'w9xpopen.exe', ]
|
||||
# sys.argv[1:] = [ 'py2exe', '-a', '--dll-excludes', 'w9xpopen.exe', ]
|
||||
sys.argv[1:] = [ 'py2exe', '-a', '--dll-excludes', 'w9xpopen.exe', ]
|
||||
|
||||
setup(name="Ren'Py",
|
||||
windows=[ dict(script="renpy.py",
|
||||
@@ -25,7 +39,7 @@ def main():
|
||||
|
||||
console=[ dict(script="renpy.py", dest_base="console") ],
|
||||
|
||||
zipfile='renpy.code',
|
||||
zipfile='lib/windows-x86/renpy.code',
|
||||
|
||||
options={ 'py2exe' : { 'excludes' : [ 'doctest',
|
||||
'pygame.macosx',
|
||||
@@ -49,8 +63,8 @@ def main():
|
||||
)
|
||||
|
||||
|
||||
zfold = zipfile.ZipFile("dist/renpy.code")
|
||||
zfnew = zipfile.ZipFile("renpy.code", "w", zipfile.ZIP_STORED)
|
||||
zfold = zipfile.ZipFile("dist/lib/windows-x86/renpy.code")
|
||||
zfnew = zipfile.ZipFile("dist/lib/windows-x86/renpy.code.new", "w", zipfile.ZIP_STORED)
|
||||
|
||||
seen = { }
|
||||
|
||||
@@ -71,8 +85,17 @@ def main():
|
||||
zfold.close()
|
||||
zfnew.close()
|
||||
|
||||
shutil.copy("c:/Python26/Microsoft.VC90.CRT.manifest", "dist/Microsoft.VC90.CRT.manifest")
|
||||
shutil.copy("c:/Python26/msvcr90.dll", "dist/msvcr90.dll")
|
||||
os.unlink("dist/lib/windows-x86/renpy.code")
|
||||
os.rename("dist/lib/windows-x86/renpy.code.new", "dist/lib/windows-x86/renpy.code")
|
||||
|
||||
shutil.copy("c:/Python26/Microsoft.VC90.CRT.manifest", "Microsoft.VC90.CRT.manifest")
|
||||
shutil.copy("c:/Python26/msvcr90.dll", "msvcr90.dll")
|
||||
|
||||
move_from_dist("lib/windows-x86")
|
||||
move_from_dist("console.exe")
|
||||
move_from_dist("python26.dll")
|
||||
move_from_dist("renpy.exe")
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
1#!/usr/bin/env python
|
||||
|
||||
import collections
|
||||
import glob
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
# A map from string to filename, line number where the string is found.
|
||||
strings = collections.defaultdict(list)
|
||||
|
||||
def process(fn):
|
||||
|
||||
lineno = 0
|
||||
|
||||
for data in file(fn, "r"):
|
||||
|
||||
lineno += 1
|
||||
|
||||
matches = [ ]
|
||||
|
||||
matches += re.finditer(r'\bu\"(\\"|[^"])+\"', data)
|
||||
matches += re.finditer(r"\bu\'(\\'|[^'])+\'", data)
|
||||
|
||||
for m in matches:
|
||||
s = m.group(0)[2:-1]
|
||||
|
||||
if "\\u" in s:
|
||||
continue
|
||||
|
||||
if len(s) == 1:
|
||||
continue
|
||||
|
||||
strings[s].append("%s:%d" % (fn, lineno))
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
files = [ ]
|
||||
|
||||
files += glob.glob("launcher2/*.rpy")
|
||||
files += glob.glob("common/*.rpy")
|
||||
files += glob.glob("common/_layout/*.rpym")
|
||||
files += glob.glob("common/_compat/*.rpym")
|
||||
|
||||
for fn in files:
|
||||
process(fn)
|
||||
|
||||
|
||||
converse = [ ]
|
||||
|
||||
for k, v in strings.iteritems():
|
||||
v = " ".join(sorted(v))
|
||||
converse.append((v, k))
|
||||
|
||||
converse.sort()
|
||||
|
||||
print """\
|
||||
# Ren'Py Visual Novel Engine
|
||||
# Copyright (C) 2009 PyTom <pytom@bishoujo.us>
|
||||
# This file is distributed under the same license as the Ren'Py package.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mainline\\n"
|
||||
"Report-Msgid-Bugs-To: PyTom <pytom@bishoujo.us>\\n"
|
||||
"POT-Creation-Date: %s\\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
||||
"MIME-Version: 1.0\\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\\n"
|
||||
"Content-Transfer-Encoding: 8bit\\n"
|
||||
""" % time.strftime("%Y-%m-%d %H:%M%z")
|
||||
|
||||
for v, k in converse:
|
||||
print
|
||||
print "#:", v
|
||||
print "#, python-format"
|
||||
print "msgid \"%s\"" % k
|
||||
print "msgstr \"\""
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ init -1210 python:
|
||||
config.default_transform = None
|
||||
config.start_scene_black = True
|
||||
|
||||
if version <= (6, 11, 0):
|
||||
config.movetransition_respects_offsets = False
|
||||
|
||||
|
||||
init 1210 python hide::
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ init -1110:
|
||||
xpos 1.0 xanchor 0.0 ypos 1.0 yanchor 1.0
|
||||
|
||||
transform default:
|
||||
reset
|
||||
center
|
||||
alpha 1 rotate None zoom 1 xzoom 1 yzoom 1 align (0, 0) alignaround (0, 0) subpixel False size None crop None
|
||||
xpos 0.5 xanchor 0.5 ypos 1.0 yanchor 1.0
|
||||
|
||||
python:
|
||||
config.default_transform = default
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# Copyright 2004-2010 PyTom <pytom@bishoujo.us>
|
||||
# See LICENSE.txt for license details.
|
||||
|
||||
# This contains code to choose between OpenGL and Software rendering, when
|
||||
# a system supports both.
|
||||
|
||||
init -1024:
|
||||
screen _gl_test:
|
||||
frame:
|
||||
xalign .5
|
||||
yalign .33
|
||||
|
||||
xpadding 20
|
||||
ypadding 20
|
||||
|
||||
has vbox
|
||||
|
||||
label _(u"Graphics Acceleration")
|
||||
|
||||
null height 10
|
||||
|
||||
textbutton _(u"Automatically Choose"):
|
||||
size_group "gl"
|
||||
action SetField(persistent, "_gl_test", "auto")
|
||||
textbutton _(u"Prefer Software Renderer"):
|
||||
size_group "gl"
|
||||
action SetField(persistent, "_gl_test", "sw")
|
||||
textbutton _(u"Prefer OpenGL Renderer"):
|
||||
size_group "gl"
|
||||
action SetField(persistent, "_gl_test", "gl")
|
||||
|
||||
null height 10
|
||||
|
||||
textbutton _(u"Continue"):
|
||||
size_group "gl"
|
||||
action Return(True)
|
||||
|
||||
init -1024 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
|
||||
|
||||
def render(self, width, height, st, at):
|
||||
self.times.append(st)
|
||||
|
||||
renpy.redraw(self, 0)
|
||||
|
||||
if len(self.times) >= self.frames:
|
||||
if (self.times[-1] - self.times[-self.frames]) < self.target:
|
||||
self.success = True
|
||||
renpy.timeout(0)
|
||||
|
||||
rv = renpy.Render(width, height)
|
||||
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)
|
||||
|
||||
|
||||
def __gl_prefer_renderers(renderers):
|
||||
"""
|
||||
Forces the current renderer to be renderer, one of gl or sw.
|
||||
"""
|
||||
|
||||
if renpy.display.prefer_renderers == renderers:
|
||||
return
|
||||
|
||||
renpy.display.prefer_renderers = renderers
|
||||
renpy.display_reset()
|
||||
|
||||
def __gl_prompt():
|
||||
"""
|
||||
Decides if we want to prompt the user to enable OpenGL mode.
|
||||
If so, shows a screen that allows the user to alter the
|
||||
OpenGL setting.
|
||||
"""
|
||||
|
||||
if not renpy.display.interface.safe_mode:
|
||||
return
|
||||
|
||||
__gl_prefer_renderers("sw")
|
||||
|
||||
renpy.call_screen("_gl_test")
|
||||
|
||||
renpy.display.interface.safe_mode = False
|
||||
|
||||
def __gl_test():
|
||||
"""
|
||||
Makes the decision as to if we should use GL or SW mode.
|
||||
"""
|
||||
|
||||
import os
|
||||
if "RENPY_RENDERER" in os.environ:
|
||||
return
|
||||
|
||||
# Our decision survives a restart.
|
||||
if _restart:
|
||||
return
|
||||
|
||||
# If GL is disabled, don't bother.
|
||||
if not config.gl_enable:
|
||||
return
|
||||
|
||||
__gl_prompt()
|
||||
|
||||
if persistent._gl_test == "gl":
|
||||
__gl_prefer_renderers("gl,sw")
|
||||
return
|
||||
|
||||
if persistent._gl_test == "sw":
|
||||
__gl_prefer_renderers("sw")
|
||||
return
|
||||
|
||||
__gl_prefer_renderers("gl,sw")
|
||||
|
||||
ui.pausebehavior(0)
|
||||
ui.interact(suppress_underlay=True, suppress_overlay=True)
|
||||
|
||||
# If GL is able to render FRAMES frames at FPS fps in less
|
||||
# than DELAY seconds, we consider it to be operational, and
|
||||
# continue in GL mode. Otherwise, we rever to software
|
||||
# rendering mode.
|
||||
FRAMES = 5
|
||||
FPS = 15
|
||||
DELAY = 1
|
||||
|
||||
renpy.transition(Dissolve(DELAY), always=True, force=True)
|
||||
ui.add(__GLTest(FRAMES, FPS, DELAY))
|
||||
result = ui.interact(suppress_overlay=True, suppress_underlay=True)
|
||||
|
||||
if result:
|
||||
__gl_prefer_renderers("gl,sw")
|
||||
else:
|
||||
__gl_prefer_renderers("sw")
|
||||
|
||||
# Init-time code:
|
||||
# Make a guess as to what modes we should be in.
|
||||
if persistent._gl_test is None:
|
||||
persistent._gl_test = "auto"
|
||||
|
||||
if persistent._gl_test == "sw":
|
||||
renpy.display.prefer_renderers = "sw"
|
||||
|
||||
|
||||
label _gl_test:
|
||||
|
||||
# Show the test image.
|
||||
scene
|
||||
show expression config.gl_test_image
|
||||
|
||||
$ __gl_test()
|
||||
|
||||
# Hide the test image.
|
||||
scene
|
||||
|
||||
return
|
||||
|
||||
@@ -62,7 +62,7 @@ init -1105 python hide:
|
||||
if renpy.has_screen("load") and renpy.has_screen("save"):
|
||||
defaults["load_save"] = layout.screen_load_save
|
||||
|
||||
if renpy.has_screen("yesno"):
|
||||
if renpy.has_screen("yesno_prompt"):
|
||||
defaults["yesno_prompt"] = layout.screen_yesno_prompt
|
||||
|
||||
if renpy.has_screen("preferences"):
|
||||
@@ -386,5 +386,49 @@ init -1105 python hide:
|
||||
layout.QUIT = u"Are you sure you want to quit?"
|
||||
layout.MAIN_MENU = u"Are you sure you want to return to the main menu?\nThis will lose unsaved progress."
|
||||
|
||||
@layout
|
||||
def yesno_screen(message, yes=None, no=None):
|
||||
"""
|
||||
:doc: other
|
||||
|
||||
|
||||
This causes the a yes/no prompt screen with the given message
|
||||
to be displayed. The screen will be hidden when the user hits
|
||||
yes or no.
|
||||
|
||||
`message`
|
||||
The message that will be displayed.
|
||||
|
||||
`yes`
|
||||
An action that is run when the user chooses yes.
|
||||
|
||||
`no`
|
||||
An action that is run when the user chooses no.
|
||||
"""
|
||||
|
||||
if renpy.has_screen("yesno_prompt"):
|
||||
|
||||
yes_action = [ Hide("yesno_prompt") ]
|
||||
no_action = [ Hide("yesno_prompt") ]
|
||||
|
||||
if yes is not None:
|
||||
yes_action.append(yes)
|
||||
if no is not None:
|
||||
no_action.append(no)
|
||||
|
||||
renpy.show_screen(
|
||||
"yesno_prompt",
|
||||
message=message,
|
||||
yes_action=yes_action,
|
||||
no_action=no_action)
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
return
|
||||
|
||||
if renpy.invoke_in_new_context(layout.yesno_prompt, None, message):
|
||||
if yes is not None:
|
||||
yes()
|
||||
else:
|
||||
if no is not None:
|
||||
no()
|
||||
|
||||
|
||||
@@ -90,8 +90,20 @@ init -1180 python:
|
||||
|
||||
|
||||
def _default_empty_window():
|
||||
store.narrator("", interact=False)
|
||||
|
||||
who = _last_say_who
|
||||
|
||||
if who is not None:
|
||||
who = eval(who)
|
||||
|
||||
if who is None:
|
||||
who = narrator
|
||||
|
||||
if isinstance(who, NVLCharacter):
|
||||
nvl_show_core()
|
||||
else:
|
||||
store.narrator("", interact=False)
|
||||
|
||||
config.empty_window = _default_empty_window
|
||||
|
||||
style.skip_indicator = Style(style.default, heavy=True, help='The skip indicator.')
|
||||
@@ -139,19 +151,23 @@ init -1180 python:
|
||||
|
||||
config.help = None
|
||||
|
||||
def _help():
|
||||
if not config.help:
|
||||
def _help(help=None):
|
||||
|
||||
if help is None:
|
||||
help = config.help
|
||||
|
||||
if help is None:
|
||||
return
|
||||
|
||||
if renpy.has_label(config.help):
|
||||
renpy.call_in_new_context(config.help)
|
||||
if renpy.has_label(help):
|
||||
renpy.call_in_new_context(help)
|
||||
return
|
||||
|
||||
_preferences.fullscreen = False
|
||||
|
||||
try:
|
||||
import webbrowser
|
||||
webbrowser.open_new("file:///" + config.basedir + "/" + config.help)
|
||||
webbrowser.open_new("file:///" + config.basedir + "/" + help)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -200,7 +216,10 @@ init -1180 python hide:
|
||||
|
||||
def invoke_game_menu():
|
||||
if renpy.context()._menu:
|
||||
renpy.jump("_noisy_return")
|
||||
if renpy.context()._main_menu:
|
||||
return
|
||||
else:
|
||||
renpy.jump("_noisy_return")
|
||||
else:
|
||||
if config.game_menu_action:
|
||||
renpy.display.behavior.run(config.game_menu_action)
|
||||
@@ -406,7 +425,7 @@ init 1180 python:
|
||||
_preferences.text_cps = config.default_text_cps
|
||||
|
||||
if config.default_afm_time is not None:
|
||||
_preferences.default_afm_time = config.default_afm_time
|
||||
_preferences.afm_time = config.default_afm_time
|
||||
|
||||
if config.default_afm_enable is not None:
|
||||
_preferences.afm_enable = config.default_afm_enable
|
||||
@@ -562,7 +581,7 @@ label _enter_menu:
|
||||
renpy.context()._menu = True
|
||||
|
||||
# This may be changed, if we are already in the main menu.
|
||||
renpy.context().main_menu = False
|
||||
renpy.context()._main_menu = False
|
||||
renpy.context_dynamic("main_menu")
|
||||
renpy.context_dynamic("_window_subtitle")
|
||||
renpy.context_dynamic("_window")
|
||||
@@ -651,7 +670,7 @@ label _noisy_return:
|
||||
# Return to the game.
|
||||
label _return:
|
||||
|
||||
if renpy.context().main_menu:
|
||||
if renpy.context()._main_menu:
|
||||
$ renpy.transition(config.game_main_transition)
|
||||
jump _main_menu_screen
|
||||
|
||||
@@ -685,6 +704,7 @@ init -1180 python hide:
|
||||
# after_load.
|
||||
label _after_load:
|
||||
$ renpy.context()._menu = False
|
||||
$ renpy.context()._main_menu = False
|
||||
|
||||
if config.after_load_transition:
|
||||
$ renpy.transition(config.after_load_transition, force=True)
|
||||
@@ -705,7 +725,11 @@ label _start:
|
||||
|
||||
for i in config.start_callbacks:
|
||||
i()
|
||||
|
||||
|
||||
$ renpy.block_rollback()
|
||||
|
||||
call _gl_test
|
||||
|
||||
call _load_reload_game from _call__load_reload_game_1
|
||||
|
||||
if not _restart and config.auto_load and renpy.can_load(config.auto_load):
|
||||
@@ -777,7 +801,7 @@ label _main_menu(_main_menu_screen="_main_menu_screen"):
|
||||
renpy.dynamic("_load_prompt")
|
||||
_load_prompt = False
|
||||
|
||||
renpy.context().main_menu = True
|
||||
renpy.context()._main_menu = True
|
||||
store.main_menu = True
|
||||
|
||||
jump expression _main_menu_screen
|
||||
|
||||
@@ -21,7 +21,7 @@ init -1130 python hide:
|
||||
for i in xrange(0, 8):
|
||||
renpy.music.register_channel(i)
|
||||
|
||||
renpy.music.register_channel("movie", "music", False, stop_on_mute=False)
|
||||
renpy.music.register_channel("movie", "music", False, stop_on_mute=False, buffer_queue=False)
|
||||
|
||||
# Set up default names for some of the channels.
|
||||
renpy.music.alias_channel(0, "sound")
|
||||
|
||||
@@ -245,6 +245,7 @@ init -1100 python:
|
||||
nvl_clear()
|
||||
|
||||
def do_extend(self):
|
||||
renpy.mode(self.mode)
|
||||
store.nvl_list = store.nvl_list[:-1]
|
||||
|
||||
# The default NVLCharacter.
|
||||
@@ -254,6 +255,7 @@ init -1100 python:
|
||||
what_style='nvl_dialogue',
|
||||
window_style='nvl_entry',
|
||||
type='nvl',
|
||||
mode='nvl',
|
||||
clear=False,
|
||||
kind=adv)
|
||||
|
||||
@@ -265,6 +267,8 @@ init -1100 python:
|
||||
|
||||
def nvl_menu(items):
|
||||
|
||||
renpy.mode('nvl_menu')
|
||||
|
||||
if nvl_list is None:
|
||||
store.nvl_list = [ ]
|
||||
|
||||
@@ -312,29 +316,23 @@ init -1100 python:
|
||||
config.nvl_adv_transition = None
|
||||
config.adv_nvl_transition = None
|
||||
|
||||
init 1140 python:
|
||||
|
||||
if config.nvl_adv_transition or config.adv_nvl_transition:
|
||||
# This is used to execute the nvl and adv mode transitions.
|
||||
def _nvl_adv_callback(mode, old_modes):
|
||||
|
||||
def _nvl_adv_callback(event, interact, type, **kwargs):
|
||||
|
||||
if event != "begin" or not interact or renpy.get_transition():
|
||||
return
|
||||
|
||||
old_type = renpy.last_interact_type()
|
||||
|
||||
if old_type == "say" and type == "nvl":
|
||||
# We have an extra line in the nvl_list as we do this. So
|
||||
# take it out for the duration of the nvl_show.
|
||||
old_nvl_list = store.nvl_list
|
||||
store.nvl_list = old_nvl_list[:-1]
|
||||
nvl_show(config.adv_nvl_transition)
|
||||
store.nvl_list = old_nvl_list
|
||||
elif old_type == "nvl" and type == "say":
|
||||
nvl_hide(config.nvl_adv_transition)
|
||||
|
||||
config.all_character_callbacks.insert(0, _nvl_adv_callback)
|
||||
old = old_modes[0]
|
||||
|
||||
if config.adv_nvl_transition:
|
||||
if mode == "nvl" or mode == "nvl_menu":
|
||||
if old == "say" or old == "menu":
|
||||
nvl_show(config.adv_nvl_transition)
|
||||
|
||||
if config.nvl_adv_transition:
|
||||
if mode == "say" or mode == "menu":
|
||||
if old == "nvl" or old == "nvl_menu":
|
||||
nvl_hide(config.nvl_adv_transition)
|
||||
|
||||
config.mode_callbacks.append(_nvl_adv_callback)
|
||||
|
||||
python early hide:
|
||||
|
||||
|
||||
@@ -2,30 +2,6 @@
|
||||
|
||||
init -1140 python:
|
||||
|
||||
def __yesno_prompt(message, yes=None, no=None):
|
||||
if renpy.has_screen("yesno_prompt"):
|
||||
|
||||
yes_action = [ Hide("yesno_prompt") ]
|
||||
no_action = [ Hide("yesno_prompt") ]
|
||||
|
||||
if yes is not None:
|
||||
yes_action.append(yes)
|
||||
if no is not None:
|
||||
no_action.append(no)
|
||||
|
||||
renpy.display.show_screen(
|
||||
"yesno_prompt",
|
||||
message=message,
|
||||
yes_action=yes_action,
|
||||
no_action=no_action)
|
||||
|
||||
if renpy.invoke_in_new_context(layout.yesno_prompt, None, message):
|
||||
if yes is not None:
|
||||
yes()
|
||||
else:
|
||||
if no is not None:
|
||||
no()
|
||||
|
||||
class Return(Action):
|
||||
"""
|
||||
:doc: control_action
|
||||
@@ -37,13 +13,17 @@ init -1140 python:
|
||||
When in a menu, this returns from the menu.
|
||||
"""
|
||||
|
||||
def __init__(self, value=True):
|
||||
def __init__(self, value=None):
|
||||
self.value = value
|
||||
|
||||
def __call__(self):
|
||||
|
||||
if renpy.context()._main_menu:
|
||||
ShowMenu("main_menu")()
|
||||
if self.value is None:
|
||||
if renpy.context()._main_menu:
|
||||
ShowMenu("main_menu")()
|
||||
else:
|
||||
return True
|
||||
|
||||
else:
|
||||
return self.value
|
||||
|
||||
@@ -71,14 +51,21 @@ init -1140 python:
|
||||
This causes another screen to be shown. `screen` is a string
|
||||
giving the name of the screen. The keyword arguments are
|
||||
passed to the screen being shown.
|
||||
|
||||
If not None, `transition` is use to show the new screen.
|
||||
"""
|
||||
|
||||
def __init__(self, screen, **kwargs):
|
||||
def __init__(self, screen, transition=None, **kwargs):
|
||||
self.screen = screen
|
||||
self.kwargs = kwargs
|
||||
|
||||
self.transition = transition
|
||||
|
||||
def __call__(self):
|
||||
renpy.show_screen(self.screen, **self.kwargs)
|
||||
|
||||
if self.transition is not None:
|
||||
renpy.transition(self.transition)
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
def get_selected(self):
|
||||
@@ -101,13 +88,21 @@ init -1140 python:
|
||||
:doc: control_action
|
||||
|
||||
This causes the screen named `screen` to be hidden, if it is shown.
|
||||
|
||||
`transition`
|
||||
If not None, a transition that occurs when hiding the screen.
|
||||
"""
|
||||
|
||||
def __init__(self, screen):
|
||||
def __init__(self, screen, transition=None):
|
||||
self.screen = screen
|
||||
|
||||
self.transition = transition
|
||||
|
||||
def __call__(self):
|
||||
renpy.hide_screen(self.screen)
|
||||
|
||||
if self.transition is not None:
|
||||
renpy.transition(self.transition)
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
|
||||
@@ -121,7 +116,45 @@ init -1140 python:
|
||||
def __call__(self):
|
||||
_screenshot()
|
||||
|
||||
def HideInterface():
|
||||
"""
|
||||
:doc other_action
|
||||
|
||||
Causes the interface to be hidden until the user clicks.
|
||||
"""
|
||||
|
||||
return ui.callsinnewcontext("_hide_windows")
|
||||
|
||||
|
||||
class With(Action):
|
||||
"""
|
||||
:doc: other_action
|
||||
|
||||
Causes `transition` to occur.
|
||||
"""
|
||||
|
||||
def __init__(self, transition):
|
||||
self.transition = transition
|
||||
|
||||
def __call__(self):
|
||||
renpy.transition(self.transition)
|
||||
renpy.restart_interaction()
|
||||
|
||||
class Notify(Action):
|
||||
"""
|
||||
:doc: other_action
|
||||
|
||||
Displays `message` using :func:`renpy.notify`.
|
||||
"""
|
||||
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
|
||||
def __call__(self):
|
||||
renpy.notify(self.message)
|
||||
|
||||
|
||||
|
||||
class InvertSelected(Action):
|
||||
"""
|
||||
:doc: other_action
|
||||
@@ -145,7 +178,20 @@ init -1140 python:
|
||||
def periodic(self, st):
|
||||
return self.action.periodic(st)
|
||||
|
||||
|
||||
def If(expression, true=None, false=None):
|
||||
"""
|
||||
:doc: other_action
|
||||
|
||||
This returns `true` if `expression` is true, and `false`
|
||||
otherwise. Use this to select an action based on an expression.
|
||||
Note that the default, None, can be used as an action that causes
|
||||
a button to be disabled.
|
||||
"""
|
||||
|
||||
if expression:
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
|
||||
##########################################################################
|
||||
# Menu-related actions.
|
||||
@@ -191,19 +237,24 @@ init -1140 python:
|
||||
|
||||
if not (renpy.has_screen(screen) or renpy.has_label(screen)):
|
||||
screen = screen + "_screen"
|
||||
|
||||
|
||||
# Ugly. We have different code depending on if we're in the
|
||||
# game menu or not.
|
||||
if renpy.context()._menu:
|
||||
|
||||
if renpy.has_screen(screen):
|
||||
|
||||
renpy.transition(config.intra_transition)
|
||||
renpy.show_screen(screen, _transient=True)
|
||||
renpy.restart_interaction()
|
||||
|
||||
elif renpy.has_label(screen):
|
||||
renpy.transition(config.intra_transition)
|
||||
renpy.scene(layer='screens')
|
||||
|
||||
ui.layer("screens")
|
||||
ui.remove_above(None)
|
||||
ui.close()
|
||||
|
||||
renpy.jump(screen)
|
||||
|
||||
else:
|
||||
@@ -262,7 +313,7 @@ init -1140 python:
|
||||
return
|
||||
|
||||
if self.confirm:
|
||||
__yesno_prompt(layout.MAIN_MENU, MainMenu(False))
|
||||
layout.yesno_screen(layout.MAIN_MENU, MainMenu(False))
|
||||
else:
|
||||
renpy.full_restart()
|
||||
|
||||
@@ -283,12 +334,13 @@ init -1140 python:
|
||||
"""
|
||||
|
||||
def __init__(self, confirm=True):
|
||||
self.confirm = True
|
||||
self.confirm = confirm
|
||||
|
||||
def __call__(self):
|
||||
|
||||
if self.confirm:
|
||||
__yesno_prompt(layout.QUIT, Quit(False))
|
||||
renpy.loadsave.force_autosave()
|
||||
layout.yesno_screen(layout.QUIT, Quit(False))
|
||||
else:
|
||||
renpy.quit()
|
||||
|
||||
@@ -317,10 +369,27 @@ init -1140 python:
|
||||
|
||||
def get_sensitive(self):
|
||||
return config.allow_skipping and (not renpy.context()._main_menu)
|
||||
|
||||
class Help(Action):
|
||||
"""
|
||||
:doc: other_action
|
||||
|
||||
Displays help.
|
||||
|
||||
`help`
|
||||
If this is a string giving a label in the programe, then
|
||||
that label is called in a new context when the button is
|
||||
chosen. Otherwise, it should be a string giving a file
|
||||
that is opened in a web browser. If None, the value of
|
||||
config.help is used in the same wayt.
|
||||
"""
|
||||
|
||||
def __init__(self, help=None):
|
||||
self.help = help
|
||||
|
||||
def AutoForward(Action):
|
||||
return Preference("auto-forward")
|
||||
|
||||
def __call__(self):
|
||||
_help(self.help)
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Functions that set variables or fields.
|
||||
@@ -345,7 +414,7 @@ init -1140 python:
|
||||
|
||||
def get_selected(self):
|
||||
return getattr(self.object, self.field) == self.value
|
||||
|
||||
|
||||
|
||||
def SetVariable(variable, value):
|
||||
"""
|
||||
@@ -512,7 +581,7 @@ init -1140 python:
|
||||
def get_selected(self):
|
||||
return renpy.music.get_playing(self.channel) == self.file
|
||||
|
||||
def periodic(self):
|
||||
def periodic(self, st):
|
||||
if self.selected != self.get_selected():
|
||||
renpy.restart_interaction()
|
||||
|
||||
@@ -637,7 +706,7 @@ init -1140 python:
|
||||
if self.value == self.old_value:
|
||||
return
|
||||
|
||||
fraction = st - (self.start_time) / self.delay
|
||||
fraction = (st - self.start_time) / self.delay
|
||||
fraction = min(1.0, fraction)
|
||||
|
||||
value = self.old_value + fraction * (self.value - self.old_value)
|
||||
@@ -693,8 +762,8 @@ init -1140 python:
|
||||
def changed(self, value):
|
||||
|
||||
if self.max_is_zero:
|
||||
if value == 0:
|
||||
value = self.range
|
||||
if value == self.range:
|
||||
value = 0
|
||||
else:
|
||||
value = value + 1
|
||||
|
||||
@@ -761,7 +830,7 @@ init -1140 python:
|
||||
def get_adjustment(self):
|
||||
w = renpy.get_widget(None, self.viewport)
|
||||
if not isinstance(w, Viewport):
|
||||
raise Exception("The displayable with id %r is not declared, or not a viewport.")
|
||||
raise Exception("The displayable with id %r is not declared, or not a viewport." % self.viewport)
|
||||
|
||||
return w.xadjustment
|
||||
|
||||
@@ -783,7 +852,7 @@ init -1140 python:
|
||||
def get_adjustment(self):
|
||||
w = renpy.get_widget(None, self.viewport)
|
||||
if not isinstance(w, Viewport):
|
||||
raise Exception("The displayable with id %r is not declared, or not a viewport.")
|
||||
raise Exception("The displayable with id %r is not declared, or not a viewport." % self.viewport)
|
||||
|
||||
return w.yadjustment
|
||||
|
||||
@@ -914,9 +983,9 @@ init -1140 python:
|
||||
|
||||
if renpy.scan_saved_game(fn):
|
||||
if self.confirm:
|
||||
__yesno_prompt(layout.OVERWRITE_SAVE, FileSave(self.name, False, self.newest, self.page))
|
||||
layout.yesno_screen(layout.OVERWRITE_SAVE, FileSave(self.name, False, self.newest, self.page))
|
||||
return
|
||||
|
||||
|
||||
renpy.save(fn, extra_info=save_name)
|
||||
|
||||
if self.newest:
|
||||
@@ -959,7 +1028,7 @@ init -1140 python:
|
||||
|
||||
if not renpy.context()._main_menu:
|
||||
if self.confirm:
|
||||
__yesno_prompt(layout.LOADING, FileLoad(self.name, False, self.page))
|
||||
layout.yesno_screen(layout.LOADING, FileLoad(self.name, False, self.page))
|
||||
return
|
||||
|
||||
renpy.load(fn)
|
||||
@@ -993,7 +1062,7 @@ init -1140 python:
|
||||
fn = __filename(self.name, self.page)
|
||||
|
||||
if self.confirm:
|
||||
__yesno_prompt(layout.DELETE_SAVE, FileDelete(self.name, False, self.page))
|
||||
layout.yesno_screen(layout.DELETE_SAVE, FileDelete(self.name, False, self.page))
|
||||
return
|
||||
|
||||
renpy.unlink_save(fn)
|
||||
@@ -1014,9 +1083,9 @@ init -1140 python:
|
||||
"""
|
||||
|
||||
if renpy.current_screen().screen_name[0] == "load":
|
||||
return FileLoad(name, page)
|
||||
return FileLoad(name, page=page)
|
||||
else:
|
||||
return FileSave(name, page)
|
||||
return FileSave(name, page=page)
|
||||
|
||||
|
||||
class FilePage(Action):
|
||||
@@ -1053,11 +1122,14 @@ init -1140 python:
|
||||
"""
|
||||
:doc: file_action
|
||||
|
||||
Goes to the next file page. (It's always possible to get to the
|
||||
next file page.)
|
||||
Goes to the next file page.
|
||||
|
||||
`max`
|
||||
If set, this should be an integer that gives the number of
|
||||
the maximum file page we can go to.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, max=None):
|
||||
|
||||
page = persistent._file_page
|
||||
|
||||
@@ -1071,7 +1143,14 @@ init -1140 python:
|
||||
page = "1"
|
||||
|
||||
else:
|
||||
page = str(int(page) + 1)
|
||||
page = int(page) + 1
|
||||
|
||||
if max is not None:
|
||||
if page > max:
|
||||
page = None
|
||||
|
||||
if page is not None:
|
||||
page = str(page)
|
||||
|
||||
self.page = page
|
||||
|
||||
@@ -1082,6 +1161,9 @@ init -1140 python:
|
||||
persistent._file_page = self.page
|
||||
renpy.restart_interaction()
|
||||
|
||||
def get_sensitive(self):
|
||||
return self.page is not None
|
||||
|
||||
|
||||
class FilePagePrevious(Action):
|
||||
"""
|
||||
@@ -1334,7 +1416,7 @@ init -1140 python:
|
||||
|
||||
|
||||
# What we do on a quit, by default.
|
||||
config.quit_action = ShowMenu("_confirm_quit")
|
||||
config.quit_action = ui.gamemenus("_confirm_quit")
|
||||
|
||||
|
||||
# This is used to ensure a fixed click-to-continue indicator is shown on
|
||||
@@ -1342,3 +1424,25 @@ init -1140 python:
|
||||
screen _ctc:
|
||||
add ctc
|
||||
|
||||
# These are used by renpy.notify.
|
||||
|
||||
transform _notify_transform:
|
||||
# These control the position.
|
||||
xalign .02 yalign .015
|
||||
|
||||
# These control the actions on show and hide.
|
||||
on show:
|
||||
alpha 0
|
||||
linear .25 alpha 1.0
|
||||
on hide:
|
||||
linear .5 alpha 0.0
|
||||
|
||||
screen notify:
|
||||
zorder 100
|
||||
|
||||
text message at _notify_transform
|
||||
|
||||
# This controls how long it takes between when the screen is
|
||||
# first shown, and when it begins hiding.
|
||||
timer 3.25 action Hide('notify')
|
||||
|
||||
|
||||
@@ -137,19 +137,24 @@ python early hide:
|
||||
def predict_play_music(p):
|
||||
return [ ]
|
||||
|
||||
def lint_play_music(p):
|
||||
def lint_play_music(p, channel="music"):
|
||||
|
||||
file = _try_eval(p["file"], 'filename')
|
||||
if p["channel"] is not None:
|
||||
_try_eval(p["channel"], 'channel')
|
||||
|
||||
if p["channel"] is not None:
|
||||
channel = _try_eval(p["channel"], 'channel')
|
||||
|
||||
if not isinstance(file, list):
|
||||
file = [ file ]
|
||||
|
||||
for fn in file:
|
||||
if isinstance(fn, basestring) and not renpy.loadable(fn):
|
||||
renpy.error("%r is not loadable" % fn)
|
||||
|
||||
if isinstance(fn, basestring):
|
||||
try:
|
||||
if not renpy.music.playable(fn, channel):
|
||||
renpy.error("%r is not loadable" % fn)
|
||||
except:
|
||||
pass
|
||||
|
||||
renpy.statements.register('play music',
|
||||
parse=parse_play_music,
|
||||
execute=execute_play_music,
|
||||
@@ -254,11 +259,14 @@ python early hide:
|
||||
fadeout=fadeout,
|
||||
fadein=eval(p["fadein"]),
|
||||
channel=channel)
|
||||
|
||||
|
||||
def lint_play_sound(p, lint_play_music=lint_play_music):
|
||||
return lint_play_music(p, channel="sound")
|
||||
|
||||
renpy.statements.register('play sound',
|
||||
parse=parse_play_music,
|
||||
execute=execute_play_sound,
|
||||
lint=lint_play_music)
|
||||
lint=lint_play_sound)
|
||||
|
||||
def execute_queue_sound(p):
|
||||
if p["channel"] is not None:
|
||||
@@ -334,7 +342,7 @@ python early hide:
|
||||
if not renpy.music.channel_defined(channel):
|
||||
renpy.error("channel %r is not defined" % channel)
|
||||
|
||||
lint_play_music(p)
|
||||
lint_play_music(p, channel)
|
||||
|
||||
def lint_stop_generic(p):
|
||||
channel = eval(p["channel"])
|
||||
|
||||
@@ -22,10 +22,14 @@ init -1200 python hide:
|
||||
# Style Declarations #################################################
|
||||
|
||||
style.default = Style(None, help='root of style hierarchy')
|
||||
style.text = Style(style.default, help='style of text')
|
||||
|
||||
style.fixed = Style(style.default, help='fixed layouts')
|
||||
style.hbox = Style(style.default, help='horizontal boxes')
|
||||
style.vbox = Style(style.default, help='vertical boxes')
|
||||
|
||||
style.grid = Style(style.default, help='grid layouts')
|
||||
style.side = Style(style.default, help='side layouts')
|
||||
|
||||
style.window = Style(style.default, help='windows created with ui.window')
|
||||
|
||||
style.image_placement = Style(style.default, help='default placement of images on the screen')
|
||||
@@ -50,7 +54,8 @@ init -1200 python hide:
|
||||
style.menu_choice_chosen_button = Style(style.menu_choice_button, help='buttons containing chosen in-game menu choices')
|
||||
style.menu_window = Style(style.window, help='a window containing a menu')
|
||||
|
||||
style.input_text = Style(style.default, help='text of an input box')
|
||||
style.input = Style(style.default, help='style of an input control')
|
||||
style.input_text = Style(style.input, help='text of an input box')
|
||||
style.input_prompt = Style(style.default, help='prompt of an input box')
|
||||
style.input_window = Style(style.window, help='window of an input box')
|
||||
|
||||
@@ -235,7 +240,7 @@ init -1090 python:
|
||||
# Menus.
|
||||
style.menu_choice.idle_color = "#0ff"
|
||||
style.menu_choice.hover_color = "#ff0"
|
||||
style.input_text.color = "#ff0"
|
||||
style.input.color = "#ff0"
|
||||
|
||||
# Styles used by centered.
|
||||
style.centered_window.xalign = 0.5
|
||||
|
||||
@@ -71,9 +71,7 @@ init -1110 python hide:
|
||||
style.vscrollbar.bar_vertical = True
|
||||
style.vscrollbar.bar_invert = True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# This recolors the given image using one or two colors.
|
||||
@theme
|
||||
def OneOrTwoColor(image, color):
|
||||
@@ -82,246 +80,68 @@ init -1110 python hide:
|
||||
else:
|
||||
return im.Twocolor(image, color, color)
|
||||
|
||||
@theme
|
||||
def roundrect_frames(
|
||||
less_rounded,
|
||||
frame):
|
||||
def roundrect_based_theme(name, file_prefix, Box=None, frame_png=None):
|
||||
|
||||
theme.clear_frames()
|
||||
|
||||
style.frame.background = RoundRect(frame, less_rounded)
|
||||
if Box is None:
|
||||
def Box(color, ignored):
|
||||
return Frame(theme.OneOrTwoColor(file_prefix + "_box.png", color), 12, 12)
|
||||
|
||||
style.frame.xpadding = 6
|
||||
style.frame.ypadding = 6
|
||||
|
||||
if frame_png is not None:
|
||||
def FrameBox(color, ignored):
|
||||
return Frame(theme.OneOrTwoColor(file_prefix + frame_png, color), 12, 12)
|
||||
else:
|
||||
FrameBox = Box
|
||||
|
||||
@theme
|
||||
def roundrect_buttons(text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
widget_hover,
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text):
|
||||
|
||||
theme.clear_buttons()
|
||||
|
||||
style.button.background = RoundRect(widget, less_rounded)
|
||||
style.button.hover_background = RoundRect(widget_hover, less_rounded)
|
||||
style.button.insensitive_background = RoundRect(disabled, less_rounded)
|
||||
|
||||
style.button_text.size = text_size
|
||||
style.button_text.color = widget_text
|
||||
style.button_text.selected_color = widget_selected
|
||||
style.button_text.insensitive_color = disabled_text
|
||||
|
||||
if less_rounded:
|
||||
style.button.xpadding = 6
|
||||
else:
|
||||
style.button.xpadding = 12
|
||||
|
||||
style.button.ypadding = 1
|
||||
style.button.xmargin = 1
|
||||
style.button.ymargin = 1
|
||||
|
||||
style.button_text.xalign = 0.5
|
||||
style.button_text.yalign = 0.5
|
||||
style.button_text.text_align = 0.5
|
||||
|
||||
@theme
|
||||
def roundrect_large_buttons(
|
||||
text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
widget_hover,
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text):
|
||||
|
||||
theme.clear_large_buttons()
|
||||
|
||||
if less_rounded:
|
||||
style.large_button.xpadding = 6
|
||||
else:
|
||||
style.large_button.xpadding = 12
|
||||
|
||||
style.large_button.ypadding = 1
|
||||
style.large_button.xmargin = 1
|
||||
style.large_button.ymargin = 1
|
||||
|
||||
style.large_button.background = RoundRect(widget, less_rounded)
|
||||
style.large_button.hover_background = RoundRect(widget_hover, less_rounded)
|
||||
style.large_button.insensitive_background = RoundRect(disabled, less_rounded)
|
||||
|
||||
style.large_button_text.size = text_size
|
||||
style.large_button_text.color = widget_text
|
||||
style.large_button_text.selected_color = widget_selected
|
||||
style.large_button_text.insensitive_color = disabled_text
|
||||
|
||||
style.large_button_text.xalign = 0
|
||||
style.large_button_text.yalign = 0
|
||||
|
||||
@theme
|
||||
def roundrect_labels(
|
||||
text_size,
|
||||
label):
|
||||
|
||||
theme.clear_labels()
|
||||
|
||||
style.label_text.size = text_size
|
||||
style.label_text.color = label
|
||||
|
||||
@theme
|
||||
def roundrect_prompts(
|
||||
text_size,
|
||||
label):
|
||||
|
||||
theme.clear_prompts()
|
||||
|
||||
style.prompt_text.size = text_size
|
||||
style.prompt_text.color = label
|
||||
|
||||
style.prompt.xalign = 0.5
|
||||
style.prompt_text.text_align = 0.5
|
||||
style.prompt_text.layout = "subtitle"
|
||||
|
||||
@theme
|
||||
def roundrect_bars(
|
||||
widget,
|
||||
widget_hover):
|
||||
|
||||
theme.clear_bars()
|
||||
|
||||
def img(name, color, x, y):
|
||||
rv = theme.OneOrTwoColor("_roundrect/" + name + ".png", color)
|
||||
if x is not None:
|
||||
rv = Frame(rv, x, y)
|
||||
return rv
|
||||
|
||||
# Bars.
|
||||
style.bar.ymaximum = 24
|
||||
style.bar.left_gutter = 6
|
||||
style.bar.right_gutter = 6
|
||||
style.bar.thumb_offset = 6
|
||||
|
||||
style.bar.left_bar = img("rrslider_full", widget, 12, 0)
|
||||
style.bar.right_bar = img("rrslider_empty", widget, 12, 0)
|
||||
style.bar.thumb = img("rrslider_thumb", widget, None, None)
|
||||
style.bar.hover_left_bar = img("rrslider_full", widget_hover, 12, 0)
|
||||
style.bar.hover_right_bar = img("rrslider_empty", widget_hover, 12, 0)
|
||||
style.bar.hover_thumb = img("rrslider_thumb", widget_hover, None, None)
|
||||
|
||||
style.vbar.xmaximum = 24
|
||||
style.vbar.top_gutter = 6
|
||||
style.vbar.bottom_gutter = 6
|
||||
style.vbar.thumb_offset = 6
|
||||
|
||||
style.vbar.bottom_bar = img("rrvslider_full", widget, 0, 12)
|
||||
style.vbar.top_bar = img("rrvslider_empty", widget, 0, 12)
|
||||
style.vbar.thumb = img("rrvslider_thumb", widget, None, None)
|
||||
style.vbar.hover_bottom_bar = img("rrvslider_full", widget_hover, 0, 12)
|
||||
style.vbar.hover_top_bar = img("rrvslider_empty", widget_hover, 0, 12)
|
||||
style.vbar.hover_thumb = img("rrvslider_thumb", widget_hover, None, None)
|
||||
|
||||
# Sliders.
|
||||
style.slider.ymaximum = 24
|
||||
style.slider.left_gutter = 6
|
||||
style.slider.right_gutter = 6
|
||||
style.slider.thumb_offset = 6
|
||||
|
||||
style.slider.left_bar = img("rrslider_full", widget, 12, 0)
|
||||
style.slider.right_bar = img("rrslider_empty", widget, 12, 0)
|
||||
style.slider.thumb = img("rrslider_thumb", widget, None, None)
|
||||
style.slider.hover_left_bar = img("rrslider_full", widget_hover, 12, 0)
|
||||
style.slider.hover_right_bar = img("rrslider_empty", widget_hover, 12, 0)
|
||||
style.slider.hover_thumb = img("rrslider_thumb", widget_hover, None, None)
|
||||
|
||||
style.vslider.xmaximum = 24
|
||||
style.vslider.top_gutter = 6
|
||||
style.vslider.bottom_gutter = 6
|
||||
style.vslider.thumb_offset = 6
|
||||
|
||||
style.vslider.bottom_bar = img("rrvslider_full", widget, 0, 12)
|
||||
style.vslider.top_bar = img("rrvslider_empty", widget, 0, 12)
|
||||
style.vslider.thumb = img("rrvslider_thumb", widget, None, None)
|
||||
style.vslider.hover_bottom_bar = img("rrvslider_full", widget_hover, 0, 12)
|
||||
style.vslider.hover_top_bar = img("rrvslider_empty", widget_hover, 0, 12)
|
||||
style.vslider.hover_thumb = img("rrvslider_thumb", widget_hover, None, None)
|
||||
|
||||
|
||||
# Scrollbars.
|
||||
style.scrollbar.left_gutter = 6
|
||||
style.scrollbar.right_gutter = 6
|
||||
style.scrollbar.thumb_offset = 6
|
||||
style.scrollbar.ymaximum = 12
|
||||
|
||||
style.scrollbar.left_bar = img("rrscrollbar", widget, 12, 0)
|
||||
style.scrollbar.right_bar = img("rrscrollbar", widget, 12, 0)
|
||||
style.scrollbar.thumb = img("rrscrollbar_thumb", widget, None, None)
|
||||
style.scrollbar.hover_left_bar = img("rrscrollbar", widget_hover, 12, 0)
|
||||
style.scrollbar.hover_right_bar = img("rrscrollbar", widget_hover, 12, 0)
|
||||
style.scrollbar.hover_thumb = img("rrscrollbar_thumb", widget_hover, None, None)
|
||||
|
||||
style.vscrollbar.top_gutter = 6
|
||||
style.vscrollbar.bottom_gutter = 6
|
||||
style.vscrollbar.thumb_offset = 6
|
||||
style.vscrollbar.xmaximum = 12
|
||||
|
||||
style.vscrollbar.left_bar = img("rrvscrollbar", widget, 0, 12)
|
||||
style.vscrollbar.right_bar = img("rrvscrollbar", widget, 0, 12)
|
||||
style.vscrollbar.thumb = img("rrvscrollbar_thumb", widget, None, None)
|
||||
style.vscrollbar.hover_left_bar = img("rrvscrollbar", widget_hover, 0, 12)
|
||||
style.vscrollbar.hover_right_bar = img("rrvscrollbar", widget_hover, 0, 12)
|
||||
style.vscrollbar.hover_thumb = img("rrvscrollbar_thumb", widget_hover, None, None)
|
||||
|
||||
@theme
|
||||
def roundrect(
|
||||
widget = (0, 60, 120, 255),
|
||||
widget_hover = (0, 80, 160, 255),
|
||||
widget_text = (200, 225, 255, 255),
|
||||
widget_selected = (255, 255, 200, 255),
|
||||
disabled = (64, 64, 64, 255),
|
||||
disabled_text = (200, 200, 200, 255),
|
||||
label = (255, 255, 255, 255),
|
||||
frame = (100, 150, 200, 255),
|
||||
|
||||
text_size=None,
|
||||
small_text_size=None,
|
||||
less_rounded = False,
|
||||
|
||||
# Compat for the old roundrect theme.
|
||||
window = None,
|
||||
button_menu = None,
|
||||
rounded_window = True,
|
||||
outline_bars = False,
|
||||
mm_root = None,
|
||||
gm_root = None):
|
||||
|
||||
if button_menu is None:
|
||||
if (config.script_version is not None) and (config.script_version < (6, 9, 0)):
|
||||
button_menu = True
|
||||
else:
|
||||
button_menu = False
|
||||
|
||||
layout.defaults()
|
||||
|
||||
if config.screen_width <= 640:
|
||||
text_size = text_size or 18
|
||||
small_text_size = small_text_size or 12
|
||||
less_rounded = True
|
||||
|
||||
else:
|
||||
text_size = text_size or 22
|
||||
small_text_size = small_text_size or 16
|
||||
radius = 12
|
||||
|
||||
theme.roundrect_frames(
|
||||
def frames(
|
||||
less_rounded,
|
||||
frame)
|
||||
frame):
|
||||
|
||||
theme.roundrect_buttons(
|
||||
theme.clear_frames()
|
||||
|
||||
style.frame.background = Box(frame, less_rounded)
|
||||
|
||||
style.frame.xpadding = 6
|
||||
style.frame.ypadding = 6
|
||||
|
||||
setattr(theme, name + "_frames", frames)
|
||||
|
||||
|
||||
def buttons(text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
widget_hover,
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text):
|
||||
|
||||
theme.clear_buttons()
|
||||
|
||||
style.button.background = Box(widget, less_rounded)
|
||||
style.button.hover_background = Box(widget_hover, less_rounded)
|
||||
style.button.insensitive_background = Box(disabled, less_rounded)
|
||||
|
||||
style.button_text.size = text_size
|
||||
style.button_text.color = widget_text
|
||||
style.button_text.selected_color = widget_selected
|
||||
style.button_text.insensitive_color = disabled_text
|
||||
|
||||
if less_rounded:
|
||||
style.button.xpadding = 6
|
||||
else:
|
||||
style.button.xpadding = 12
|
||||
|
||||
style.button.ypadding = 1
|
||||
style.button.xmargin = 1
|
||||
style.button.ymargin = 1
|
||||
|
||||
style.button_text.xalign = 0.5
|
||||
style.button_text.yalign = 0.5
|
||||
style.button_text.text_align = 0.5
|
||||
|
||||
setattr(theme, name + "_buttons", buttons)
|
||||
|
||||
def large_buttons(
|
||||
text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
@@ -329,55 +149,260 @@ init -1110 python hide:
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text)
|
||||
disabled_text):
|
||||
|
||||
theme.roundrect_large_buttons(
|
||||
small_text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
widget_hover,
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text)
|
||||
theme.clear_large_buttons()
|
||||
|
||||
theme.roundrect_labels(
|
||||
text_size,
|
||||
label)
|
||||
|
||||
theme.roundrect_prompts(
|
||||
text_size,
|
||||
label)
|
||||
|
||||
theme.roundrect_bars(
|
||||
widget,
|
||||
widget_hover)
|
||||
|
||||
if mm_root is not None:
|
||||
style.mm_root.background = mm_root
|
||||
|
||||
if gm_root is not None:
|
||||
style.gm_root.background = gm_root
|
||||
|
||||
if window is not None:
|
||||
|
||||
if rounded_window:
|
||||
style.window.background = RoundRect(window, less_rounded)
|
||||
style.window.xpadding = 6
|
||||
style.window.xmargin = 6
|
||||
style.window.ypadding = 6
|
||||
style.window.ymargin = 6
|
||||
if less_rounded:
|
||||
style.large_button.xpadding = 6
|
||||
else:
|
||||
style.window.background = Solid(window)
|
||||
style.window.xpadding = 6
|
||||
style.window.xmargin = 0
|
||||
style.window.ypadding = 6
|
||||
style.window.ymargin = 0
|
||||
style.large_button.xpadding = 12
|
||||
|
||||
style.large_button.ypadding = 1
|
||||
style.large_button.xmargin = 1
|
||||
style.large_button.ymargin = 1
|
||||
|
||||
style.large_button.background = Box(widget, less_rounded)
|
||||
style.large_button.hover_background = Box(widget_hover, less_rounded)
|
||||
style.large_button.insensitive_background = Box(disabled, less_rounded)
|
||||
|
||||
style.large_button_text.size = text_size
|
||||
style.large_button_text.color = widget_text
|
||||
style.large_button_text.selected_color = widget_selected
|
||||
style.large_button_text.insensitive_color = disabled_text
|
||||
|
||||
style.large_button_text.xalign = 0
|
||||
style.large_button_text.yalign = 0
|
||||
|
||||
setattr(theme, name + "_large_buttons", large_buttons)
|
||||
|
||||
def labels(
|
||||
text_size,
|
||||
label):
|
||||
|
||||
theme.clear_labels()
|
||||
|
||||
style.label_text.size = text_size
|
||||
style.label_text.color = label
|
||||
|
||||
setattr(theme, name + "_labels", labels)
|
||||
|
||||
def prompts(
|
||||
text_size,
|
||||
label):
|
||||
|
||||
theme.clear_prompts()
|
||||
|
||||
style.prompt_text.size = text_size
|
||||
style.prompt_text.color = label
|
||||
|
||||
style.prompt.xalign = 0.5
|
||||
style.prompt_text.text_align = 0.5
|
||||
style.prompt_text.layout = "subtitle"
|
||||
|
||||
setattr(theme, name + "_prompts", prompts)
|
||||
|
||||
|
||||
def bars(
|
||||
widget,
|
||||
widget_hover):
|
||||
|
||||
theme.clear_bars()
|
||||
|
||||
def img(name, color, x, y):
|
||||
rv = theme.OneOrTwoColor(file_prefix + name + ".png", color)
|
||||
if x is not None:
|
||||
rv = Frame(rv, x, y, tile=True)
|
||||
return rv
|
||||
|
||||
# Bars.
|
||||
style.bar.ymaximum = 24
|
||||
style.bar.left_gutter = 6
|
||||
style.bar.right_gutter = 6
|
||||
style.bar.thumb_offset = 6
|
||||
|
||||
style.bar.left_bar = img("slider_full", widget, 12, 0)
|
||||
style.bar.right_bar = img("slider_empty", widget, 12, 0)
|
||||
style.bar.thumb = img("slider_thumb", widget, None, None)
|
||||
style.bar.hover_left_bar = img("slider_full", widget_hover, 12, 0)
|
||||
style.bar.hover_right_bar = img("slider_empty", widget_hover, 12, 0)
|
||||
style.bar.hover_thumb = img("slider_thumb", widget_hover, None, None)
|
||||
|
||||
style.vbar.xmaximum = 24
|
||||
style.vbar.top_gutter = 6
|
||||
style.vbar.bottom_gutter = 6
|
||||
style.vbar.thumb_offset = 6
|
||||
|
||||
style.vbar.bottom_bar = img("vslider_full", widget, 0, 12)
|
||||
style.vbar.top_bar = img("vslider_empty", widget, 0, 12)
|
||||
style.vbar.thumb = img("vslider_thumb", widget, None, None)
|
||||
style.vbar.hover_bottom_bar = img("vslider_full", widget_hover, 0, 12)
|
||||
style.vbar.hover_top_bar = img("vslider_empty", widget_hover, 0, 12)
|
||||
style.vbar.hover_thumb = img("vslider_thumb", widget_hover, None, None)
|
||||
|
||||
# Sliders.
|
||||
style.slider.ymaximum = 24
|
||||
style.slider.left_gutter = 6
|
||||
style.slider.right_gutter = 6
|
||||
style.slider.thumb_offset = 6
|
||||
|
||||
style.slider.left_bar = img("slider_full", widget, 12, 0)
|
||||
style.slider.right_bar = img("slider_empty", widget, 12, 0)
|
||||
style.slider.thumb = img("slider_thumb", widget, None, None)
|
||||
style.slider.hover_left_bar = img("slider_full", widget_hover, 12, 0)
|
||||
style.slider.hover_right_bar = img("slider_empty", widget_hover, 12, 0)
|
||||
style.slider.hover_thumb = img("slider_thumb", widget_hover, None, None)
|
||||
|
||||
style.vslider.xmaximum = 24
|
||||
style.vslider.top_gutter = 6
|
||||
style.vslider.bottom_gutter = 6
|
||||
style.vslider.thumb_offset = 6
|
||||
|
||||
style.vslider.bottom_bar = img("vslider_full", widget, 0, 12)
|
||||
style.vslider.top_bar = img("vslider_empty", widget, 0, 12)
|
||||
style.vslider.thumb = img("vslider_thumb", widget, None, None)
|
||||
style.vslider.hover_bottom_bar = img("vslider_full", widget_hover, 0, 12)
|
||||
style.vslider.hover_top_bar = img("vslider_empty", widget_hover, 0, 12)
|
||||
style.vslider.hover_thumb = img("vslider_thumb", widget_hover, None, None)
|
||||
|
||||
|
||||
if button_menu:
|
||||
layout.button_menu()
|
||||
# Scrollbars.
|
||||
style.scrollbar.left_gutter = 6
|
||||
style.scrollbar.right_gutter = 6
|
||||
style.scrollbar.thumb_offset = 6
|
||||
style.scrollbar.ymaximum = 12
|
||||
|
||||
style.scrollbar.left_bar = img("scrollbar", widget, 12, 0)
|
||||
style.scrollbar.right_bar = img("scrollbar", widget, 12, 0)
|
||||
style.scrollbar.thumb = img("scrollbar_thumb", widget, None, None)
|
||||
style.scrollbar.hover_left_bar = img("scrollbar", widget_hover, 12, 0)
|
||||
style.scrollbar.hover_right_bar = img("scrollbar", widget_hover, 12, 0)
|
||||
style.scrollbar.hover_thumb = img("scrollbar_thumb", widget_hover, None, None)
|
||||
|
||||
style.vscrollbar.top_gutter = 6
|
||||
style.vscrollbar.bottom_gutter = 6
|
||||
style.vscrollbar.thumb_offset = 6
|
||||
style.vscrollbar.xmaximum = 12
|
||||
|
||||
style.vscrollbar.left_bar = img("vscrollbar", widget, 0, 12)
|
||||
style.vscrollbar.right_bar = img("vscrollbar", widget, 0, 12)
|
||||
style.vscrollbar.thumb = img("vscrollbar_thumb", widget, None, None)
|
||||
style.vscrollbar.hover_left_bar = img("vscrollbar", widget_hover, 0, 12)
|
||||
style.vscrollbar.hover_right_bar = img("vscrollbar", widget_hover, 0, 12)
|
||||
style.vscrollbar.hover_thumb = img("vscrollbar_thumb", widget_hover, None, None)
|
||||
|
||||
setattr(theme, name + "_bars", bars)
|
||||
|
||||
def main(
|
||||
widget = (0, 60, 120, 255),
|
||||
widget_hover = (0, 80, 160, 255),
|
||||
widget_text = (200, 225, 255, 255),
|
||||
widget_selected = (255, 255, 200, 255),
|
||||
disabled = (64, 64, 64, 255),
|
||||
disabled_text = (200, 200, 200, 255),
|
||||
label = (255, 255, 255, 255),
|
||||
frame = (100, 150, 200, 255),
|
||||
|
||||
text_size=None,
|
||||
small_text_size=None,
|
||||
less_rounded = False,
|
||||
|
||||
# Compat for the old roundrect theme.
|
||||
window = None,
|
||||
button_menu = None,
|
||||
rounded_window = True,
|
||||
outline_bars = False,
|
||||
mm_root = None,
|
||||
gm_root = None):
|
||||
|
||||
if button_menu is None:
|
||||
if (config.script_version is not None) and (config.script_version < (6, 9, 0)):
|
||||
button_menu = True
|
||||
else:
|
||||
button_menu = False
|
||||
|
||||
layout.defaults()
|
||||
|
||||
if config.screen_width <= 640:
|
||||
text_size = text_size or 18
|
||||
small_text_size = small_text_size or 12
|
||||
less_rounded = True
|
||||
|
||||
else:
|
||||
text_size = text_size or 22
|
||||
small_text_size = small_text_size or 16
|
||||
radius = 12
|
||||
|
||||
frames(
|
||||
less_rounded,
|
||||
frame)
|
||||
|
||||
buttons(
|
||||
text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
widget_hover,
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text)
|
||||
|
||||
large_buttons(
|
||||
small_text_size,
|
||||
less_rounded,
|
||||
widget,
|
||||
widget_hover,
|
||||
widget_text,
|
||||
widget_selected,
|
||||
disabled,
|
||||
disabled_text)
|
||||
|
||||
labels(
|
||||
text_size,
|
||||
label)
|
||||
|
||||
prompts(
|
||||
text_size,
|
||||
label)
|
||||
|
||||
bars(
|
||||
widget,
|
||||
widget_hover)
|
||||
|
||||
if mm_root is not None:
|
||||
style.mm_root.background = mm_root
|
||||
|
||||
if gm_root is not None:
|
||||
style.gm_root.background = gm_root
|
||||
|
||||
if window is not None:
|
||||
|
||||
if rounded_window:
|
||||
style.window.background = RoundRect(window, less_rounded)
|
||||
style.window.xpadding = 6
|
||||
style.window.xmargin = 6
|
||||
style.window.ypadding = 6
|
||||
style.window.ymargin = 6
|
||||
else:
|
||||
style.window.background = Solid(window)
|
||||
style.window.xpadding = 6
|
||||
style.window.xmargin = 0
|
||||
style.window.ypadding = 6
|
||||
style.window.ymargin = 0
|
||||
|
||||
|
||||
if button_menu:
|
||||
layout.button_menu()
|
||||
|
||||
setattr(theme, name, main)
|
||||
|
||||
roundrect_based_theme("roundrect", "_roundrect/rr", RoundRect)
|
||||
roundrect_based_theme("bordered", "_theme_bordered/br")
|
||||
roundrect_based_theme("diamond", "_theme_diamond/d")
|
||||
roundrect_based_theme("tv", "_theme_tv/t")
|
||||
roundrect_based_theme("glow", "_theme_glow/g", None, "_outline.png")
|
||||
|
||||
|
||||
@theme
|
||||
def ancient():
|
||||
|
||||
|
||||
@@ -1,29 +1,34 @@
|
||||
# This file contains code that helps support the development of Ren'Py
|
||||
# games.
|
||||
|
||||
screen _developer:
|
||||
window style "gm_root"
|
||||
|
||||
frame:
|
||||
style_group "_developer"
|
||||
|
||||
align (.025, .05)
|
||||
|
||||
has vbox:
|
||||
first_spacing 10
|
||||
|
||||
label "Developer Menu"
|
||||
|
||||
textbutton _(u"Return") action Return()
|
||||
textbutton _(u"Reload Game (Shift + R)") action ui.callsinnewcontext("_save_reload_game")
|
||||
textbutton _(u"Variable Viewer") action Jump("_debugger_screen")
|
||||
textbutton _(u"Theme Test") action Jump("_theme_test")
|
||||
textbutton _(u"Style Hierarchy") action Jump("_style_hierarchy")
|
||||
textbutton _(u"Image Location Picker") action Jump("_image_location_picker")
|
||||
textbutton _(u"Filename List") action Jump("_filename_list")
|
||||
|
||||
init python hide:
|
||||
style._developer_button = Style(style.button)
|
||||
style._developer_button.size_group = "_developer"
|
||||
|
||||
label _developer_screen:
|
||||
|
||||
python hide:
|
||||
|
||||
ui.window(style=style.gm_root)
|
||||
ui.null()
|
||||
|
||||
ui.frame(xpos=10, ypos=10, style=style.menu_frame)
|
||||
ui.vbox(box_first_spacing=10)
|
||||
layout.label(u"Developer Menu", None)
|
||||
|
||||
sg = "developer_menu"
|
||||
|
||||
layout.button(u"Return", None, clicked=ui.returns(True), size_group=sg)
|
||||
layout.button(u"Reload Game (Shift+R)", None, clicked=ui.callsinnewcontext("_save_reload_game"), size_group=sg)
|
||||
layout.button(u"Variable Viewer", None, clicked=ui.jumps("_debugger_screen"), size_group=sg)
|
||||
layout.button(u"Theme Test", None, clicked=ui.jumps("_theme_test"), size_group=sg)
|
||||
layout.button(u"Style Hierarchy", None, clicked=ui.jumps("_style_hierarchy"), size_group=sg)
|
||||
# layout.button(u"FPS Meter", None, clicked=ui.jumps("_fps_meter"), size_group=sg)
|
||||
layout.button(u"Image Location Picker", None, clicked=ui.jumps("_image_location_picker"), size_group=sg)
|
||||
|
||||
ui.close()
|
||||
ui.interact()
|
||||
call screen _developer
|
||||
|
||||
return
|
||||
|
||||
@@ -92,7 +97,7 @@ label _theme_test:
|
||||
return ""
|
||||
|
||||
toggle_var = True
|
||||
adj = ui.adjustment(100, 25, page=25)
|
||||
adj = ui.adjustment(100, 25, page=25, adjustable=True)
|
||||
|
||||
while True:
|
||||
|
||||
@@ -369,8 +374,8 @@ init python:
|
||||
sr = renpy.render(Solid("#0ff4"), w, h, st, at)
|
||||
rv.blit(sr, (minx, miny))
|
||||
|
||||
text.append("Imagemap rectangle: %r" % ((minx, miny, maxx, maxy),))
|
||||
text.append("Cropping rectangle: %r" % ((minx, miny, w, h),))
|
||||
# text.append("Imagemap rectangle: %r" % ((minx, miny, maxx, maxy),))
|
||||
text.append("Rectangle: %r" % ((minx, miny, w, h),))
|
||||
|
||||
if self.mouse:
|
||||
mx, my = self.mouse
|
||||
@@ -466,6 +471,30 @@ label _image_location_picker:
|
||||
|
||||
renpy.jump("_image_location_picker")
|
||||
|
||||
label _filename_list:
|
||||
|
||||
python hide:
|
||||
import os
|
||||
f = file("files.txt", "w")
|
||||
|
||||
for dirname, dirs, files in os.walk(config.gamedir):
|
||||
|
||||
dirs.sort()
|
||||
files.sort()
|
||||
|
||||
for fn in files:
|
||||
fn = os.path.join(dirname, fn)
|
||||
fn = fn[len(config.gamedir) + 1:]
|
||||
print >>f, fn
|
||||
print fn
|
||||
|
||||
f.close()
|
||||
|
||||
renpy.launch_editor(["files.txt"], transient=1)
|
||||
|
||||
|
||||
jump _developer_screen
|
||||
|
||||
|
||||
init python:
|
||||
config.underlay.append(im.Tile("_transparent_tile.png"))
|
||||
|
||||
@@ -133,7 +133,7 @@ init python:
|
||||
a channel.
|
||||
"""
|
||||
|
||||
def __init__(self, name, mixer, enable='True', sound='None', channel=0):
|
||||
def __init__(self, name, mixer, enable='True', sound='None', channel="sound"):
|
||||
"""
|
||||
@param name: The name of this preference, as shown to the user.
|
||||
|
||||
@@ -360,15 +360,18 @@ init python hide:
|
||||
_VolumePreference(u"Music Volume",
|
||||
'music',
|
||||
'config.has_music')
|
||||
|
||||
_VolumePreference(u"Sound Volume",
|
||||
'sfx',
|
||||
'config.has_sound',
|
||||
'config.sample_sound')
|
||||
'config.sample_sound',
|
||||
'sound')
|
||||
|
||||
_VolumePreference(u'Voice Volume',
|
||||
'voice',
|
||||
'config.has_voice',
|
||||
'config.sample_voice',
|
||||
2)
|
||||
'voice')
|
||||
|
||||
_JumpPreference(u'Joystick...',
|
||||
'joystick_preferences_screen',
|
||||
|
||||
@@ -77,12 +77,12 @@ init python:
|
||||
ime.button("Joystick", ui.jumps("joystick_preferences_screen"), False)
|
||||
|
||||
def play_sound():
|
||||
renpy.sound.play(config.sample_sound)
|
||||
renpy.music.play(config.sample_sound, channel="sound")
|
||||
|
||||
ime.button("Sound Test", play_sound, False)
|
||||
|
||||
def play_voice():
|
||||
renpy.sound.play(config.sample_sound, channel=2)
|
||||
renpy.music.play(config.sample_sound, channel="voice")
|
||||
|
||||
ime.button("Voice Test", play_voice, False)
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 489 B |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 313 B |
|
After Width: | Height: | Size: 287 B |
|
After Width: | Height: | Size: 236 B |
|
After Width: | Height: | Size: 265 B |
|
After Width: | Height: | Size: 324 B |
|
After Width: | Height: | Size: 356 B |
|
After Width: | Height: | Size: 289 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 255 B |
|
After Width: | Height: | Size: 359 B |
|
After Width: | Height: | Size: 405 B |
|
After Width: | Height: | Size: 313 B |
|
After Width: | Height: | Size: 763 B |
|
After Width: | Height: | Size: 862 B |
|
After Width: | Height: | Size: 524 B |
|
After Width: | Height: | Size: 450 B |
|
After Width: | Height: | Size: 781 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 611 B |
|
After Width: | Height: | Size: 460 B |
|
After Width: | Height: | Size: 816 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 529 B |
|
After Width: | Height: | Size: 315 B |
|
After Width: | Height: | Size: 246 B |
|
After Width: | Height: | Size: 184 B |
|
After Width: | Height: | Size: 364 B |
|
After Width: | Height: | Size: 384 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 408 B |
|
After Width: | Height: | Size: 412 B |
|
After Width: | Height: | Size: 212 B |
@@ -1 +0,0 @@
|
||||
dist/console.exe
|
||||
@@ -9,6 +9,9 @@ import time
|
||||
import zlib
|
||||
import compileall
|
||||
import shutil
|
||||
import subprocess
|
||||
import makeupdate
|
||||
import time
|
||||
|
||||
zlib.Z_DEFAULT_COMPRESSION = 9
|
||||
|
||||
@@ -20,7 +23,7 @@ def data(fn):
|
||||
if fn.startswith("renpy.app"):
|
||||
return rv
|
||||
|
||||
if fn.endswith(".rpy") or fn.endswith(".py") or fn.endswith(".txt"):
|
||||
if fn.endswith(".rpy") or fn.endswith(".rpym") or fn.endswith(".py") or fn.endswith(".txt"):
|
||||
rv = rv.replace("\n", "\r\n")
|
||||
rv = rv.replace("\r\r\n", "\r\n")
|
||||
|
||||
@@ -87,7 +90,11 @@ def tree(root):
|
||||
|
||||
if ".svn" in dirs:
|
||||
dirs.remove(".svn")
|
||||
|
||||
|
||||
if ".doctrees" in dirs:
|
||||
dirs.remove(".doctrees")
|
||||
|
||||
|
||||
for f in filenames:
|
||||
if f[-1] == '~' or f[0] == '.':
|
||||
continue
|
||||
@@ -113,41 +120,44 @@ def main():
|
||||
|
||||
prefix = sys.argv[1]
|
||||
|
||||
# Update the update-version.txt file.
|
||||
p = subprocess.Popen(["bzr", "revno"], stdout=subprocess.PIPE)
|
||||
revno = p.stdout.read().strip() + "-" + str(time.time())
|
||||
p.wait()
|
||||
|
||||
f = file("lib/update-version.txt", "w")
|
||||
f.write(revno + " base\n")
|
||||
f.close()
|
||||
|
||||
# Compile all the python files.
|
||||
compileall.compile_dir("renpy/", ddir=prefix + "/renpy/", force=1)
|
||||
|
||||
os.environ['RENPY_PATH_ELIDE'] = '/home/tom/ab/renpy:' + prefix
|
||||
|
||||
# Chmod the mac app.
|
||||
os.chmod("./renpy.app/Contents/MacOS/Ren'Py Launcher", 0755)
|
||||
|
||||
# Chmod down renpy.py, for now.
|
||||
os.chmod("renpy.py", 0644)
|
||||
|
||||
# Compile the various games
|
||||
for i in [ 'tutorial/game', 'launcher', 'template/game', 'the_question/game' ]:
|
||||
os.system("./renpy.sh --compile --game " + i)
|
||||
|
||||
|
||||
files = [ ]
|
||||
more_files = [ ]
|
||||
|
||||
files.append("CHANGELOG.txt")
|
||||
files.append("LICENSE.txt")
|
||||
files.extend(tree("common"))
|
||||
more_files.append("console.exe")
|
||||
files.extend(tree("launcher"))
|
||||
files.extend(tree("tutorial"))
|
||||
# files.extend(tree("dse"))
|
||||
files.extend(tree("the_question"))
|
||||
|
||||
# editor = tree("editor")
|
||||
# editor.remove("editor/scite.exe")
|
||||
# files.append("editor/scite.exe")
|
||||
# more_files.extend(editor)
|
||||
|
||||
more_files.extend(tree("jedit"))
|
||||
|
||||
# files.extend(tree("extras"))
|
||||
more_files.extend(tree("lib"))
|
||||
more_files.extend(tree("lib/linux-x86"))
|
||||
|
||||
|
||||
module_files = [
|
||||
"lib/pysdlsound/linmixer.py",
|
||||
"lib/pysdlsound/__init__.py",
|
||||
@@ -185,32 +195,20 @@ def main():
|
||||
for i in module_files:
|
||||
files.append('module/' + i)
|
||||
|
||||
files.extend(tree('renpy'))
|
||||
files.append('renpy.py')
|
||||
|
||||
more_files.append('python26.dll')
|
||||
more_files.append('msvcr90.dll')
|
||||
more_files.append('Microsoft.VC90.CRT.manifest')
|
||||
files.extend(tree('renpy'))
|
||||
more_files.extend(tree('renpy.app'))
|
||||
more_files.append('renpy.code')
|
||||
more_files.append('renpy.exe')
|
||||
files.append('renpy.py')
|
||||
|
||||
more_files.append('renpy.exe')
|
||||
more_files.append("console.exe")
|
||||
more_files.append('renpy.sh')
|
||||
|
||||
files.extend(tree('template'))
|
||||
# files.extend(tree('tools'))
|
||||
|
||||
files.extend(tree('doc'))
|
||||
|
||||
# files.append('doc/index.html')
|
||||
# files.append('doc/common.css')
|
||||
# files.append('doc/docs.css')
|
||||
# files.append('doc/monobook.css')
|
||||
# files.append('doc/monobook2.css')
|
||||
# files.append('doc/shared.css')
|
||||
# files.extend(tree('doc/reference'))
|
||||
# files.extend(tree('doc/tutorials'))
|
||||
# files.extend(tree('doc/images'))
|
||||
|
||||
|
||||
files.sort()
|
||||
more_files.sort()
|
||||
|
||||
@@ -222,6 +220,7 @@ def main():
|
||||
print "----"
|
||||
tarup("dists/" + prefix + "-source.tar.bz2", prefix, files)
|
||||
print "----"
|
||||
|
||||
# Make the 7zip.
|
||||
os.chdir("dists")
|
||||
os.system("unzip " + prefix + "-sdk.zip")
|
||||
@@ -233,13 +232,23 @@ def main():
|
||||
|
||||
os.system("7z a " + prefix + "-sdk.7z " + prefix)
|
||||
os.system("cat ../7z.sfx " + prefix + "-sdk.7z > " + prefix + "-sdk.7z.exe""")
|
||||
shutil.rmtree(prefix)
|
||||
os.unlink(prefix + "-sdk.7z")
|
||||
|
||||
|
||||
os.chdir("..")
|
||||
|
||||
if os.path.exists("updates/prerelease"):
|
||||
shutil.rmtree("updates/prerelease")
|
||||
|
||||
os.rename("dists/" + prefix, "updates/prerelease")
|
||||
os.unlink("updates/prerelease/lib/update-version.txt")
|
||||
|
||||
makeupdate.make_update("updates/prerelease", revno)
|
||||
|
||||
os.chmod("renpy.py", 0755)
|
||||
|
||||
print
|
||||
print "Did you remember to rebuild the exe after the last change?"
|
||||
print "Did you run me with renpython -OO?"
|
||||
print "Was ming using the right crt?"
|
||||
print "Did you update renpy.py and launcher/script_version.rpy?"
|
||||
print "Did you run with a RENPY_SCALE_FACTOR?"
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ init python:
|
||||
return rv
|
||||
|
||||
|
||||
def switch_theme(name):
|
||||
def switch_theme(theme_function, name):
|
||||
"""
|
||||
Switches the theme of the current project to the named theme.
|
||||
"""
|
||||
@@ -130,7 +130,7 @@ init python:
|
||||
m = re.match(r' theme.(\w+)\(', l)
|
||||
if m:
|
||||
if m.group(1) in theme_functions:
|
||||
l = theme_templates[td["theme"]] % td
|
||||
l = theme_templates[theme_function] % td
|
||||
changed = True
|
||||
|
||||
out.write(l + "\n")
|
||||
@@ -160,29 +160,26 @@ init python:
|
||||
|
||||
##########################################################################
|
||||
# Code that handles display.
|
||||
|
||||
|
||||
current_theme_function = None
|
||||
current_theme = None
|
||||
|
||||
def show_theme(name, target):
|
||||
def show_theme(function, name, target):
|
||||
"""
|
||||
Changes from the current theme to the roundrect theme named
|
||||
`name`.
|
||||
Changes from the current theme to the theme named `name`.
|
||||
"""
|
||||
|
||||
if current_theme == name:
|
||||
if current_theme_function == function and current_theme == name:
|
||||
return
|
||||
|
||||
store.current_theme_function = function
|
||||
store.current_theme = name
|
||||
|
||||
td = theme_data[name].copy()
|
||||
kind = td["theme"]
|
||||
del td["theme"]
|
||||
|
||||
if kind == "roundrect":
|
||||
td["rounded_window"] = False
|
||||
td["rounded_window"] = False
|
||||
|
||||
renpy.style.restore(style_backup)
|
||||
getattr(theme, kind)(**td)
|
||||
getattr(theme, function)(**td)
|
||||
customize_styles()
|
||||
renpy.style.rebuild()
|
||||
|
||||
@@ -264,7 +261,7 @@ label repeat_choose_theme:
|
||||
button(name,
|
||||
ui.returns(function),
|
||||
"",
|
||||
hovered=curried_show_theme(exemplar, "repeat_choose_theme"),
|
||||
hovered=curried_show_theme(function, exemplar, "repeat_choose_theme"),
|
||||
unhovered=does_nothing)
|
||||
|
||||
ui.close() # vbox
|
||||
@@ -292,7 +289,8 @@ label repeat_choose_color_scheme:
|
||||
|
||||
tip = _(u"Please choose a color scheme for your project.")
|
||||
|
||||
themes = [ k for k,v in theme_data.iteritems() if v["theme"] == theme_function ]
|
||||
|
||||
themes = theme_data.keys()
|
||||
themes.sort()
|
||||
|
||||
screen()
|
||||
@@ -307,9 +305,9 @@ label repeat_choose_color_scheme:
|
||||
|
||||
for i in themes:
|
||||
button(i,
|
||||
curried_switch_theme(i),
|
||||
curried_switch_theme(theme_function, i),
|
||||
"",
|
||||
hovered=curried_show_theme(i, "repeat_choose_color_scheme"),
|
||||
hovered=curried_show_theme(theme_function, i, "repeat_choose_color_scheme"),
|
||||
unhovered=does_nothing)
|
||||
|
||||
ui.close() # vbox
|
||||
|
||||
@@ -41,6 +41,7 @@ ignored_files = (
|
||||
"thumbs.db",
|
||||
"traceback.txt",
|
||||
"errors.txt",
|
||||
"files.txt",
|
||||
"saves"
|
||||
)
|
||||
|
||||
@@ -146,7 +147,7 @@ class MyZipFile(zipfile.ZipFile):
|
||||
def tree(
|
||||
src,
|
||||
dest,
|
||||
exclude_suffix=[ ".pyc", "~", ".bak" ],
|
||||
exclude_suffix=[ ".pyc", "~", ".bak", ".old", ".new" ],
|
||||
exclude_prefix=[ "#", "." ],
|
||||
exclude_files = set(ignored_files),
|
||||
root_exclude_prefix = [ ],
|
||||
@@ -392,11 +393,13 @@ def distribute(
|
||||
if build_windows or build_all:
|
||||
|
||||
win_files.append((rb + "renpy.exe", "/" + executable_name + ".exe"))
|
||||
win_files.append((rb + "renpy.code", "/renpy.code"))
|
||||
win_files.append((rb + "python26.dll", "/python26.dll"))
|
||||
win_files.append((rb + "msvcr90.dll", "/msvcr90.dll"))
|
||||
win_files.append((rb + "Microsoft.VC90.CRT.manifest", "/Microsoft.VC90.CRT.manifest"))
|
||||
|
||||
win_files.append((rb + "lib", "/lib"))
|
||||
win_files.extend(tree(rb + "lib/windows-x86", "/lib/windows-x86"))
|
||||
|
||||
if os.path.exists(project_path + "/icon.ico"):
|
||||
file_data[rb + "renpy.exe"] = change_icon.change_icons(
|
||||
rb + "renpy.exe",
|
||||
|
||||
@@ -221,6 +221,27 @@ init 11 python:
|
||||
|
||||
interact()
|
||||
|
||||
def pauseinfo(t, message):
|
||||
"""
|
||||
Displays an error to the user, and lets him click to return to
|
||||
`target`.
|
||||
"""
|
||||
|
||||
set_tooltip("")
|
||||
|
||||
screen()
|
||||
|
||||
ui.vbox()
|
||||
title(t)
|
||||
text(message)
|
||||
|
||||
ui.null(height=20)
|
||||
|
||||
button(_(u"Ok"), ui.returns(True), None)
|
||||
ui.close()
|
||||
|
||||
interact()
|
||||
|
||||
def info(t, message):
|
||||
"""
|
||||
Displays an informational message to the user, and immediately
|
||||
|
||||
@@ -100,6 +100,9 @@ init -1 python hide:
|
||||
## Set this to False if the game does not have any sound effects.
|
||||
config.sound = False
|
||||
|
||||
# Disable opengl.
|
||||
config.gl_enable = False
|
||||
|
||||
python early:
|
||||
config.save_directory = "launcher-2"
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
def k(s):
|
||||
s = s.replace(" ", "")
|
||||
s = s.replace(":", "")
|
||||
s = s.replace("\n", "")
|
||||
|
||||
return int(s, 16)
|
||||
|
||||
modulus = k("""
|
||||
00:c2:e6:31:c6:7d:b3:cf:57:12:91:cf:b4:2c:9d:
|
||||
25:17:cf:21:f8:ac:5b:1d:c1:95:56:9d:1c:1c:d5:
|
||||
eb:67:ca:0a:a4:3f:e5:9c:6c:10:6e:4a:7a:2c:c2:
|
||||
d6:e3:3f:84:6d:b1:6f:70:3d:05:4e:06:91:3c:51:
|
||||
28:3f:b1:26:a5:be:6e:a6:14:a1:09:95:87:10:4d:
|
||||
c3:4b:44:fd:e0:a6:9d:f8:1f:50:ca:8a:0d:fd:86:
|
||||
7d:39:74:af:af:4e:05:8b:bd:93:b5:9b:6a:85:ca:
|
||||
1e:47:25:ca:f1:31:47:10:3e:a2:26:79:d2:00:34:
|
||||
f4:c5:a8:db:b6:36:2b:70:ef:14:8c:44:41:02:11:
|
||||
64:31:d4:d8:cd:7b:a7:e1:af:25:2c:a4:31:fb:84:
|
||||
c7:bc:6e:7c:fb:6a:46:5d:ee:bb:5f:74:96:a1:fe:
|
||||
13:79:55:e8:c4:74:77:1c:ea:6a:8e:a8:cb:89:da:
|
||||
20:db:88:18:e5:4a:f9:93:43:03:53:c3:d8:a3:2c:
|
||||
73:ea:8c:64:55:da:cf:a5:c7:11:70:ce:d4:51:3c:
|
||||
2c:19:06:3c:23:0c:d6:02:a5:95:28:b7:b0:34:1f:
|
||||
5d:32:38:e0:01:f2:12:b5:b2:8f:6b:83:83:06:6c:
|
||||
e0:ca:ec:e5:45:3e:75:79:f4:bf:47:e2:56:cd:8a:
|
||||
7b:cc:c7:0d:14:af:00:f6:e0:64:e2:30:a3:6c:ed:
|
||||
05:1e:33:9a:88:8b:0d:31:48:2b:02:65:61:4b:cd:
|
||||
84:90:c5:83:ba:93:1f:b7:78:7f:ec:4e:e9:bc:02:
|
||||
03:86:c2:a9:00:87:4c:e1:bb:d8:e7:b2:12:a6:9b:
|
||||
ab:9f:24:6f:6d:fe:09:60:22:d9:45:c2:20:55:70:
|
||||
27:9d:3a:84:fb:57:9a:d3:d0:d2:d3:18:25:8c:40:
|
||||
f8:2c:15:98:de:2e:2d:be:b4:dd:6e:24:2b:07:0b:
|
||||
21:08:a6:db:30:df:5c:7f:50:6f:be:b7:2e:40:28:
|
||||
58:85:89:de:4e:c7:66:af:fc:05:1c:c7:4d:d1:d2:
|
||||
fa:2c:00:1a:0e:47:5f:30:b6:e6:90:fe:99:96:42:
|
||||
4d:17:d3:13:36:7b:76:1c:36:c6:31:f3:a8:b0:9c:
|
||||
33:a1:b3:e9:40:51:b9:29:1d:b4:36:2a:20:0e:c0:
|
||||
f7:fb:a9:db:18:e0:67:ca:5d:d7:46:03:17:32:04:
|
||||
35:24:5a:fe:0a:1e:7b:96:8b:0a:fb:3c:f6:94:92:
|
||||
ab:d8:7d:ed:e4:2b:64:d7:ab:8d:11:89:e3:80:9d:
|
||||
28:59:da:de:6f:55:30:30:78:9a:06:30:5b:a4:ff:
|
||||
7a:70:49:b6:8c:9a:66:c0:a8:77:74:ca:f5:02:05:
|
||||
63:8c:83
|
||||
""")
|
||||
|
||||
exponent = 0x10001
|
||||
|
||||
@@ -105,11 +105,14 @@ label top:
|
||||
ui.null()
|
||||
|
||||
ui.null()
|
||||
|
||||
|
||||
|
||||
ui.close()
|
||||
ui.close()
|
||||
|
||||
if update_allowed:
|
||||
ui.key("U", Jump("update"))
|
||||
|
||||
interact()
|
||||
|
||||
# ProcessBehavior can return True, which sends us here.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
init -999:
|
||||
$ config.script_version = (6, 11, 0)
|
||||
$ config.script_version = (6, 11, 2)
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
init python:
|
||||
LAUNCHER_RPYS = set(['options.rpy', 'strings.rpy', 'transupdate.rpy', 'choose_theme.rpy', 'archiver.rpy', 'project.rpy', 'script_version.rpy', 'new.rpy', 'themes_data.rpy', 'opts.rpy', 'interface.rpy', 'projectsdir.rpy', 'distribute.rpy', 'script.rpy', 'editor.rpy'])
|
||||
LAUNCHER_RPYS = set(['options.rpy', 'strings.rpy', 'transupdate.rpy', 'choose_theme.rpy', 'archiver.rpy', 'project.rpy', 'script_version.rpy', 'new.rpy', 'updater.rpy', 'themes_data.rpy', 'opts.rpy', 'interface.rpy', 'projectsdir.rpy', 'update_interface.rpy', 'distribute.rpy', 'script.rpy', 'editor.rpy'])
|
||||
|
||||
TRANSLATION_STRINGS = [
|
||||
|
||||
u"Graphics Acceleration",
|
||||
u"Automatically Choose",
|
||||
u"Prefer Software Renderer",
|
||||
u"Prefer OpenGL Renderer",
|
||||
u"Continue",
|
||||
u"Are you sure?",
|
||||
u"Are you sure you want to delete this save?",
|
||||
u"Are you sure you want to overwrite your save?",
|
||||
@@ -64,14 +69,13 @@ init python:
|
||||
u"Joystick...",
|
||||
u"Joystick Configuration",
|
||||
u"Voice Volume",
|
||||
u"Developer Menu",
|
||||
u"Return to the developer menu",
|
||||
u"Reload Game (Shift+R)",
|
||||
u"Reload Game (Shift + R)",
|
||||
u"Variable Viewer",
|
||||
u"Return to the developer menu",
|
||||
u"Theme Test",
|
||||
u"Style Hierarchy",
|
||||
u"FPS Meter",
|
||||
u"Image Location Picker",
|
||||
u"Filename List",
|
||||
u"Done",
|
||||
u"Auto",
|
||||
u"Quick",
|
||||
@@ -104,6 +108,16 @@ init python:
|
||||
u"Choose Theme",
|
||||
u"Please choose a color scheme for your project.",
|
||||
u"Choose Color Scheme",
|
||||
u"Base Name",
|
||||
u"Please enter in the base name for your distribution. This name is used to generate the names of directories and archive files. Usually, this is the name of your game, plus a version number, like \"moonlight-1.0\".",
|
||||
u"Executable Name",
|
||||
u"Please enter a name for the executables in your distribution. This should not include an extension, as that will be added automatically.",
|
||||
u"Ignore Extensions",
|
||||
u"Please enter a space-separated list of file extensions. Files with these extensions will not be included in the built distributions.",
|
||||
u"Documentation Extensions",
|
||||
u"Please enter a space separated list of documentation extensions. Files in the base directory with these extensions will have a second copy stored outside of the Macintosh application.",
|
||||
u"Thank you for choosing Ren'Py.",
|
||||
u"The distributions have been built. Be sure to test them before release.\n\nNote that unpacking and repacking the Macintosh, Linux, or Combined distributions on Windows is not supported.\n\nPlease announce your release at the {a=http://lemmasoft.renai.us/forums/}Lemma Soft Forums{/a}, and add it to {a=http://games.renpy.org}games.renpy.org{/a}.",
|
||||
u"Building Distributions",
|
||||
u"I've just performed a lint on your project. If it contains errors, you should say no and fix them.\nPlease also check {a=http://www.renpy.org/wiki/renpy/Download_Ren'Py}www.renpy.org{/a} to see if updates or fixes are available.\n\nDo you want to continue?",
|
||||
u"Base Name:",
|
||||
@@ -125,21 +139,6 @@ init python:
|
||||
u"Zip distribution for the Windows x86, Linux x86, Macintosh x86 and Macintosh ppc platforms.",
|
||||
u"Build",
|
||||
u"Start building the distributions.",
|
||||
u"Base Name",
|
||||
u"Please enter in the base name for your distribution. This name is used to generate the names of directories and archive files. Usually, this is the name of your game, plus a version number, like \"moonlight-1.0\".",
|
||||
u"Executable Name",
|
||||
u"Please enter a name for the executables in your distribution. This should not include an extension, as that will be added automatically.",
|
||||
u"Ignore Extensions",
|
||||
u"Please enter a space-separated list of file extensions. Files with these extensions will not be included in the built distributions.",
|
||||
u"Documentation Extensions",
|
||||
u"Please enter a space separated list of documentation extensions. Files in the base directory with these extensions will have a second copy stored outside of the Macintosh application.",
|
||||
u"Scanning...",
|
||||
u"Building Windows...",
|
||||
u"Building Linux...",
|
||||
u"Building Macintosh...",
|
||||
u"Building Combined...",
|
||||
u"Thank you for choosing Ren'Py.",
|
||||
u"The distributions have been built. Be sure to test them before release.\n\nNote that unpacking and repacking the Macintosh, Linux, or Combined distributions on Windows is not supported.\n\nPlease announce your release at the {a=http://lemmasoft.renai.us/forums/}Lemma Soft Forums{/a}, so we can add it to the Ren'Py web site.",
|
||||
u"The editor has been set from the RENPY_EDITOR environment variable, and cannot be changed.",
|
||||
u"Choose Editor",
|
||||
u"Please choose the editor that will be use to edit scripts and display errors. More editors can be downloaded from {a=http://www.renpy.org/wiki/renpy/Editors}the Ren'Py website{/a}.",
|
||||
@@ -154,6 +153,7 @@ init python:
|
||||
u"Something with that name already exists in the projects directory.",
|
||||
u"Creating Project",
|
||||
u"Please wait while we create the project.",
|
||||
u"Could not create the project directory. The error was: %s",
|
||||
u"%s Launcher",
|
||||
u"Launcher Options",
|
||||
u"Using RENPY_EDITOR",
|
||||
@@ -177,7 +177,10 @@ init python:
|
||||
u"Choose Projects Directory",
|
||||
u"Please choose the directory containing your projects.",
|
||||
u"Could not run zenity. The projects directory has been set to the directory immediately above the directory containing Ren'Py.",
|
||||
u"Tutorial Game",
|
||||
u"Launches the Ren'Py tutorial game.",
|
||||
u"Update Ren'Py",
|
||||
u"Updates Ren'Py to the latest version.",
|
||||
u"Now showing the Ren'Py documentation in your web browser.",
|
||||
u"Now showing the Ren'Py Games List in your web browser.",
|
||||
u"Launch",
|
||||
@@ -204,6 +207,11 @@ init python:
|
||||
u"Change Ren'Py launcher options.",
|
||||
u"Ren'Py Help",
|
||||
u"Open the Ren'Py documentation in a web browser.",
|
||||
u"Tutorial Game",
|
||||
u"Retrieving catalog",
|
||||
u"Checking files",
|
||||
u"Making directories.",
|
||||
u"Downloading updated files",
|
||||
u"Renaming files",
|
||||
u"Fixing permissions.",
|
||||
]
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@ init 1 python:
|
||||
# This is a list of (theme name, theme function, theme exemplar) tuples.
|
||||
themes = [
|
||||
("Roundrect", "roundrect", "Basic Blue"),
|
||||
("Bordered", "bordered", "Dramatic Flesh"),
|
||||
("Diamond", "diamond", "Colorblind"),
|
||||
("TV", "tv", "Fine China"),
|
||||
("Glow", "glow", "Really Red"),
|
||||
]
|
||||
|
||||
# This is a map from theme function to template text that sensibly calls
|
||||
@@ -57,6 +61,11 @@ init 1 python:
|
||||
## do so below.
|
||||
)"""
|
||||
|
||||
theme_templates["bordered"] = theme_templates["roundrect"].replace("roundrect", "bordered")
|
||||
theme_templates["diamond"] = theme_templates["roundrect"].replace("roundrect", "diamond")
|
||||
theme_templates["tv"] = theme_templates["roundrect"].replace("roundrect", "tv")
|
||||
theme_templates["glow"] = theme_templates["roundrect"].replace("roundrect", "glow")
|
||||
|
||||
# This is a map from theme name to the code needed to implement that
|
||||
# theme.
|
||||
theme_data = {
|
||||
@@ -66,7 +75,6 @@ init 1 python:
|
||||
'gm_root': '#dcebff',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#dcebff',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#003c78',
|
||||
'widget_hover': '#0050a0',
|
||||
'widget_selected': '#ffffc8',
|
||||
@@ -77,7 +85,6 @@ init 1 python:
|
||||
'gm_root': '#000000',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#000000',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#000000',
|
||||
'widget_hover': '#830000',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -88,7 +95,6 @@ init 1 python:
|
||||
'gm_root': '#393939',
|
||||
'label': '#c2c2c2',
|
||||
'mm_root': '#393939',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#898989',
|
||||
'widget_hover': '#464646',
|
||||
'widget_selected': '#F2F2F2',
|
||||
@@ -99,7 +105,6 @@ init 1 python:
|
||||
'gm_root': '#D0B4BA',
|
||||
'label': '#805C40',
|
||||
'mm_root': '#D0B4BA',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#ECC7D0',
|
||||
'widget_hover': '#E1D4C9',
|
||||
'widget_selected': '#805C40',
|
||||
@@ -110,7 +115,6 @@ init 1 python:
|
||||
'gm_root': '#FDF5E3',
|
||||
'label': '#502F13',
|
||||
'mm_root': '#FDF5E3',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#D96B00',
|
||||
'widget_hover': '#FD9B1C',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -121,7 +125,6 @@ init 1 python:
|
||||
'gm_root': '#2a201f',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#2a201f',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#BF7C51',
|
||||
'widget_hover': '#dda570',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -132,7 +135,6 @@ init 1 python:
|
||||
'gm_root': '#FBF9DF',
|
||||
'label': '#698071',
|
||||
'mm_root': '#FBF9DF',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#F5D4EE',
|
||||
'widget_hover': '#F0DDFF',
|
||||
'widget_selected': '#000000',
|
||||
@@ -143,7 +145,6 @@ init 1 python:
|
||||
'gm_root': '#b0b8ba',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#b0b8ba',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#8699a7',
|
||||
'widget_hover': '#9eb1ad',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -154,7 +155,6 @@ init 1 python:
|
||||
'gm_root': '#F7F7FA',
|
||||
'label': '#39435E',
|
||||
'mm_root': '#F7F7FA',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#6A7183',
|
||||
'widget_hover': '#1A2B47',
|
||||
'widget_selected': '#E3E3E4',
|
||||
@@ -165,7 +165,6 @@ init 1 python:
|
||||
'gm_root': '#D98989',
|
||||
'label': '#5D1010',
|
||||
'mm_root': '#D98989',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#F09898',
|
||||
'widget_hover': '#D6C5BB',
|
||||
'widget_selected': '#B31E1E',
|
||||
@@ -176,7 +175,6 @@ init 1 python:
|
||||
'gm_root': '#E6E6E6',
|
||||
'label': '#D9D9D9',
|
||||
'mm_root': '#E6E6E6',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#D9D9D9',
|
||||
'widget_hover': '#F0F2F2',
|
||||
'widget_selected': '#737373',
|
||||
@@ -187,7 +185,6 @@ init 1 python:
|
||||
'gm_root': '#1A140E',
|
||||
'label': '#F1EBE5',
|
||||
'mm_root': '#1A140E',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#4D3B29',
|
||||
'widget_hover': '#996E45',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -198,7 +195,6 @@ init 1 python:
|
||||
'gm_root': '#1A0001',
|
||||
'label': '#1A0001',
|
||||
'mm_root': '#1A0001',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#777777',
|
||||
'widget_hover': '#73735C',
|
||||
'widget_selected': '#000000',
|
||||
@@ -209,7 +205,6 @@ init 1 python:
|
||||
'gm_root': '#A84A3E',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#A84A3E',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#A89E7D',
|
||||
'widget_hover': '#8DB6B9',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -220,7 +215,6 @@ init 1 python:
|
||||
'gm_root': '#ffd0d0',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#ffd0d0',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#963232',
|
||||
'widget_hover': '#c83232',
|
||||
'widget_selected': '#ffffc8',
|
||||
@@ -231,7 +225,6 @@ init 1 python:
|
||||
'gm_root': '#B4CDD4',
|
||||
'label': '#94C7D4',
|
||||
'mm_root': '#B4CDD4',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#F2E6AA',
|
||||
'widget_hover': '#FCFCA4',
|
||||
'widget_selected': '#1A5766',
|
||||
@@ -242,7 +235,6 @@ init 1 python:
|
||||
'gm_root': '#B09D5A',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#B09B4F',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#753D00',
|
||||
'widget_hover': '#B19A48',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -253,7 +245,6 @@ init 1 python:
|
||||
'gm_root': '#000000',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#000000',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#333333',
|
||||
'widget_hover': '#000000',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -264,7 +255,6 @@ init 1 python:
|
||||
'gm_root': '#695640',
|
||||
'label': '#F2EDC4',
|
||||
'mm_root': '#695640',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#7A674F',
|
||||
'widget_hover': '#BDA77D',
|
||||
'widget_selected': '#FDFBEE',
|
||||
@@ -275,7 +265,6 @@ init 1 python:
|
||||
'gm_root': '#F7F7C5',
|
||||
'label': '#FCFCD7',
|
||||
'mm_root': '#F7F7C5',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#FFE06D',
|
||||
'widget_hover': '#E38A4F',
|
||||
'widget_selected': '#996600',
|
||||
@@ -286,7 +275,6 @@ init 1 python:
|
||||
'gm_root': '#FBF9EA',
|
||||
'label': '#F1EBE5',
|
||||
'mm_root': '#FBF9EA',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#33271C',
|
||||
'widget_hover': '#ECE7C4',
|
||||
'widget_selected': '#ffffff',
|
||||
@@ -297,7 +285,6 @@ init 1 python:
|
||||
'gm_root': '#e5f1e5',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#e5f1e5',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#7AA27B',
|
||||
'widget_hover': '#A3C7A3',
|
||||
'widget_selected': '#ffffff',
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# This is an early version of an interface for the updater. For now, we just
|
||||
# assume that the user wants to update the prerelease channel, and the
|
||||
# base tag.
|
||||
|
||||
init python:
|
||||
import os
|
||||
import time
|
||||
|
||||
version_fn = os.path.join(config.basedir, "lib", "update-version.txt")
|
||||
update_allowed = os.path.exists(version_fn)
|
||||
|
||||
label update:
|
||||
|
||||
python hide:
|
||||
|
||||
try:
|
||||
info("Checking for update...", "")
|
||||
|
||||
old_version = file(version_fn, "rb").read()
|
||||
updater = Updater(config.basedir, 'http://update.renpy.org/renpy/updates/prerelease', [ 'base' ])
|
||||
|
||||
# Check the version.
|
||||
version, verbose_version = updater.check_version(old_version)
|
||||
|
||||
if version is None:
|
||||
pauseinfo("Up To Date", "Your version of Ren'Py is up to date.")
|
||||
renpy.jump("top")
|
||||
|
||||
|
||||
if not yesno("Update Available", "Would you like to update to %s?" % verbose_version):
|
||||
renpy.jump("top")
|
||||
|
||||
# If we've made it this far, the user has decided that he wants
|
||||
# to try an update.
|
||||
|
||||
for what, amount, limit in updater.step():
|
||||
progress(what, limit, amount)
|
||||
|
||||
f = file(version_fn, "wb")
|
||||
f.write(version)
|
||||
f.close()
|
||||
|
||||
pauseinfo("Update complete.", "The update has finished. Ren'Py will now restart.")
|
||||
|
||||
if sys.platform == "win32" and sys.argv[0].lower().endswith(".exe"):
|
||||
proc = subprocess.Popen([sys.argv[0], config.basedir])
|
||||
else:
|
||||
proc = subprocess.Popen([sys.executable, sys.argv[0], config.basedir])
|
||||
|
||||
renpy.quit()
|
||||
|
||||
|
||||
except UpdateException, e:
|
||||
error('The update has failed, with the error message: %s' % e.args[0])
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
init python:
|
||||
|
||||
import urllib2
|
||||
import bz2
|
||||
import os
|
||||
import hashlib
|
||||
import public
|
||||
|
||||
class UpdateException(Exception):
|
||||
"""
|
||||
The exception that we return if the update fails.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
class Updater(object):
|
||||
"""
|
||||
A class that attempts to update a tree of files, with a reasonable
|
||||
degree of safety, security, speed, and progress reporting.
|
||||
"""
|
||||
|
||||
def __init__(self, local, remote, tags):
|
||||
"""
|
||||
Create a new updater.
|
||||
|
||||
`local`
|
||||
The name of the local directory where the files are stored.
|
||||
`remote`
|
||||
The remote url base.
|
||||
`tags`
|
||||
A list of tags to update.
|
||||
"""
|
||||
|
||||
self.local = local
|
||||
self.remote = remote
|
||||
|
||||
# The remote version we're upgrading to.
|
||||
self.version = None
|
||||
|
||||
# A list of directory names.
|
||||
self.directories = [ ]
|
||||
|
||||
# A list of file, bz2-size, adler32 tuples.
|
||||
self.files = [ ]
|
||||
|
||||
# Xbit files.
|
||||
self.xbit = [ ]
|
||||
|
||||
# The tags we use.
|
||||
self.tags = set(tags)
|
||||
|
||||
def snarf(self, url):
|
||||
"""
|
||||
Gets the url as a string.
|
||||
"""
|
||||
|
||||
url = self.remote + "/" + url
|
||||
|
||||
try:
|
||||
u = urllib2.urlopen(url, None, 5)
|
||||
return u.read()
|
||||
except Exception, e:
|
||||
raise UpdateException("Could not download %r: %r" % (url, e))
|
||||
|
||||
def retrieve(self, relative):
|
||||
"""
|
||||
Downloads the bz2-compressed file, and then decompresses it into
|
||||
relative.new.
|
||||
"""
|
||||
|
||||
bz = os.path.join(self.local, relative + ".new.bz2")
|
||||
new = os.path.join(self.local, relative + ".new")
|
||||
|
||||
url = self.remote + "/" + relative + ".bz2"
|
||||
|
||||
try:
|
||||
u = urllib2.urlopen(url, None, 5)
|
||||
|
||||
f = file(bz, "wb")
|
||||
f.write(u.read())
|
||||
f.close()
|
||||
|
||||
u.close()
|
||||
|
||||
bzf = bz2.BZ2File(bz, "rb")
|
||||
f = file(new, "wb")
|
||||
|
||||
while True:
|
||||
buf = bzf.read(1024 * 1024)
|
||||
|
||||
if not buf:
|
||||
break
|
||||
|
||||
f.write(buf)
|
||||
|
||||
f.close()
|
||||
bzf.close()
|
||||
|
||||
os.unlink(bz)
|
||||
|
||||
except Exception, e:
|
||||
raise UpdateException("Could not download %r: %r" % (url, e))
|
||||
|
||||
|
||||
def check_version(self, version):
|
||||
"""
|
||||
Checks to see if version is still up to date. Returns a new-version,
|
||||
verbose-version string. new-version is an internal representation
|
||||
of the version being downloaded, while verbose-version is a
|
||||
string that can be presented to the user.
|
||||
|
||||
The `version` argument should be given the new-version returned
|
||||
from the last successful update. new-version is None if we are
|
||||
up to date.
|
||||
"""
|
||||
|
||||
remote_version = self.snarf("version")
|
||||
|
||||
self.version, verbose_version = remote_version.split("\n", 1)
|
||||
self.version += " " + " ".join(sorted(self.tags))
|
||||
|
||||
if self.version.strip() == version.strip():
|
||||
return None, verbose_version
|
||||
else:
|
||||
return self.version, verbose_version
|
||||
|
||||
def verify_hash(self, relative, digest):
|
||||
"""
|
||||
Verifies that the file `relative` has the hash value `digest`.
|
||||
"""
|
||||
|
||||
fn = os.path.join(self.local, relative)
|
||||
|
||||
if not os.path.exists(fn):
|
||||
return False
|
||||
|
||||
hash = hashlib.sha256()
|
||||
|
||||
try:
|
||||
f = file(fn, "rb")
|
||||
|
||||
while True:
|
||||
data = f.read(1024 * 1024)
|
||||
|
||||
if not data:
|
||||
break
|
||||
|
||||
if not "renpy.app" in fn:
|
||||
if fn.endswith(".rpy") or fn.endswith(".rpym") or fn.endswith(".py") or fn.endswith(".txt"):
|
||||
data = data.replace("\n", "\r\n")
|
||||
data = data.replace("\r\r\n", "\r\n")
|
||||
|
||||
hash.update(data)
|
||||
|
||||
f.close()
|
||||
|
||||
except:
|
||||
return False
|
||||
|
||||
return hash.hexdigest() == digest
|
||||
|
||||
|
||||
def get_catalog(self):
|
||||
"""
|
||||
Downloads the catalog file from the server, checking the signature
|
||||
as necessary.
|
||||
"""
|
||||
|
||||
self.retrieve("catalog1")
|
||||
catalog_fn = os.path.join(self.local, "catalog1.new")
|
||||
|
||||
verified = False
|
||||
|
||||
try:
|
||||
hash = hashlib.sha256()
|
||||
|
||||
f = file(catalog_fn, "rb")
|
||||
|
||||
# Read control information.
|
||||
for l in f:
|
||||
if l[0] == "-":
|
||||
break
|
||||
|
||||
hash.update(l)
|
||||
|
||||
l = l[:-1]
|
||||
|
||||
a = l.split("\t")
|
||||
|
||||
if a[0] == "file":
|
||||
cmd, digest, size, tag, name = a
|
||||
|
||||
if tag in self.tags:
|
||||
self.files.append((name, digest, int(size)))
|
||||
|
||||
elif a[0] == "dir":
|
||||
cmd, tag, name = a
|
||||
|
||||
if tag in self.tags:
|
||||
self.directories.append(name)
|
||||
|
||||
elif a[0] == "xbit":
|
||||
cmd, name = a
|
||||
self.xbit.append(name)
|
||||
|
||||
else:
|
||||
raise UpdateException("Unknown upgrade command: %r" % l)
|
||||
|
||||
# Compute the unsigned message.
|
||||
unsigned = int("01" + hash.hexdigest(), 16)
|
||||
|
||||
for l in f:
|
||||
a = l[:-1].split("\t")
|
||||
|
||||
if a[0] != "signature":
|
||||
continue
|
||||
|
||||
signature = int(a[1], 16)
|
||||
if pow(signature, public.exponent, public.modulus) == unsigned:
|
||||
verified = True
|
||||
|
||||
f.close()
|
||||
os.unlink(catalog_fn)
|
||||
|
||||
except UpdateException:
|
||||
raise
|
||||
except Exception, e:
|
||||
raise UpdateException("Could not download catalog: %r" % (e,))
|
||||
|
||||
if not verified:
|
||||
raise UpdateException("Could not verify catalog signature.")
|
||||
|
||||
|
||||
def step(self):
|
||||
"""
|
||||
This is a generator that performs the steps in the update
|
||||
process. It yields a (message, complete, total) tuple for
|
||||
each step, and terminates upon success.
|
||||
"""
|
||||
|
||||
yield (u"Retrieving catalog", 0, 1)
|
||||
self.get_catalog()
|
||||
|
||||
updated_files = [ ]
|
||||
download_size = 0
|
||||
|
||||
for i, (name, hash, size) in enumerate(self.files):
|
||||
yield (u"Checking files", i, len(self.files))
|
||||
|
||||
if not self.verify_hash(name, hash):
|
||||
updated_files.append((name, hash, size))
|
||||
download_size += size
|
||||
|
||||
complete_size = 0
|
||||
|
||||
# Todo: Make directories.
|
||||
|
||||
for i, dir in enumerate(self.directories):
|
||||
|
||||
yield (u"Making directories", i, len(self.directories))
|
||||
|
||||
dir = os.path.join(self.local, dir)
|
||||
|
||||
if not os.path.exists(dir):
|
||||
try:
|
||||
os.mkdir(dir)
|
||||
except:
|
||||
raise UpdateException("Couldn't make directory %r." % dir)
|
||||
|
||||
complete = 0
|
||||
|
||||
for name, hash, size in updated_files:
|
||||
|
||||
yield (u"Downloading updated files", complete, len(updated_files))
|
||||
|
||||
if self.verify_hash(name + ".new", hash):
|
||||
complete_size += size
|
||||
continue
|
||||
|
||||
self.retrieve(name)
|
||||
|
||||
if not self.verify_hash(name + ".new", hash):
|
||||
raise UpdateException("Could not verify download of %r." % name)
|
||||
|
||||
complete_size += size
|
||||
complete += 1
|
||||
|
||||
umask = os.umask(0)
|
||||
os.umask(umask)
|
||||
|
||||
for i, (name, hash, size) in enumerate(updated_files):
|
||||
|
||||
yield (u"Renaming files", i, len(updated_files))
|
||||
|
||||
fn = os.path.join(self.local, name)
|
||||
|
||||
if os.path.exists(fn + ".old"):
|
||||
os.unlink(fn + ".old")
|
||||
|
||||
if os.path.exists(fn):
|
||||
os.rename(fn, fn + ".old")
|
||||
|
||||
os.rename(fn + ".new", fn)
|
||||
|
||||
if fn.endswith(".py") and os.path.exists(fn + 'o'):
|
||||
os.unlink(fn + 'o')
|
||||
|
||||
for i, name in enumerate(self.xbit):
|
||||
yield (u"Fixing permissions", i, len(self.xbit))
|
||||
|
||||
fn = os.path.join(self.local, name)
|
||||
|
||||
if os.path.exists(fn):
|
||||
os.chmod(fn, 0777 & (~umask))
|
||||
|
||||
|
||||
# if __name__ == "__main__":
|
||||
|
||||
# up = Updater("/tmp/renpy-1", "file:///tmp/renpy-6.11.0", [ "base" ])
|
||||
# version, verbose_version = up.check_version(1)
|
||||
|
||||
# for message, done, total in up.step():
|
||||
# print message, "(%d/%d)" % (done, total)
|
||||
|
||||
# print version
|
||||
# print verbose_version
|
||||
|
||||
|
||||
@@ -1,534 +0,0 @@
|
||||
# This file contains the code needed to build a Ren'Py distribution.
|
||||
|
||||
init python:
|
||||
import zipfile
|
||||
import tarfile
|
||||
import os
|
||||
import os.path
|
||||
import time
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
import pefile
|
||||
|
||||
# Returns true if a file or directory should not be included in
|
||||
# the distribution
|
||||
|
||||
ignored_files = ("thumbs.db",
|
||||
"launcherinfo.py",
|
||||
"traceback.txt",
|
||||
"errors.txt",
|
||||
"icon.ico",
|
||||
"icon.icns"
|
||||
)
|
||||
|
||||
|
||||
root_ignored_files = (
|
||||
"common",
|
||||
"renpy",
|
||||
"renpy.code",
|
||||
"python23.dll",
|
||||
"python24.dll",
|
||||
"python25.dll",
|
||||
"msvcr71.dll",
|
||||
"lib",
|
||||
"iliad-icon.png",
|
||||
"manifest.xml"
|
||||
)
|
||||
|
||||
def ignored(fn, dir, dest, root):
|
||||
if fn[0] == ".":
|
||||
return True
|
||||
|
||||
for i in store.ignore_extensions:
|
||||
if fn.endswith(i):
|
||||
return True
|
||||
|
||||
if fn.lower() in ignored_files:
|
||||
return True
|
||||
|
||||
if fn == "saves":
|
||||
return True
|
||||
|
||||
if fn == "archived":
|
||||
return True
|
||||
|
||||
if root and dir == dest:
|
||||
if fn.endswith(".py") or fn.endswith(".sh") or fn.endswith(".app"):
|
||||
return True
|
||||
|
||||
if fn in root_ignored_files:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def tree(src, dest,
|
||||
exclude_suffix=[ ".pyc", "~", ".bak" ],
|
||||
exclude_prefix=[ ".", '#' ],
|
||||
exclude=ignored_files,
|
||||
exclude_func=ignored,
|
||||
root=False,
|
||||
):
|
||||
|
||||
# Get rid of trailing slashes.
|
||||
if src[-1] == "/":
|
||||
src = src[:-1]
|
||||
|
||||
if dest and dest[-1] == "/":
|
||||
dest = dest[:-1]
|
||||
|
||||
# What should we include?
|
||||
def include(fn, destdir, dest):
|
||||
for i in exclude_suffix:
|
||||
if fn.endswith(i):
|
||||
return False
|
||||
|
||||
for i in exclude_prefix:
|
||||
if fn.startswith(i):
|
||||
return False
|
||||
|
||||
for i in exclude:
|
||||
if i == fn.lower():
|
||||
return False
|
||||
|
||||
if exclude_func and exclude_func(fn, destdir, dest, root):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
rv = [ ]
|
||||
|
||||
# Walk the tree, including what is necessary.
|
||||
for srcdir, dirs, files in os.walk(src):
|
||||
|
||||
if dest:
|
||||
destdir = dest + srcdir[len(src):]
|
||||
else:
|
||||
destdir = srcdir[len(src) + 1:]
|
||||
|
||||
if destdir:
|
||||
rv.append((srcdir, destdir))
|
||||
|
||||
for fn in files:
|
||||
|
||||
if not include(fn, destdir, dest):
|
||||
continue
|
||||
|
||||
sfn = srcdir + "/" + fn
|
||||
|
||||
if destdir:
|
||||
dfn = destdir + "/" + fn
|
||||
else:
|
||||
dfn = fn
|
||||
|
||||
dfn = dfn.replace("\\", "/")
|
||||
|
||||
rv.append((sfn, dfn))
|
||||
|
||||
dirs[:] = [ i for i in dirs if include(i, destdir, dest) ]
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
label distribute:
|
||||
|
||||
python hide:
|
||||
zlib.Z_DEFAULT_COMPRESSION = 9
|
||||
|
||||
store.progress_time = 0
|
||||
|
||||
def progress(tit, n, m, time=time):
|
||||
|
||||
if time.time() < store.progress_time + .1:
|
||||
return
|
||||
|
||||
title(tit)
|
||||
|
||||
mid(message)
|
||||
ui.bar(m, n, xmaximum=200, xalign=0.5)
|
||||
ui.close()
|
||||
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
# Check to see which platforms we can build on.
|
||||
if os.path.exists(config.renpy_base + "/renpy.exe"):
|
||||
windows = True
|
||||
else:
|
||||
windows = False
|
||||
|
||||
if os.path.exists(config.renpy_base + "/lib/linux-x86"):
|
||||
linux = True
|
||||
else:
|
||||
linux = False
|
||||
|
||||
if os.path.exists(config.renpy_base + "/lib/linux-iliad"):
|
||||
iliad = True
|
||||
else:
|
||||
iliad = False
|
||||
|
||||
if os.path.exists(config.renpy_base + "/renpy.app"):
|
||||
mac = True
|
||||
else:
|
||||
mac = False
|
||||
|
||||
if not (windows or mac or linux or iliad):
|
||||
store.error(u"Can't Distribute", u"Ren'Py is missing files required for distribution. Please download the full package from {a=http://www.renpy.org/}www.renpy.org{/a}.", "tools_menu")
|
||||
|
||||
lint()
|
||||
|
||||
store.message = ""
|
||||
|
||||
title(_(u"Building Distributions"))
|
||||
|
||||
mid()
|
||||
text(u"I've just performed a lint on your project. If it contains errors, you should say no and fix them.\nCheck {a=http://www.renpy.org/wiki/renpy/Download_Ren'Py}www.renpy.org{/a} to see if updates or fixes are available.\n\nDo you want to continue?")
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
button(u"Yes", clicked=ui.returns(True))
|
||||
button(u"No", clicked=ui.returns(False))
|
||||
ui.close()
|
||||
|
||||
if not interact():
|
||||
renpy.jump("tools")
|
||||
|
||||
|
||||
# if not windows or not mac or not linux:
|
||||
# store.message = "The full version of Ren'Py can build for Windows, Mac, and Linux. Download it from www.renpy.org."
|
||||
|
||||
title(u"Building Distributions")
|
||||
|
||||
mid()
|
||||
text(u"Distributions will be built for the following platforms:")
|
||||
|
||||
spacer()
|
||||
|
||||
if windows:
|
||||
text(u"Windows 2000+", style='launcher_input')
|
||||
|
||||
if linux:
|
||||
text(u"Linux x86", style='launcher_input')
|
||||
|
||||
if iliad:
|
||||
text(u"iLiad", style='launcher_input')
|
||||
|
||||
if mac:
|
||||
text(u"Mac OS X 10.4+", style='launcher_input')
|
||||
|
||||
spacer()
|
||||
|
||||
|
||||
# TODO: If missing platforms, prompt for a DL.
|
||||
|
||||
text(u"Is this okay?")
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
button(u"Yes", clicked=ui.returns(True))
|
||||
button(u"No", clicked=ui.returns(False))
|
||||
ui.close()
|
||||
|
||||
if not interact():
|
||||
renpy.jump("tools")
|
||||
|
||||
default_name = project.info.get('distribution_base', project.name)
|
||||
|
||||
name = prompt(u"Building Distributions",
|
||||
u"Please enter a base name for the directories making up this distribution.",
|
||||
"tools",
|
||||
default_name,
|
||||
u"This usually should include a name and version number, like 'moonlight_walks-1.0'.")
|
||||
|
||||
name = name.strip()
|
||||
|
||||
if not name:
|
||||
store.error(u"Error", u"The distribution name should not be empty.", "tools_menu")
|
||||
|
||||
try:
|
||||
name = name.encode("ascii")
|
||||
except:
|
||||
store.error(u"Error", u"Distribution names must be ASCII. This is because archive file formats do not support non-ASCII characters in a uniform way.", "tools_menu")
|
||||
|
||||
project.info['distribution_base'] = name
|
||||
|
||||
ignore_extensions = project.info.get('ignore_extensions', "~ .bak")
|
||||
ignore_extensions = prompt(u"Building Distributions", u"Please enter a space separated list of the file extensions you do not want included in the distribution.", "tools", ignore_extensions)
|
||||
store.ignore_extensions = [ i.strip() for i in ignore_extensions.strip().split() ]
|
||||
project.info['ignore_extensions'] = ignore_extensions
|
||||
|
||||
project.save()
|
||||
|
||||
# Figure out the files that will make up the distribution.
|
||||
|
||||
multi = [ ]
|
||||
|
||||
# This finds the files and directories in the tree, and includes
|
||||
# them in the result.
|
||||
|
||||
|
||||
# renpy and common directories.
|
||||
multi.extend(tree(config.renpy_base + "/renpy", "renpy"))
|
||||
multi.append((config.renpy_base + "/LICENSE.txt", "renpy/LICENSE.txt"))
|
||||
multi.extend(tree(config.commondir, "common"))
|
||||
|
||||
# Include the project.
|
||||
multi.extend(tree(project.path, '',
|
||||
exclude_suffix = [ ],
|
||||
exclude_prefix = [ ],
|
||||
exclude=[ ],
|
||||
root=True))
|
||||
|
||||
shortgamedir = project.gamedir[len(project.path)+1:]
|
||||
|
||||
|
||||
def add_script_version(fn, multi=multi, shortgamedir=shortgamedir):
|
||||
|
||||
for a, b in multi:
|
||||
if b == shortgamedir + "/" + fn:
|
||||
return
|
||||
|
||||
for i in store.ignore_extensions:
|
||||
if fn.endswith(i):
|
||||
return
|
||||
|
||||
multi.append((config.gamedir + "/" + fn, shortgamedir + "/" + fn))
|
||||
|
||||
add_script_version("script_version.rpy")
|
||||
add_script_version("script_version.rpyc")
|
||||
|
||||
# renpy.py
|
||||
multi.append((config.renpy_base + "/renpy.py",
|
||||
project.name + ".py"))
|
||||
|
||||
# Windows Zip
|
||||
if windows:
|
||||
win_files = [
|
||||
( config.renpy_base + "/renpy.exe", project.name + ".exe"),
|
||||
( config.renpy_base + "/renpy.code", "renpy.code" ),
|
||||
( config.renpy_base + "/python25.dll", "python25.dll" ),
|
||||
( config.renpy_base + "/msvcr71.dll", "msvcr71.dll" ),
|
||||
]
|
||||
|
||||
win_data = { }
|
||||
if os.path.exists(project.path + "/icon.ico"):
|
||||
win_data[project.name + ".exe"] = pefile.change_icons(
|
||||
config.renpy_base + "/renpy.exe",
|
||||
project.path + "/icon.ico",
|
||||
)
|
||||
|
||||
zf = zipfile.ZipFile(name + ".zip", "w", zipfile.ZIP_DEFLATED)
|
||||
|
||||
progress_len = len(multi) + len(win_files)
|
||||
store.message = u"Be sure to announce your project at the Lemma Soft Forums."
|
||||
|
||||
for i, (fn, an) in enumerate(multi + win_files):
|
||||
progress(u"Building Windows", i, progress_len)
|
||||
|
||||
if os.path.isdir(fn):
|
||||
continue
|
||||
|
||||
zi = zipfile.ZipInfo(name + "/" + an)
|
||||
|
||||
s = os.stat(fn)
|
||||
zi.date_time = time.gmtime(s.st_mtime)[:6]
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.create_system = 3
|
||||
|
||||
zi.external_attr = long(0100666) << 16
|
||||
data = file(fn, "rb").read()
|
||||
|
||||
data = win_data.get(an, data)
|
||||
|
||||
zf.writestr(zi, data)
|
||||
|
||||
|
||||
zf.close()
|
||||
|
||||
|
||||
# Linux Tar Bz2
|
||||
if linux:
|
||||
|
||||
linux_files = [
|
||||
(config.renpy_base + "/lib/linux-x86", "lib/linux-x86"),
|
||||
(config.renpy_base + "/renpy.sh", project.name + ".sh"),
|
||||
(config.renpy_base + "/lib/python", "lib/python"),
|
||||
]
|
||||
|
||||
|
||||
linux_files.extend(tree(config.renpy_base + "/lib/linux-x86", "lib/linux-x86"))
|
||||
|
||||
tf = tarfile.open(name + "-linux-x86.tar.bz2", "w:bz2")
|
||||
tf.dereference = True
|
||||
|
||||
progress_len = len(multi) + len(linux_files)
|
||||
store.message = u"If appropriate, please submit your game to www.renai.us."
|
||||
|
||||
for j, i in enumerate(multi + linux_files):
|
||||
|
||||
progress(u"Building Linux", j, progress_len)
|
||||
|
||||
fn, an = i
|
||||
|
||||
info = tf.gettarinfo(fn, name + "-linux-x86/" + an)
|
||||
|
||||
if info.isdir():
|
||||
perms = 0777
|
||||
elif info.name.endswith(".sh"):
|
||||
perms = 0777
|
||||
elif info.name.endswith(".so"):
|
||||
perms = 0777
|
||||
elif info.name.endswith("python"):
|
||||
perms = 0777
|
||||
elif info.name.endswith("python.real"):
|
||||
perms = 0777
|
||||
else:
|
||||
perms = 0666
|
||||
|
||||
info.mode = perms
|
||||
info.uid = 1000
|
||||
info.gid = 1000
|
||||
info.uname = "renpy"
|
||||
info.gname = "renpy"
|
||||
|
||||
if info.isreg():
|
||||
tf.addfile(info, file(fn, "rb"))
|
||||
else:
|
||||
tf.addfile(info)
|
||||
|
||||
tf.close()
|
||||
|
||||
|
||||
# iLiad Tar Bz2
|
||||
if iliad:
|
||||
|
||||
iliad_files = [
|
||||
(config.renpy_base + "/lib", "lib"),
|
||||
(config.renpy_base + "/renpy-iliad.sh", project.name + ".sh"),
|
||||
(config.renpy_base + "/lib/python", "lib/python"),
|
||||
(config.renpy_base + "/manifest.xml", "manifest.xml"),
|
||||
(config.renpy_base + "/iliad-icon.png", "iliad-icon.png"),
|
||||
]
|
||||
|
||||
iliad_files.extend(tree(config.renpy_base + "/lib/linux-iliad", "lib/linux-iliad"))
|
||||
|
||||
iliad_data = { }
|
||||
|
||||
manifest = file(config.renpy_base + "/manifest.xml", "r").read()
|
||||
manifest = manifest.replace("GAMENAME", project.name)
|
||||
iliad_data["manifest.xml"] = manifest
|
||||
|
||||
zf = zipfile.ZipFile(name + "-iLiad.zip", "w", zipfile.ZIP_DEFLATED)
|
||||
|
||||
progress_len = len(multi) + len(iliad_files)
|
||||
store.message = u"We thank Hixbooks for sponsoring iLiad support."
|
||||
|
||||
for i, (fn, an) in enumerate(multi + iliad_files):
|
||||
|
||||
progress(u"Building iLiad", i, progress_len)
|
||||
|
||||
if os.path.isdir(fn):
|
||||
continue
|
||||
|
||||
zi = zipfile.ZipInfo(project.name + "/" + an)
|
||||
|
||||
s = os.stat(fn)
|
||||
zi.date_time = time.gmtime(s.st_mtime)[:6]
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.create_system = 3
|
||||
|
||||
for ext in [ ".sh", ".so", "python", "python.real" ]:
|
||||
if fn.endswith(ext):
|
||||
zi.external_attr = long(0100777) << 16
|
||||
data = file(fn, "rb").read()
|
||||
break
|
||||
else:
|
||||
zi.external_attr = long(0100666) << 16
|
||||
data = file(fn, "rb").read()
|
||||
|
||||
data = iliad_data.get(an, data)
|
||||
zf.writestr(zi, data)
|
||||
|
||||
zf.close()
|
||||
|
||||
if mac:
|
||||
|
||||
mac_files = tree(config.renpy_base + "/renpy.app",
|
||||
project.name + ".app")
|
||||
|
||||
mac_files = [ (fn, an.replace("Ren'Py Launcher", project.name)) for (fn, an) in mac_files ]
|
||||
|
||||
# Data replacement for macintosh.
|
||||
mac_data = { }
|
||||
|
||||
quoted_name = project.name.replace("&", "&").replace("<", "<")
|
||||
info_plist = file(config.renpy_base + "/renpy.app/Contents/Info.plist", "rb").read().replace("Ren'Py Launcher", quoted_name)
|
||||
mac_data[project.name + ".app/Contents/Info.plist"] = info_plist
|
||||
|
||||
quoted_name = project.name.replace("\"", "\\\"")
|
||||
launcher_py = file(config.renpy_base + "/renpy.app/Contents/Resources/launcher.py", "rb").read().replace("Ren'Py Launcher", quoted_name)
|
||||
mac_data[project.name + ".app/Contents/Resources/launcher.py"] = launcher_py
|
||||
|
||||
if os.path.exists(project.path + "/icon.icns"):
|
||||
icon_data = file(project.path + "/icon.icns", "rb").read()
|
||||
mac_data[project.name + ".app/Contents/Resources/launcher.icns"] = icon_data
|
||||
|
||||
zf = zipfile.ZipFile(name + "-mac.zip", "w", zipfile.ZIP_DEFLATED)
|
||||
|
||||
progress_len = len(multi) + len(mac_files)
|
||||
store.message = u"Thank you for choosing Ren'Py."
|
||||
|
||||
for i, (fn, an) in enumerate(multi + mac_files):
|
||||
|
||||
progress(u"Building Mac OS X", i, progress_len)
|
||||
|
||||
if os.path.isdir(fn):
|
||||
continue
|
||||
|
||||
zi = zipfile.ZipInfo(name + "-mac/" + an)
|
||||
|
||||
s = os.stat(fn)
|
||||
zi.date_time = time.gmtime(s.st_mtime)[:6]
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.create_system = 3
|
||||
|
||||
if os.path.dirname(fn).endswith("MacOS") or fn.endswith(".so") or fn.endswith(".dylib"):
|
||||
zi.external_attr = long(0100777) << 16
|
||||
data = file(fn, "rb").read()
|
||||
else:
|
||||
zi.external_attr = long(0100666) << 16
|
||||
data = file(fn, "rb").read()
|
||||
|
||||
data = mac_data.get(an, data)
|
||||
zf.writestr(zi, data)
|
||||
|
||||
zf.close()
|
||||
|
||||
|
||||
# Announce Success
|
||||
|
||||
store.message = ""
|
||||
|
||||
title(u"Success")
|
||||
|
||||
mid()
|
||||
text(u"The distribution(s) have been built. Be sure to test them before release.")
|
||||
|
||||
spacer()
|
||||
|
||||
if mac:
|
||||
text(u"Note that unpacking and repacking Mac zips and Linux tarballs on Windows isn't supported.")
|
||||
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
button(u"Return", clicked=ui.returns(True))
|
||||
ui.close()
|
||||
|
||||
interact()
|
||||
|
||||
|
||||
jump tools
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# This file contains logic for detecting an editor, and for selecting
|
||||
# the default editor.
|
||||
|
||||
init:
|
||||
python hide:
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
if not config.editor:
|
||||
|
||||
editor = os.path.normpath(config.renpy_base + "/jedit/jedit.jar")
|
||||
|
||||
if os.path.exists(editor):
|
||||
|
||||
editor = renpy.shell_escape(editor)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
config.editor = 'javaw.exe -jar "' + editor + '" -reuseview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
config.editor_transient = 'javaw.exe -jar "' + editor + '" -newplainview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
else:
|
||||
config.editor = 'java -jar "' + editor + '" -reuseview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
config.editor_transient = 'java -jar "' + editor + '" -newplainview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
|
||||
if config.editor:
|
||||
os.environ['RENPY_EDITOR'] = config.editor
|
||||
if config.editor_transient:
|
||||
os.environ['RENPY_EDITOR_TRANSIENT'] = config.editor_transient
|
||||
|
||||
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,792 +0,0 @@
|
||||
python early:
|
||||
config.save_directory = "launcher-1"
|
||||
|
||||
init:
|
||||
|
||||
python:
|
||||
# Set up the window.
|
||||
config.screen_width = 350
|
||||
config.screen_height = 450
|
||||
config.window_title = "Ren'Py Launcher"
|
||||
|
||||
# Disable sound and joystick.
|
||||
config.sound = False
|
||||
config.joystick = False
|
||||
|
||||
# Disables autosave (we can't save/load)
|
||||
config.has_autosave = False
|
||||
|
||||
# Create some launcher styles.
|
||||
style.create('launcher_button', 'button')
|
||||
style.create('launcher_button_text', 'button_text')
|
||||
style.create('launcher_title_label', 'default')
|
||||
style.create('launcher_label', 'default')
|
||||
style.create('launcher_input', 'default')
|
||||
style.create('launcher_text', 'default')
|
||||
style.create('launcher_bottom_vbox', 'vbox')
|
||||
style.create('launcher_mid_vbox', 'vbox')
|
||||
|
||||
style_backup = renpy.style.backup()
|
||||
|
||||
_launcher_per_page = 8
|
||||
|
||||
# Choose the roundrect theme for the buttons.
|
||||
layout.compat()
|
||||
theme.roundrect(launcher=True)
|
||||
|
||||
style.hyperlink_text.color = "#0ff"
|
||||
|
||||
config.underlay = [
|
||||
renpy.Keymap(
|
||||
quit = renpy.quit_event,
|
||||
iconify = renpy.iconify,
|
||||
)
|
||||
]
|
||||
|
||||
def quote(c):
|
||||
n = ord(c)
|
||||
if 0x20 <= n <= 0x7f:
|
||||
return c
|
||||
else:
|
||||
return "\\x%02x" % n
|
||||
|
||||
def ifrw(label):
|
||||
if project.info.get("ro", False):
|
||||
return None
|
||||
else:
|
||||
return ui.jumps(label)
|
||||
|
||||
# We don't want the user going into the game menu.
|
||||
def interact():
|
||||
ui.window(background=Solid("#0008"), ypos=1.0, yminimum=80, xmargin=0, ymargin=0)
|
||||
ui.null()
|
||||
|
||||
ui.image("eileen_small.png", xalign=0.0, yalign=1.0)
|
||||
ui.add(DynamicDisplayable("Text(_(store.message), size=14, color='#fff', xpos=100, ypos=375, xmaximum=240)"))
|
||||
ui.text(renpy.version(), xalign=0, yalign=1.0, size=12, color='#000')
|
||||
|
||||
return ui.interact()
|
||||
|
||||
def title(name):
|
||||
ui.window(style='mm_root')
|
||||
ui.null()
|
||||
|
||||
ui.frame(xminimum=350, yminimum=370)
|
||||
ui.viewport(child_size=(2000, None), draggable=True, ymaximum=34)
|
||||
_label_factory(name, "launcher_title", size=28)
|
||||
|
||||
# ui.text(name, xpos=4, ypos=4, size=30, color="#559")
|
||||
|
||||
def text(name, style="launcher_text"):
|
||||
ui.text(_(name), style=style)
|
||||
|
||||
def label(name):
|
||||
_label_factory(name, "launcher")
|
||||
|
||||
def spacer():
|
||||
ui.add(Null(1, 6))
|
||||
|
||||
def mid(focus="mid"):
|
||||
ui.vbox(style='launcher_mid_vbox', focus=focus)
|
||||
|
||||
def bottom(focus="bottom"):
|
||||
ui.vbox(style='launcher_bottom_vbox', focus=focus)
|
||||
|
||||
def button(text, hover_text=None, clicked=None, hovered=None, selected=False):
|
||||
if hover_text:
|
||||
def hovered(hover_text=_(hover_text)):
|
||||
if store.message != hover_text:
|
||||
store.message = hover_text
|
||||
renpy.restart_interaction()
|
||||
|
||||
# ui.button(clicked=clicked, hovered=hovered)
|
||||
# ui.text(text, style="button_text")
|
||||
_button_factory(text, 'launcher', clicked=clicked, hovered=hovered, selected=selected, xmaximum=200)
|
||||
|
||||
|
||||
def prompt(name, message, cancel, default='', hint=''):
|
||||
store.message = _(hint)
|
||||
|
||||
# Creating the project.
|
||||
title(name)
|
||||
|
||||
mid()
|
||||
|
||||
text(message)
|
||||
|
||||
ui.input(default, exclude='{}/\\', style='launcher_input')
|
||||
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
button("Cancel", clicked=ui.jumps("main"))
|
||||
ui.close()
|
||||
|
||||
return interact()
|
||||
|
||||
def error(name, message, target):
|
||||
store.message = ''
|
||||
|
||||
# Creating the project.
|
||||
title(name)
|
||||
|
||||
mid()
|
||||
text(message)
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
button("Cancel", clicked=ui.jumps(target))
|
||||
ui.close()
|
||||
|
||||
return interact()
|
||||
|
||||
|
||||
def paged_menu(tit, choices, message, per_page=None, cancel='main'):
|
||||
|
||||
if per_page is None:
|
||||
per_page = _launcher_per_page
|
||||
|
||||
page = 0
|
||||
pages = (len(choices) - 1) / per_page
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
store.message = message
|
||||
|
||||
title(tit)
|
||||
|
||||
mid(focus="paged_menu")
|
||||
|
||||
for name, desc, ret, hovered, selected in choices[page * per_page:(page + 1) * per_page]:
|
||||
if len(name) > 19:
|
||||
name = name[:18] + u"\u2026"
|
||||
button(name, desc, clicked=ui.returns(("return", ret)), hovered=hovered, selected=selected)
|
||||
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
|
||||
if pages >= 1:
|
||||
|
||||
if page < pages:
|
||||
button(u"Next Page", u"Go to the next page of projects.", clicked=ui.returns(("page", page + 1)))
|
||||
else:
|
||||
button(u"Next Page")
|
||||
|
||||
if page > 0:
|
||||
button(u"Previous Page", u"Go to the previous page of projects.", clicked=ui.returns(("page", page - 1)))
|
||||
else:
|
||||
button(u"Previous Page")
|
||||
|
||||
button(u"Cancel", u"Return to the top menu.", ui.jumps(cancel))
|
||||
|
||||
ui.close()
|
||||
|
||||
cmd, arg = interact()
|
||||
|
||||
if cmd == "repeat":
|
||||
continue
|
||||
|
||||
if cmd == "page":
|
||||
page = arg
|
||||
continue
|
||||
|
||||
if cmd == "return":
|
||||
return arg
|
||||
|
||||
class ProcessBehavior(renpy.display.layout.Null):
|
||||
|
||||
def __init__(self, proc):
|
||||
super(ProcessBehavior, self).__init__()
|
||||
|
||||
self.proc = proc
|
||||
|
||||
def event(self, ev, x, y, st):
|
||||
|
||||
if self.proc.poll() is not None:
|
||||
return True
|
||||
|
||||
renpy.game.interface.timeout(.25)
|
||||
|
||||
class Project(object):
|
||||
def __init__(self, name, path, gamedir, info):
|
||||
# name
|
||||
self.name = name
|
||||
|
||||
# path to project
|
||||
self.path = path
|
||||
|
||||
# gamedir
|
||||
self.gamedir = gamedir
|
||||
|
||||
self.info = info
|
||||
|
||||
import re
|
||||
|
||||
def upper(m):
|
||||
return m.group(0).upper()
|
||||
|
||||
title = re.sub(r'^.', upper, name)
|
||||
title = re.sub(r'\s+\S', upper, title)
|
||||
self.title = title
|
||||
|
||||
def save(self):
|
||||
import os
|
||||
|
||||
f = file(self.path + "/" + "launcherinfo.py.new", "w")
|
||||
for k, v in self.info.iteritems():
|
||||
f.write("%s = %r\n" % (k, v))
|
||||
f.close()
|
||||
|
||||
try:
|
||||
os.rename(self.path + "/launcherinfo.py.new", self.path + "/launcherinfo.py")
|
||||
except:
|
||||
os.unlink(self.path + "/launcherinfo.py")
|
||||
os.rename(self.path + "/launcherinfo.py.new", self.path + "/launcherinfo.py")
|
||||
|
||||
|
||||
def load_project(dir, name):
|
||||
import os.path
|
||||
|
||||
# Ignore unicode files.
|
||||
for i in name:
|
||||
if ord(i) >= 127:
|
||||
return
|
||||
|
||||
if os.path.isdir(dir + "/game"):
|
||||
gamedir = dir + "/game"
|
||||
elif os.path.isdir(dir + "/data"):
|
||||
gamedir = dir + "/data"
|
||||
else:
|
||||
return
|
||||
|
||||
desc = u""
|
||||
|
||||
info = dict()
|
||||
info["description"] = desc
|
||||
|
||||
if os.path.exists(dir + "/launcherinfo.py"):
|
||||
source = file(dir + "/launcherinfo.py", "rU").read().decode("utf8")
|
||||
if source[0] == u'\ufeff':
|
||||
source = source[1:]
|
||||
source = source.encode("raw_unicode_escape")
|
||||
|
||||
exec source in info
|
||||
|
||||
del info["__builtins__"]
|
||||
|
||||
store.projects.append(Project(name, dir, gamedir, info))
|
||||
|
||||
def load_projects():
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
store.projects = [ ]
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
if cwd == config.renpy_base:
|
||||
dirs = [ cwd ]
|
||||
else:
|
||||
dirs = [ config.renpy_base, cwd ]
|
||||
|
||||
for d in dirs:
|
||||
|
||||
contents = os.listdir(d)
|
||||
contents.sort()
|
||||
|
||||
for dd in contents:
|
||||
|
||||
dir = d + "/" + dd
|
||||
|
||||
if os.path.isdir(dir):
|
||||
load_project(dir, dd)
|
||||
|
||||
if not store.projects:
|
||||
raise Exception("The launcher will not function without any projects.")
|
||||
|
||||
|
||||
def lint():
|
||||
|
||||
import renpy.subprocess as subprocess
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
store.message = u"Lint in progress."
|
||||
title(u"Lint")
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
lf = file("lint.txt", "w+")
|
||||
|
||||
if hasattr(sys, "winver") and sys.argv[0].lower().endswith(".exe"):
|
||||
proc = subprocess.Popen([config.renpy_base + "/console.exe", "--lint", project.path], stdin=lf, stdout=lf, stderr=lf)
|
||||
else:
|
||||
proc = subprocess.Popen([sys.executable, sys.argv[0], "--lint", project.path], stdout=lf)
|
||||
|
||||
proc.wait()
|
||||
|
||||
lf.close()
|
||||
|
||||
renpy.launch_editor([ "lint.txt" ],transient=1)
|
||||
|
||||
def rmpersistent():
|
||||
|
||||
import renpy.subprocess as subprocess
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
store.message = u"Deleting persistent data."
|
||||
title(u"Delete Persistent")
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
if hasattr(sys, "winver") and sys.argv[0].lower().endswith(".exe"):
|
||||
proc = subprocess.Popen([config.renpy_base + "/console.exe", "--rmpersistent", project.path])
|
||||
else:
|
||||
proc = subprocess.Popen([sys.executable, sys.argv[0], "--rmpersistent", project.path])
|
||||
|
||||
proc.wait()
|
||||
|
||||
label main_menu:
|
||||
return
|
||||
|
||||
label find_project:
|
||||
|
||||
python hide:
|
||||
load_projects()
|
||||
|
||||
wanted = persistent.project or "demo"
|
||||
|
||||
for p in projects:
|
||||
if p.name == wanted:
|
||||
store.project = p
|
||||
break
|
||||
else:
|
||||
store.project = projects[0]
|
||||
|
||||
|
||||
store.game_proc = None
|
||||
|
||||
return
|
||||
|
||||
|
||||
label start:
|
||||
|
||||
call find_project from _call_find_project_1
|
||||
|
||||
label main:
|
||||
|
||||
python:
|
||||
store.message = u"What do you want to do?"
|
||||
|
||||
label top_menu:
|
||||
|
||||
|
||||
python hide:
|
||||
|
||||
while True:
|
||||
|
||||
title(project.title)
|
||||
|
||||
mid()
|
||||
|
||||
label(u"This Project")
|
||||
|
||||
if not game_proc or game_proc.poll() is not None:
|
||||
clicked = ui.jumps("launch")
|
||||
else:
|
||||
clicked = None
|
||||
|
||||
button(u"Launch",
|
||||
u"Starts the project running.",
|
||||
clicked=clicked)
|
||||
|
||||
|
||||
if config.editor:
|
||||
button(u"Edit Script",
|
||||
u"Edits the script files.",
|
||||
clicked=ui.jumps("edit"))
|
||||
|
||||
|
||||
button(u"Change Theme",
|
||||
u"Changes the color theme of the project.",
|
||||
ifrw("choose_theme"))
|
||||
|
||||
button(u"Game Directory",
|
||||
u"Opens the game directory.",
|
||||
clicked=ui.jumps("game_directory"))
|
||||
|
||||
|
||||
|
||||
button(u"Tools",
|
||||
u"Shows the tools menu.",
|
||||
clicked=ui.jumps("tools"))
|
||||
|
||||
spacer()
|
||||
|
||||
label(u"Change Project")
|
||||
|
||||
button(u"Select Project",
|
||||
u"Select a project to work with.",
|
||||
clicked=ui.jumps("select_project"))
|
||||
|
||||
button(u"New Project",
|
||||
u"Create a new project from a template.",
|
||||
clicked=ui.jumps("new"))
|
||||
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
button(u"Documentation", u"Read Ren'Py tutorials and manuals.", clicked=ui.jumps("documentation"))
|
||||
button(u"Quit", u"Quit the Ren'Py Launcher.", clicked=ui.jumps("confirm_quit"))
|
||||
ui.close()
|
||||
|
||||
|
||||
if game_proc and game_proc.poll() is None:
|
||||
ui.add(ProcessBehavior(game_proc))
|
||||
|
||||
interact()
|
||||
|
||||
jump top_menu
|
||||
|
||||
label select_project:
|
||||
|
||||
python hide:
|
||||
|
||||
choices = [ (p.name, p.info["description"], p, None, False) for p in projects if not p.info.get("template") ]
|
||||
|
||||
store.project = paged_menu(u"Select a Project", choices, u"Please select a project.")
|
||||
|
||||
persistent.project = store.project.name
|
||||
|
||||
store.game_proc = None
|
||||
|
||||
jump main
|
||||
|
||||
label launch:
|
||||
|
||||
python hide:
|
||||
import renpy.subprocess
|
||||
import sys
|
||||
import os.path
|
||||
import os
|
||||
|
||||
if hasattr(sys, "winver") and sys.argv[0].lower().endswith(".exe"):
|
||||
proc = renpy.subprocess.Popen([sys.argv[0], project.path])
|
||||
else:
|
||||
proc = renpy.subprocess.Popen([sys.executable, sys.argv[0], project.path])
|
||||
|
||||
store.message = _(u"%s has been launched.") % project.title
|
||||
|
||||
store.game_proc = proc
|
||||
|
||||
|
||||
jump top_menu
|
||||
|
||||
|
||||
|
||||
label edit:
|
||||
|
||||
python hide:
|
||||
import os
|
||||
|
||||
|
||||
files = [ project.gamedir + "/" + i for i in os.listdir(project.gamedir) if i.endswith(".rpy") if not i[0] == "."]
|
||||
|
||||
files.sort()
|
||||
|
||||
for i in files[:]:
|
||||
if i.endswith("options.rpy"):
|
||||
files.remove(i)
|
||||
files.insert(0, i)
|
||||
|
||||
for i in files[:]:
|
||||
if i.endswith("script.rpy"):
|
||||
files.remove(i)
|
||||
files.insert(0, i)
|
||||
|
||||
if not renpy.launch_editor(files):
|
||||
error(u"Error", u"Launching the editor failed. You may need Java, which can be downloaded for free from {a=http://www.java.com}java.com{/a}.", "start")
|
||||
|
||||
store.message = _(u"Launched editor with %d script files.") % len(files)
|
||||
|
||||
jump top_menu
|
||||
|
||||
label game_directory:
|
||||
|
||||
python hide:
|
||||
import os
|
||||
import os.path
|
||||
import platform
|
||||
import sys
|
||||
|
||||
gamedir = os.path.normpath(project.gamedir)
|
||||
|
||||
if sys.platform == "win32":
|
||||
os.startfile(gamedir)
|
||||
elif platform.mac_ver()[0]:
|
||||
import renpy.subprocess as subprocess
|
||||
subprocess.Popen([ "open", gamedir ])
|
||||
else:
|
||||
import renpy.subprocess as subprocess
|
||||
subprocess.Popen([ "xdg-open", gamedir ])
|
||||
|
||||
|
||||
gamedir = "".join(quote(i) for i in gamedir)
|
||||
store.message = _(u"Opening game directory:\n%s") % gamedir
|
||||
|
||||
jump top_menu
|
||||
|
||||
|
||||
label tools:
|
||||
|
||||
$ store.message = u"Please choose a tool you want to use with this project."
|
||||
|
||||
label tools_menu:
|
||||
|
||||
python hide:
|
||||
|
||||
title(_("Tools: %s") % project.title)
|
||||
|
||||
mid()
|
||||
|
||||
label(u"Anytime")
|
||||
|
||||
button(u"Check Script (Lint)",
|
||||
u"Checks the game's script for likely errors. This should be run before releasing.",
|
||||
clicked=ui.jumps("lint"))
|
||||
|
||||
|
||||
button(u"Delete Persistent",
|
||||
u"Deletes the game's persistent data.",
|
||||
clicked=ui.jumps("rmpersistent"))
|
||||
|
||||
# button("Quick Backup",
|
||||
# "Makes a backup copy of the project. You also need to make backups somewhere other then this computer.",
|
||||
# clicked=ui.jumps("backup"))
|
||||
|
||||
spacer()
|
||||
|
||||
label(u"Release Day")
|
||||
|
||||
button(u"Add From to Calls",
|
||||
u"Adds a from clause to each of the call statements in your script.",
|
||||
clicked=ifrw("add_from_to_calls"))
|
||||
|
||||
button(u"Archive Files",
|
||||
u"Archive files found under the game and archived directories.",
|
||||
clicked=ifrw("archive_files"))
|
||||
|
||||
button(u"Build Distributions",
|
||||
u"Build distributions for the platforms supported by Ren'Py.",
|
||||
clicked=ui.jumps("distribute"))
|
||||
|
||||
ui.close()
|
||||
|
||||
bottom()
|
||||
|
||||
button(u"Back",
|
||||
u"Goes back to the top menu.",
|
||||
clicked=ui.jumps("main"))
|
||||
|
||||
ui.close()
|
||||
|
||||
interact()
|
||||
|
||||
label lint:
|
||||
|
||||
python hide:
|
||||
lint()
|
||||
|
||||
store.message = u"A lint report should appear shortly."
|
||||
|
||||
jump tools_menu
|
||||
|
||||
|
||||
|
||||
label archive_files:
|
||||
|
||||
python hide:
|
||||
import os
|
||||
import os.path
|
||||
|
||||
import renpy.tools.archiver as archiver
|
||||
|
||||
extensions = project.info.get('archive_extensions', "*.png *.gif *.jpg")
|
||||
extensions = prompt(u"Archiving Files", u"Please enter a space separated list of the file patterns you want archived.", "tools", extensions)
|
||||
if not extensions.strip():
|
||||
renpy.jumps("tools_menu")
|
||||
project.info['archive_extensions'] = extensions
|
||||
extensions = [ i.strip() for i in extensions.strip().split() ]
|
||||
|
||||
|
||||
base = project.info.get('archive_base', "data")
|
||||
base = prompt(u"Archiving Files", u"Please enter the name of the archive file, without the .rpa extension.", "tools", base)
|
||||
base = base.strip()
|
||||
if not base:
|
||||
renpy.jumps("tools_menu")
|
||||
project.info['archive_base'] = base
|
||||
|
||||
project.save()
|
||||
|
||||
# Tell the user we're archiving images.
|
||||
title(u"Archiving Files")
|
||||
store.message = u"Please wait while we archive files."
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
|
||||
gamedir = project.gamedir
|
||||
archived = project.path + "/archived"
|
||||
|
||||
files = [ ]
|
||||
prefix = gamedir + "/" + base
|
||||
|
||||
def should_archive(fn, extensions=extensions):
|
||||
import fnmatch
|
||||
|
||||
fn = fn.lower()
|
||||
|
||||
if fn[0] == ".":
|
||||
return False
|
||||
|
||||
if fn == "presplash.png":
|
||||
return False
|
||||
if fn == "presplash.jpg":
|
||||
return False
|
||||
|
||||
for e in extensions:
|
||||
if fnmatch.fnmatch(fn, e):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
archived_files = set()
|
||||
|
||||
for bdir in (gamedir, archived):
|
||||
|
||||
for dirname, dirs, filenames in os.walk(bdir):
|
||||
|
||||
# Ignore svn.
|
||||
dirs[:] = [ i for i in dirs if not i[0] == '.' ]
|
||||
|
||||
for fn in filenames:
|
||||
|
||||
fullfn = dirname + "/" + fn
|
||||
shortfn = fullfn[len(bdir)+1:]
|
||||
|
||||
if shortfn in archived_files:
|
||||
continue
|
||||
|
||||
if not should_archive(shortfn):
|
||||
continue
|
||||
|
||||
files.append((fullfn, shortfn))
|
||||
archived_files.add(shortfn)
|
||||
|
||||
archiver.archive(prefix, files)
|
||||
|
||||
# f = file(gamedir + "/images.rpy", "w")
|
||||
# print >>f, "init:"
|
||||
# print >>f, " $ config.archives.append('images')"
|
||||
# f.close()
|
||||
|
||||
for fullfn, shortfn in files:
|
||||
afn = archived + "/" + shortfn
|
||||
|
||||
if fullfn == afn:
|
||||
continue
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.dirname(afn))
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
os.rename(fullfn, afn)
|
||||
except:
|
||||
os.rename(afn, afn + ".old")
|
||||
os.rename(fullfn, afn)
|
||||
os.unlink(afn + ".old")
|
||||
|
||||
store.message = u"The files have been added to the archive, and moved into the archived directory."
|
||||
|
||||
jump tools_menu
|
||||
|
||||
label backup:
|
||||
|
||||
python hide:
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
|
||||
# Tell the user we're archiving images.
|
||||
title(u"Making Backup")
|
||||
store.message = u"Please wait while we make a backup."
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
try:
|
||||
os.mkdir('backups')
|
||||
except:
|
||||
pass
|
||||
|
||||
while True:
|
||||
|
||||
btime = str(int(time.time()))
|
||||
bdir = "backups/%s.%s" % (project.name, btime)
|
||||
|
||||
if not os.path.exists(bdir):
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
shutil.copytree(project.path, bdir)
|
||||
|
||||
store.message = _(u"The backup was placed into %s.") % bdir
|
||||
|
||||
jump tools_menu
|
||||
|
||||
|
||||
label add_from_to_calls:
|
||||
|
||||
python hide:
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
|
||||
title(u"Add From to Calls")
|
||||
store.message = u"Please wait while we add from clauses to call statements."
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
import renpy.tools.add_from as add_from
|
||||
|
||||
add_from.add_from(project.gamedir, config.commondir)
|
||||
|
||||
store.message = _(u"Done adding from clauses to call statements. You may want to remove the .bak files created.")
|
||||
|
||||
jump tools_menu
|
||||
|
||||
label rmpersistent:
|
||||
|
||||
python hide:
|
||||
rmpersistent()
|
||||
store.message = _(u"Done deleting persistent data.")
|
||||
|
||||
jump tools_menu
|
||||
|
||||
|
||||
label confirm_quit:
|
||||
$ renpy.quit()
|
||||
|
||||
label documentation:
|
||||
python hide:
|
||||
import webbrowser
|
||||
webbrowser.open_new("file:///" + config.renpy_base + "/doc/index.html")
|
||||
store.message = _(u"Now showing the Ren'Py documentation in your web browser.")
|
||||
|
||||
jump top_menu
|
||||
@@ -1,167 +0,0 @@
|
||||
label new:
|
||||
|
||||
python hide:
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import time
|
||||
|
||||
|
||||
# Select a template.
|
||||
|
||||
choices = [ (p.name, p.info["description"], p, None, False) for p in projects if p.info.get("template", None)]
|
||||
|
||||
template = paged_menu(u"Select a Template", choices, u"Please select a project to use as a template for your project.")
|
||||
|
||||
# Choose project name.
|
||||
|
||||
name = prompt(u"Project Name", u"Type the name of your new project, and press enter.\n", "main")
|
||||
name = name.strip()
|
||||
|
||||
error = None
|
||||
|
||||
if not name:
|
||||
error = u"Please enter a non-empty project name."
|
||||
elif os.path.exists(name):
|
||||
error = u"A file or directory named '%s' already exists." % name
|
||||
else:
|
||||
try:
|
||||
name = name.encode("ascii")
|
||||
except:
|
||||
error = u"Project names must be ASCII. This is because the ZIP file format does not support non-ASCII characters in a uniform way."
|
||||
|
||||
if error:
|
||||
store.error(u"Error", error, "main")
|
||||
|
||||
# Tell the user we're creating the project.
|
||||
title(u"Creating Project")
|
||||
store.message = u"Please wait while we create the project."
|
||||
ui.pausebehavior(0)
|
||||
interact()
|
||||
|
||||
# Here is where we actually create the project.
|
||||
|
||||
import shutil
|
||||
|
||||
shutil.copytree(template.path, name)
|
||||
|
||||
unlink = template.info.get("unlink", [ ])
|
||||
unlink += [ 'launcherinfo.py' ]
|
||||
|
||||
for i in unlink:
|
||||
if os.path.exists(name + "/" + i):
|
||||
os.unlink(name + "/" + i)
|
||||
|
||||
for dir, dirs, files in os.walk(name):
|
||||
for d in list(dirs):
|
||||
if d.startswith("."):
|
||||
dirs.remove(d)
|
||||
dn = dir + "/" + d
|
||||
shutil.rmtree(dn, True)
|
||||
|
||||
# Change the save directory.
|
||||
options = file(name + "/game/options.rpy").read()
|
||||
save_dir = "%s-%d" % (name, time.time())
|
||||
options = options.replace("template-1220804310", save_dir)
|
||||
file(name + "/game/options.rpy", "w").write(options)
|
||||
|
||||
persistent.project = name
|
||||
|
||||
call find_project from _call_find_project_2
|
||||
|
||||
label choose_theme:
|
||||
|
||||
python hide:
|
||||
|
||||
# Select a color scheme.
|
||||
|
||||
themes = theme_data.keys()
|
||||
themes.sort()
|
||||
|
||||
choices = [ ]
|
||||
for i in themes:
|
||||
|
||||
def hovered(i=i):
|
||||
td = theme_data[i].copy()
|
||||
engine = td["theme"]
|
||||
del td["theme"]
|
||||
|
||||
if engine == "roundrect":
|
||||
renpy.style.restore(style_backup)
|
||||
theme.roundrect(launcher=True, **td)
|
||||
renpy.style.rebuild()
|
||||
return ("repeat", 0)
|
||||
|
||||
choices.append((i, None, i, hovered, False))
|
||||
|
||||
color_theme = paged_menu(u"Select a Theme", choices, u"Please select a color theme for your project. You can always change the colors later.", cancel='color_theme_cancel')
|
||||
|
||||
# Restore default theme.
|
||||
renpy.style.restore(style_backup)
|
||||
theme.roundrect(launcher=True)
|
||||
renpy.style.rebuild()
|
||||
|
||||
ofn = project.path + "/game/options.rpy"
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
if not os.path.exists(ofn):
|
||||
error(u"Changing Theme", u"The options file does not seem to exist.", "main")
|
||||
|
||||
inf = file(ofn, "rU")
|
||||
outf = file(ofn + ".new", "w")
|
||||
|
||||
td = theme_data[color_theme]
|
||||
|
||||
# TODO: Make this less specific to roundrect. Need to figure out
|
||||
# how to switch themes, rather than just recolor them.
|
||||
|
||||
changing = False
|
||||
changed = False
|
||||
|
||||
for l in inf:
|
||||
|
||||
if re.match(r'\s*theme.roundrect\(', l):
|
||||
changing = True
|
||||
changed = True
|
||||
elif re.match(r'\s*\)', l):
|
||||
changing = False
|
||||
elif changing:
|
||||
|
||||
def repl(m, td=td):
|
||||
return m.group(1) + m.group(2) + " = \"" + td.get(m.group(2), m.group(3)) + "\","
|
||||
|
||||
l = re.sub(r'^(\s*)(\w+) = "([\da-fA-F#]+)",', repl, l)
|
||||
|
||||
outf.write(l)
|
||||
|
||||
outf.close()
|
||||
inf.close()
|
||||
|
||||
try:
|
||||
os.rename(ofn + ".new", ofn)
|
||||
except:
|
||||
|
||||
# I hate windows.
|
||||
os.rename(ofn, ofn + ".old")
|
||||
os.rename(ofn + ".new", ofn)
|
||||
os.unlink(ofn + ".old")
|
||||
|
||||
if not changed:
|
||||
error(u"Changing Theme", u"Could not modify options.rpy, perhaps it was edited too much.", "main")
|
||||
|
||||
jump main
|
||||
|
||||
|
||||
|
||||
label color_theme_cancel:
|
||||
|
||||
python hide:
|
||||
|
||||
# Restore default theme.
|
||||
renpy.style.restore(style_backup)
|
||||
theme.roundrect(launcher=True)
|
||||
renpy.style.rebuild()
|
||||
|
||||
jump main
|
||||
@@ -1,343 +0,0 @@
|
||||
|
||||
# http://www.csn.ul.ie/~caolan/publink/winresdump/winresdump/doc/pefile.html
|
||||
# Contains a reasonable description of the format.
|
||||
|
||||
import struct
|
||||
import sys
|
||||
import array
|
||||
|
||||
# The starting point of the resource segment in the file.
|
||||
RESOURCE_BASE=0x3600
|
||||
|
||||
# The virtual memory location the resource segment is loaded
|
||||
# to.
|
||||
RESOURCE_VIRTUAL=0x6000
|
||||
|
||||
# The offset of the field that tells us with the alignment need be.
|
||||
ALIGNMENT_FIELD = 0x130
|
||||
|
||||
# The start of the .rsrc segment header.
|
||||
RSRC_HEADER = 0x268
|
||||
|
||||
# Locations in the file where we need to patch in the resource
|
||||
# segment length.
|
||||
RESOURCE_LENGTH_PATCHES = [ 0x0184, RSRC_HEADER + 0x8 ]
|
||||
|
||||
# Locations in the file where we need to patch in the padded
|
||||
# resource segment length.
|
||||
RESOURCE_PADDED_PATCHES = [ RSRC_HEADER + 0x10 ]
|
||||
|
||||
# Locations in the file where we need to patch in the change in the
|
||||
# size of the resource segement (and hence the change in the file's
|
||||
# total size.)
|
||||
SIZE_DELTA_PATCHES = [ 0x148 ]
|
||||
|
||||
# A location in the file that will be checked to be sure it matches
|
||||
# RESOURCE_BASE.
|
||||
CHECK_ADDRESS = RSRC_HEADER + 0x14
|
||||
|
||||
# A location in the file that will be checked to make sure it matches
|
||||
# RESOURCE_VIRTUAL
|
||||
CHECK_ADDRESS2 = RSRC_HEADER + 0xc
|
||||
|
||||
# This class performs various operations on memory-loaded binary files,
|
||||
# including modifications.
|
||||
class BinFile(object):
|
||||
|
||||
def set_u32(self, addr, value):
|
||||
self.a[addr+0] = (value >> 0) & 0xff
|
||||
self.a[addr+1] = (value >> 8) & 0xff
|
||||
self.a[addr+2] = (value >> 16) & 0xff
|
||||
self.a[addr+3] = (value >> 24) & 0xff
|
||||
|
||||
def u32(self):
|
||||
addr = self.addr
|
||||
rv = self.a[addr]
|
||||
rv |= self.a[addr+1] << 8
|
||||
rv |= self.a[addr+2] << 16
|
||||
rv |= self.a[addr+3] << 24
|
||||
self.addr += 4
|
||||
return rv
|
||||
|
||||
def u16(self):
|
||||
addr = self.addr
|
||||
rv = self.a[addr]
|
||||
rv |= self.a[addr+1] << 8
|
||||
self.addr += 2
|
||||
return rv
|
||||
|
||||
def u8(self):
|
||||
rv = self.a[self.addr]
|
||||
self.addr += 1
|
||||
return rv
|
||||
|
||||
def name(self):
|
||||
c = self.u16()
|
||||
|
||||
rv = u""
|
||||
for i in range(c):
|
||||
rv += unichr(self.u16())
|
||||
|
||||
return rv
|
||||
|
||||
def seek(self, addr):
|
||||
self.addr = addr
|
||||
|
||||
def tostring(self):
|
||||
return self.a.tostring()
|
||||
|
||||
def substring(self, start, len):
|
||||
return self.a[start:start+len].tostring()
|
||||
|
||||
def __init__(self, fn):
|
||||
data = open(fn, "rb").read()
|
||||
self.a = array.array('B')
|
||||
self.a.fromstring(data)
|
||||
|
||||
##############################################################################
|
||||
# These functions parse data out of the file. In these functions, offset is
|
||||
# relative to the start of the file.
|
||||
|
||||
# This parses a data block out of the resources.
|
||||
def parse_data(offset):
|
||||
pe.seek(RESOURCE_BASE + offset)
|
||||
data_offset = pe.u32()
|
||||
data_len = pe.u32()
|
||||
code_page = pe.u32()
|
||||
pe.u32()
|
||||
|
||||
l = [ ]
|
||||
|
||||
pe.seek(data_offset + RESOURCE_BASE - RESOURCE_VIRTUAL)
|
||||
for i in range(data_len):
|
||||
l.append(chr(pe.u8()))
|
||||
|
||||
return (code_page, "".join(l))
|
||||
|
||||
# This parses a resource directory.
|
||||
def parse_directory(offset):
|
||||
|
||||
pe.seek(RESOURCE_BASE + offset)
|
||||
char = pe.u32()
|
||||
timedate = pe.u32()
|
||||
major = pe.u16()
|
||||
minor = pe.u16()
|
||||
n_named = pe.u16()
|
||||
n_id = pe.u16()
|
||||
|
||||
entries = [ ]
|
||||
|
||||
for i in range(n_named + n_id):
|
||||
entries.append((pe.u32(), pe.u32()))
|
||||
|
||||
rv = { }
|
||||
|
||||
for name, value in entries:
|
||||
|
||||
if name & 0x80000000:
|
||||
pe.seek((name & 0x7fffffff) + RESOURCE_BASE)
|
||||
name = pe.name()
|
||||
|
||||
if value & 0x80000000:
|
||||
value = parse_directory(value & 0x7fffffff)
|
||||
else:
|
||||
value = parse_data(value)
|
||||
|
||||
rv[name] = value
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
##############################################################################
|
||||
# This utility function displays the tree of resources that have been loaded.
|
||||
def show_resources(d, prefix):
|
||||
|
||||
if not isinstance(d, dict):
|
||||
print prefix, "Codepage", d[0], "length", len(d[1])
|
||||
return
|
||||
|
||||
for k in d:
|
||||
print prefix, k
|
||||
show_resources(d[k], prefix + " ")
|
||||
|
||||
##############################################################################
|
||||
# These functions repack the resources into a new resource segment. Here,
|
||||
# the offset is relative to the start of the resource segment.
|
||||
|
||||
class Packer(object):
|
||||
|
||||
def pack(self, d):
|
||||
self.data = ""
|
||||
self.data_offset = 0
|
||||
|
||||
self.entries = ""
|
||||
self.entries_offset = 0
|
||||
|
||||
head = self.pack_dict(d, 0)
|
||||
|
||||
self.data = ""
|
||||
self.data_offset = len(head) + len(self.entries)
|
||||
|
||||
self.entries = ""
|
||||
self.entries_offset = len(head)
|
||||
|
||||
return self.pack_dict(d, 0) + self.entries + self.data
|
||||
|
||||
|
||||
|
||||
def pack_name(self, s):
|
||||
rv = self.data_offset + len(self.data)
|
||||
|
||||
l = len(s)
|
||||
s = s.encode("utf-16le")
|
||||
self.data += struct.pack("<H", l) + s + "\0\0"
|
||||
|
||||
return rv
|
||||
|
||||
def pack_tuple(self, t):
|
||||
codepage, data = t
|
||||
|
||||
rv = len(self.entries) + self.entries_offset
|
||||
|
||||
if len(self.data) % 2:
|
||||
self.data += "P"
|
||||
|
||||
daddr = len(self.data) + self.data_offset
|
||||
|
||||
self.entries += struct.pack("<IIII", daddr + RESOURCE_VIRTUAL, len(data), codepage, 0)
|
||||
self.data += data
|
||||
|
||||
# if len(self.data) % 1 == 1:
|
||||
# self.data += 'P'
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
|
||||
|
||||
def pack_dict(self, d, offset):
|
||||
name_entries = sorted((a, b) for a, b in d.iteritems() if isinstance(a, unicode))
|
||||
id_entries = sorted((a, b) for a, b in d.iteritems() if isinstance(a, int))
|
||||
|
||||
rv = struct.pack("<IIHHHH", 0, 0, 4, 0, len(name_entries), len(id_entries))
|
||||
|
||||
offset += len(rv) + (len(name_entries) + len(id_entries)) * 8
|
||||
|
||||
rest = ""
|
||||
|
||||
for (name, value) in name_entries + id_entries:
|
||||
if isinstance(name, unicode):
|
||||
name = 0x80000000 | self.pack_name(name)
|
||||
|
||||
if isinstance(value, dict):
|
||||
addr = offset | 0x80000000
|
||||
packed = self.pack_dict(value, offset)
|
||||
offset += len(packed)
|
||||
rest += packed
|
||||
else:
|
||||
addr = self.pack_tuple(value)
|
||||
|
||||
rv += struct.pack("<II", name, addr)
|
||||
|
||||
return rv + rest
|
||||
|
||||
##############################################################################
|
||||
# This loads in an icon file, and returns a dictionary that is suitable for
|
||||
# use in the resources of an exe file.
|
||||
def load_icon(fn):
|
||||
f = BinFile(fn)
|
||||
|
||||
f.seek(0)
|
||||
f.u16()
|
||||
f.u16()
|
||||
count = f.u16()
|
||||
|
||||
rv = { }
|
||||
rv[3] = { }
|
||||
|
||||
group = struct.pack("HHH", 0, 1, count)
|
||||
|
||||
for i in range(count):
|
||||
width = f.u8()
|
||||
height = f.u8()
|
||||
colors = f.u8()
|
||||
reserved = f.u8()
|
||||
planes = f.u16()
|
||||
bpp = f.u16()
|
||||
size = f.u32()
|
||||
offset = f.u32()
|
||||
|
||||
addr = f.addr
|
||||
f.seek(offset + 16)
|
||||
if not f.u32():
|
||||
f.set_u32(offset + 20, 0)
|
||||
|
||||
rv[3][i + 1] = { 0 : (1252, f.substring(offset, size)) }
|
||||
|
||||
|
||||
group += struct.pack("BBBBHHIH", width, height, colors, reserved,
|
||||
planes, bpp, size, i + 1)
|
||||
|
||||
f.seek(addr)
|
||||
|
||||
rv[14] = { 1 : { 0 : (1252, group) } }
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
##############################################################################
|
||||
# This is the main function that should be called externally, that copies over
|
||||
# the icons.
|
||||
def change_icons(oldexe, icofn):
|
||||
global pe
|
||||
pe = BinFile(oldexe)
|
||||
|
||||
# Check that RESOURCE_BASE and RESOURCE_VIRTUAL are still valid.
|
||||
pe.seek(CHECK_ADDRESS)
|
||||
if pe.u32() != RESOURCE_BASE:
|
||||
raise Exception("RESOURCE_BASE is no longer correct. Please check all relocations.")
|
||||
|
||||
pe.seek(CHECK_ADDRESS2)
|
||||
if pe.u32() != RESOURCE_VIRTUAL:
|
||||
raise Exception("RESOURCE_VIRTUAL is no longer correct. Please check all relocations.")
|
||||
|
||||
resources = parse_directory(0)
|
||||
# show_resources(resources, "")
|
||||
resources.update(load_icon(icofn))
|
||||
# show_resources(resources, "")
|
||||
|
||||
rsrc = Packer().pack(resources)
|
||||
rsrc_len = len(rsrc)
|
||||
|
||||
pe.seek(ALIGNMENT_FIELD)
|
||||
alignment = pe.u32()
|
||||
|
||||
if len(rsrc) % alignment:
|
||||
pad = alignment - (len(rsrc) % alignment)
|
||||
padding = "RENPYVNE" * (pad / 8 + 1)
|
||||
padding = padding[:pad]
|
||||
rsrc += padding
|
||||
|
||||
padded_len = len(rsrc)
|
||||
|
||||
for addr in RESOURCE_LENGTH_PATCHES:
|
||||
pe.set_u32(addr, rsrc_len)
|
||||
|
||||
for addr in RESOURCE_PADDED_PATCHES:
|
||||
pe.seek(addr)
|
||||
size_delta = padded_len - pe.u32()
|
||||
pe.set_u32(addr, padded_len)
|
||||
|
||||
for addr in SIZE_DELTA_PATCHES:
|
||||
pe.seek(addr)
|
||||
pe.set_u32(addr, pe.u32() + size_delta)
|
||||
|
||||
|
||||
return pe.tostring()[:RESOURCE_BASE] + rsrc
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
f = file(sys.argv[3], "wb")
|
||||
f.write(change_icons(sys.argv[1], sys.argv[2]))
|
||||
f.close()
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
init 1 python:
|
||||
theme_data = {'Basic Blue': {'disabled': '#404040',
|
||||
'disabled_text': '#c8c8c8',
|
||||
'frame': '#6496c8',
|
||||
'gm_root': '#dcebff',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#dcebff',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#003c78',
|
||||
'widget_hover': '#0050a0',
|
||||
'widget_selected': '#ffffc8',
|
||||
'widget_text': '#c8ffff'},
|
||||
'Bloody Mary': {'disabled': '#400000',
|
||||
'disabled_text': '#260000',
|
||||
'frame': '#400808',
|
||||
'gm_root': '#000000',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#000000',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#000000',
|
||||
'widget_hover': '#830000',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#C2C2C2'},
|
||||
'Colorblind': {'disabled': '#898989',
|
||||
'disabled_text': '#666666',
|
||||
'frame': '#252525',
|
||||
'gm_root': '#393939',
|
||||
'label': '#c2c2c2',
|
||||
'mm_root': '#393939',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#898989',
|
||||
'widget_hover': '#464646',
|
||||
'widget_selected': '#F2F2F2',
|
||||
'widget_text': '#CCCCCC'},
|
||||
'Cotton Candy': {'disabled': '#C8AFA1',
|
||||
'disabled_text': '#E1D4C9',
|
||||
'frame': '#FCF5F2',
|
||||
'gm_root': '#D0B4BA',
|
||||
'label': '#805C40',
|
||||
'mm_root': '#D0B4BA',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#ECC7D0',
|
||||
'widget_hover': '#E1D4C9',
|
||||
'widget_selected': '#805C40',
|
||||
'widget_text': '#805C40'},
|
||||
'Creamsicle': {'disabled': '#FFECBF',
|
||||
'disabled_text': '#ffffff',
|
||||
'frame': '#FFECBF',
|
||||
'gm_root': '#FDF5E3',
|
||||
'label': '#502F13',
|
||||
'mm_root': '#FDF5E3',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#D96B00',
|
||||
'widget_hover': '#FD9B1C',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#FCE6B1'},
|
||||
'Dramatic Flesh': {'disabled': '#ab6038',
|
||||
'disabled_text': '#BF7C51',
|
||||
'frame': '#49271b',
|
||||
'gm_root': '#2a201f',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#2a201f',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#BF7C51',
|
||||
'widget_hover': '#dda570',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#E5DFDF'},
|
||||
'Easter Baby': {'disabled': '#DDE9FF',
|
||||
'disabled_text': '#A6AFBF',
|
||||
'frame': '#CCF8DC',
|
||||
'gm_root': '#FBF9DF',
|
||||
'label': '#698071',
|
||||
'mm_root': '#FBF9DF',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#F5D4EE',
|
||||
'widget_hover': '#F0DDFF',
|
||||
'widget_selected': '#000000',
|
||||
'widget_text': '#698071'},
|
||||
'Favorite Jeans': {'disabled': '#919994',
|
||||
'disabled_text': '#B6BFB9',
|
||||
'frame': '#6f7571',
|
||||
'gm_root': '#b0b8ba',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#b0b8ba',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#8699a7',
|
||||
'widget_hover': '#9eb1ad',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#dcdfd6'},
|
||||
'Fine China': {'disabled': '#ADB9CC',
|
||||
'disabled_text': '#DFBA14',
|
||||
'frame': '#ADB9CC',
|
||||
'gm_root': '#F7F7FA',
|
||||
'label': '#39435E',
|
||||
'mm_root': '#F7F7FA',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#6A7183',
|
||||
'widget_hover': '#1A2B47',
|
||||
'widget_selected': '#E3E3E4',
|
||||
'widget_text': '#C9C9CB'},
|
||||
'First Valentines': {'disabled': '#F8F2D0',
|
||||
'disabled_text': '#BFA1A1',
|
||||
'frame': '#F8F2D0',
|
||||
'gm_root': '#D98989',
|
||||
'label': '#5D1010',
|
||||
'mm_root': '#D98989',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#F09898',
|
||||
'widget_hover': '#D6C5BB',
|
||||
'widget_selected': '#B31E1E',
|
||||
'widget_text': '#593131'},
|
||||
'Ice Queen': {'disabled': '#F0F2F2',
|
||||
'disabled_text': '#FBFBFB',
|
||||
'frame': '#ffffff',
|
||||
'gm_root': '#E6E6E6',
|
||||
'label': '#D9D9D9',
|
||||
'mm_root': '#E6E6E6',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#D9D9D9',
|
||||
'widget_hover': '#F0F2F2',
|
||||
'widget_selected': '#737373',
|
||||
'widget_text': '#ffffff'},
|
||||
'Mocha Latte': {'disabled': '#614D3A',
|
||||
'disabled_text': '#80654D',
|
||||
'frame': '#926841',
|
||||
'gm_root': '#1A140E',
|
||||
'label': '#F1EBE5',
|
||||
'mm_root': '#1A140E',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#4D3B29',
|
||||
'widget_hover': '#996E45',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#B99D83'},
|
||||
'Muted Horror': {'disabled': '#73735C',
|
||||
'disabled_text': '#8C8C70',
|
||||
'frame': '#555544',
|
||||
'gm_root': '#1A0001',
|
||||
'label': '#1A0001',
|
||||
'mm_root': '#1A0001',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#777777',
|
||||
'widget_hover': '#73735C',
|
||||
'widget_selected': '#000000',
|
||||
'widget_text': '#404033'},
|
||||
'Old Polaroid': {'disabled': '#A89E7D',
|
||||
'disabled_text': '#CCC097',
|
||||
'frame': '#49403E',
|
||||
'gm_root': '#A84A3E',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#A84A3E',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#A89E7D',
|
||||
'widget_hover': '#8DB6B9',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#49403E'},
|
||||
'Really Red': {'disabled': '#404040',
|
||||
'disabled_text': '#c8c8c8',
|
||||
'frame': '#e17373',
|
||||
'gm_root': '#ffd0d0',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#ffd0d0',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#963232',
|
||||
'widget_hover': '#c83232',
|
||||
'widget_selected': '#ffffc8',
|
||||
'widget_text': '#ffffff'},
|
||||
'Summer Sky': {'disabled': '#6074BF',
|
||||
'disabled_text': '#7383BF',
|
||||
'frame': '#6074BF',
|
||||
'gm_root': '#B4CDD4',
|
||||
'label': '#94C7D4',
|
||||
'mm_root': '#B4CDD4',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#F2E6AA',
|
||||
'widget_hover': '#FCFCA4',
|
||||
'widget_selected': '#1A5766',
|
||||
'widget_text': '#7DA8B3'},
|
||||
'Swamp Critter': {'disabled': '#A2521D',
|
||||
'disabled_text': '#753D00',
|
||||
'frame': '#797C1C',
|
||||
'gm_root': '#B09D5A',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#B09B4F',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#753D00',
|
||||
'widget_hover': '#B19A48',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#CCCAC2'},
|
||||
'Urban Sprawl': {'disabled': '#8F0000',
|
||||
'disabled_text': '#333333',
|
||||
'frame': '#8F0000',
|
||||
'gm_root': '#000000',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#000000',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#333333',
|
||||
'widget_hover': '#000000',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#6C8A2F'},
|
||||
'Victorian Gingerbread': {'disabled': '#7A674F',
|
||||
'disabled_text': '#664F33',
|
||||
'frame': '#BF8A73',
|
||||
'gm_root': '#695640',
|
||||
'label': '#F2EDC4',
|
||||
'mm_root': '#695640',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#7A674F',
|
||||
'widget_hover': '#BDA77D',
|
||||
'widget_selected': '#FDFBEE',
|
||||
'widget_text': '#F2EDC4'},
|
||||
'Watermelon Pie': {'disabled': '#FABF46',
|
||||
'disabled_text': '#FFE06D',
|
||||
'frame': '#C3CD91',
|
||||
'gm_root': '#F7F7C5',
|
||||
'label': '#FCFCD7',
|
||||
'mm_root': '#F7F7C5',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#FFE06D',
|
||||
'widget_hover': '#E38A4F',
|
||||
'widget_selected': '#996600',
|
||||
'widget_text': '#FAA700'},
|
||||
'White Chocolate': {'disabled': '#614D3A',
|
||||
'disabled_text': '#80654D',
|
||||
'frame': '#926841',
|
||||
'gm_root': '#FBF9EA',
|
||||
'label': '#F1EBE5',
|
||||
'mm_root': '#FBF9EA',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#33271C',
|
||||
'widget_hover': '#ECE7C4',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#B99D83'},
|
||||
'Winter Mint': {'disabled': '#426143',
|
||||
'disabled_text': '#819981',
|
||||
'frame': '#245536',
|
||||
'gm_root': '#e5f1e5',
|
||||
'label': '#ffffff',
|
||||
'mm_root': '#e5f1e5',
|
||||
'theme': 'roundrect',
|
||||
'widget': '#7AA27B',
|
||||
'widget_hover': '#A3C7A3',
|
||||
'widget_selected': '#ffffff',
|
||||
'widget_text': '#CDE0CE'}}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
sys.path.append('/home/tom/ab/keys/')
|
||||
|
||||
import os
|
||||
import bz2
|
||||
import hashlib
|
||||
import public
|
||||
import private
|
||||
import shutil
|
||||
|
||||
def sha(s):
|
||||
"""
|
||||
Hashes s into a string.
|
||||
"""
|
||||
|
||||
hash = hashlib.sha256()
|
||||
hash.update(s)
|
||||
return hash.hexdigest()
|
||||
|
||||
|
||||
def make_update(root, version):
|
||||
|
||||
# A list of command strings.
|
||||
commands = [ ]
|
||||
|
||||
for dir, dirs, files in os.walk(root):
|
||||
for fn in files:
|
||||
fn = os.path.join(dir, fn)
|
||||
|
||||
oldf = file(fn, "rb")
|
||||
bzf = bz2.BZ2File(fn + ".bz2", "wb")
|
||||
bzf.write(oldf.read())
|
||||
bzf.close()
|
||||
oldf.close()
|
||||
|
||||
shutil.copymode(fn, fn + ".bz2")
|
||||
os.unlink(fn)
|
||||
|
||||
for dir, dirs, files in os.walk(root):
|
||||
|
||||
for fn in dirs + files:
|
||||
|
||||
path = os.path.join(dir, fn)
|
||||
relpath = os.path.relpath(path, root)
|
||||
|
||||
if relpath in [ "version", "catalog1.bz2" ]:
|
||||
continue
|
||||
|
||||
if os.path.isdir(path):
|
||||
commands.append(('dir', "base", relpath))
|
||||
|
||||
elif relpath.endswith(".rpyc.bz2"):
|
||||
continue
|
||||
elif relpath.endswith(".rpymc.bz2"):
|
||||
continue
|
||||
elif relpath.endswith(".rpyb.bz2"):
|
||||
continue
|
||||
|
||||
elif relpath.endswith(".pyo.bz2"):
|
||||
continue
|
||||
|
||||
elif relpath.endswith(".bz2"):
|
||||
|
||||
hash = sha(bz2.BZ2File(path, "r").read())
|
||||
size = "%d" % (os.path.getsize(path))
|
||||
|
||||
commands.append(('file', hash, size, "base", relpath[:-4]))
|
||||
|
||||
if os.access(path, os.X_OK):
|
||||
commands.append(('xbit', relpath[:-4]))
|
||||
|
||||
|
||||
out = bz2.BZ2File(os.path.join(root, "catalog1.bz2"), "w")
|
||||
hash = hashlib.sha256()
|
||||
|
||||
for i in commands:
|
||||
|
||||
line = "\t".join(i) + "\n"
|
||||
hash.update(line)
|
||||
out.write(line)
|
||||
|
||||
unsigned = int("01" + hash.hexdigest(), 16)
|
||||
signed = pow(unsigned, private.exponent, public.modulus)
|
||||
|
||||
out.write("-\n")
|
||||
out.write("signature\t%x\n" % signed)
|
||||
out.close()
|
||||
|
||||
f = file(os.path.join(root, "version"), "w")
|
||||
f.write(version)
|
||||
f.write("\n")
|
||||
f.write("the latest Ren'Py pre-release")
|
||||
f.close()
|
||||
|
||||
@@ -105,11 +105,13 @@ def premultiply(
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h):
|
||||
int h,
|
||||
border_left, border_top, border_right, border_bottom):
|
||||
|
||||
"""
|
||||
Creates a string containing the premultiplied image data for
|
||||
for the (x, y, w, h) box inside pysurf.
|
||||
for the (x, y, w, h) box inside pysurf. The various border_
|
||||
parameters control the addition of a border on the sides.
|
||||
"""
|
||||
|
||||
# Adjust the alpha if we have an alpha-free image.
|
||||
@@ -145,8 +147,10 @@ def premultiply(
|
||||
|
||||
# alpha value.
|
||||
cdef unsigned int a
|
||||
|
||||
|
||||
|
||||
# pixel pointer.
|
||||
cdef unsigned int *pp
|
||||
|
||||
surf = PySurface_AsSurface(pysurf)
|
||||
pixels = <unsigned char *> surf.pixels
|
||||
|
||||
@@ -170,10 +174,42 @@ def premultiply(
|
||||
p += 4
|
||||
op += 4
|
||||
|
||||
if border_left:
|
||||
pp = <unsigned int *> (out)
|
||||
|
||||
for y from 0 <= y < h:
|
||||
pp[0] = pp[1]
|
||||
pp += w
|
||||
|
||||
if border_right:
|
||||
pp = <unsigned int *> (out)
|
||||
pp += w - 2
|
||||
|
||||
for y from 0 <= y < h:
|
||||
pp[1] = pp[0]
|
||||
pp += w
|
||||
|
||||
if border_top:
|
||||
pp = <unsigned int *> (out)
|
||||
|
||||
for x from 0 <= x < w:
|
||||
pp[0] = pp[w]
|
||||
pp += 1
|
||||
|
||||
if border_top:
|
||||
pp = <unsigned int *> (out)
|
||||
pp += (y - 2) * w
|
||||
|
||||
for x from 0 <= x < w:
|
||||
pp[w] = pp[0]
|
||||
pp += 1
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
def load_premultiplied(data, width, height, update):
|
||||
def load_premultiplied(
|
||||
data, width, height, update, format,
|
||||
):
|
||||
|
||||
cdef char *pixels
|
||||
|
||||
@@ -191,7 +227,7 @@ def load_premultiplied(data, width, height, update):
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
GL_BGRA,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixels)
|
||||
|
||||
@@ -203,13 +239,14 @@ def load_premultiplied(data, width, height, update):
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_BGRA,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixels)
|
||||
|
||||
|
||||
def store_framebuffer(
|
||||
object pysurf,
|
||||
int format,
|
||||
):
|
||||
|
||||
"""
|
||||
@@ -231,7 +268,7 @@ def store_framebuffer(
|
||||
0,
|
||||
surf.w,
|
||||
surf.h,
|
||||
GL_BGRA,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixels)
|
||||
|
||||
@@ -246,7 +283,8 @@ def draw_rectangle(
|
||||
transform,
|
||||
tex0, int tex0x, int tex0y,
|
||||
tex1, int tex1x, int tex1y,
|
||||
tex2, int tex2x, int tex2y):
|
||||
tex2, int tex2x, int tex2y,
|
||||
):
|
||||
|
||||
"""
|
||||
This draws a rectangle (textured with up to four textures) to the
|
||||
|
||||
@@ -85,7 +85,9 @@ typedef struct PacketQueue {
|
||||
|
||||
typedef struct VideoPicture {
|
||||
double pts; ///<presentation time stamp for this picture
|
||||
SDL_Overlay *bmp;
|
||||
SDL_Surface *surf;
|
||||
AVFrame *frame;
|
||||
int fmt;
|
||||
int width, height; /* source height & width */
|
||||
int allocated;
|
||||
} VideoPicture;
|
||||
@@ -684,15 +686,19 @@ static void free_subpicture(SubPicture *sp)
|
||||
static void video_image_display(VideoState *is)
|
||||
{
|
||||
VideoPicture *vp;
|
||||
#if 0
|
||||
SubPicture *sp;
|
||||
#endif
|
||||
|
||||
AVPicture pict;
|
||||
float aspect_ratio;
|
||||
int width, height, x, y;
|
||||
SDL_Rect rect;
|
||||
int i;
|
||||
|
||||
static struct SwsContext *img_convert_ctx;
|
||||
|
||||
vp = &is->pictq[is->pictq_rindex];
|
||||
if (vp->bmp) {
|
||||
if (vp->surf) {
|
||||
/* XXX: use variable in the frame */
|
||||
if (is->video_st->sample_aspect_ratio.num)
|
||||
aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
|
||||
@@ -738,6 +744,7 @@ static void video_image_display(VideoState *is)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (is->subtitle_st)
|
||||
{
|
||||
if (is->subpq_size > 0)
|
||||
@@ -764,35 +771,60 @@ static void video_image_display(VideoState *is)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* XXX: we suppose the screen has a 1.0 pixel ratio */
|
||||
height = is->height;
|
||||
width = ((int)rint(height * aspect_ratio)) & ~1;
|
||||
|
||||
if (width > is->width) {
|
||||
width = is->width;
|
||||
height = ((int)rint(width / aspect_ratio)) & ~1;
|
||||
}
|
||||
|
||||
x = (is->width - width) / 2;
|
||||
y = (is->height - height) / 2;
|
||||
|
||||
if (!is->no_background) {
|
||||
/* fill the background */
|
||||
// fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));
|
||||
} else {
|
||||
is->no_background = 0;
|
||||
}
|
||||
|
||||
rect.x = is->xleft + x;
|
||||
rect.y = is->ytop + y;
|
||||
rect.w = width;
|
||||
rect.h = height;
|
||||
|
||||
SDL_DisplayYUVOverlay(vp->bmp, &rect);
|
||||
img_convert_ctx = sws_getCachedContext(
|
||||
img_convert_ctx,
|
||||
is->video_st->codec->width,
|
||||
is->video_st->codec->height,
|
||||
is->video_st->codec->pix_fmt,
|
||||
rect.w,
|
||||
rect.h,
|
||||
vp->fmt, //dst_pix_fmt,
|
||||
sws_flags,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (img_convert_ctx != NULL) {
|
||||
|
||||
pict.data[0] = &((uint8_t *)vp->surf->pixels)[rect.y * vp->surf->pitch + rect.x * 4];
|
||||
pict.linesize[0] = vp->surf->pitch;
|
||||
|
||||
sws_scale(
|
||||
img_convert_ctx,
|
||||
(const uint8_t * const *) vp->frame->data,
|
||||
vp->frame->linesize,
|
||||
0,
|
||||
is->video_st->codec->height,
|
||||
pict.data,
|
||||
pict.linesize);
|
||||
}
|
||||
|
||||
} else {
|
||||
#if 0
|
||||
fill_rectangle(screen,
|
||||
is->xleft, is->ytop, is->width, is->height,
|
||||
QERGB(0x00, 0x00, 0x00));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -970,8 +1002,10 @@ static void video_refresh_timer(void *opaque)
|
||||
VideoState *is = opaque;
|
||||
VideoPicture *vp;
|
||||
|
||||
#if 0
|
||||
SubPicture *sp, *sp2;
|
||||
|
||||
#endif
|
||||
|
||||
double delay;
|
||||
|
||||
if (is->video_st) {
|
||||
@@ -1039,7 +1073,10 @@ static void video_refresh_timer(void *opaque)
|
||||
if (delay > 0.010) {
|
||||
video_display(is);
|
||||
}
|
||||
|
||||
|
||||
av_free(vp->frame);
|
||||
vp->frame = NULL;
|
||||
|
||||
/* update queue size and signal for next picture */
|
||||
if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
|
||||
is->pictq_rindex = 0;
|
||||
@@ -1085,9 +1122,11 @@ static void alloc_picture(void *opaque, PyObject *pysurf)
|
||||
{
|
||||
VideoState *is = opaque;
|
||||
VideoPicture *vp;
|
||||
|
||||
SDL_Surface *surf;
|
||||
|
||||
uint32_t pixel;
|
||||
uint8_t *bytes = (uint8_t *) &pixel;
|
||||
|
||||
if (!is->needs_alloc) {
|
||||
return;
|
||||
}
|
||||
@@ -1097,39 +1136,26 @@ static void alloc_picture(void *opaque, PyObject *pysurf)
|
||||
surf = PySurface_AsSurface(pysurf);
|
||||
is->width = surf->w;
|
||||
is->height = surf->h;
|
||||
|
||||
|
||||
vp = &is->pictq[is->pictq_windex];
|
||||
|
||||
if (vp->bmp)
|
||||
SDL_FreeYUVOverlay(vp->bmp);
|
||||
|
||||
#if 0
|
||||
/* XXX: use generic function */
|
||||
/* XXX: disable overlay if no hardware acceleration or if RGB format */
|
||||
switch(is->video_st->codec->pix_fmt) {
|
||||
case PIX_FMT_YUV420P:
|
||||
case PIX_FMT_YUV422P:
|
||||
case PIX_FMT_YUV444P:
|
||||
case PIX_FMT_YUYV422:
|
||||
case PIX_FMT_YUV410P:
|
||||
case PIX_FMT_YUV411P:
|
||||
is_yuv = 1;
|
||||
break;
|
||||
default:
|
||||
is_yuv = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
vp->bmp = SDL_CreateYUVOverlay(
|
||||
is->video_st->codec->width,
|
||||
is->video_st->codec->height,
|
||||
SDL_YV12_OVERLAY,
|
||||
surf);
|
||||
|
||||
vp->surf = surf;
|
||||
vp->width = is->video_st->codec->width;
|
||||
vp->height = is->video_st->codec->height;
|
||||
|
||||
pixel = SDL_MapRGBA(surf->format, 1, 2, 3, 4);
|
||||
if (bytes[0] == 4 && bytes[1] == 1) {
|
||||
vp->fmt = PIX_FMT_ARGB;
|
||||
} else if (bytes[0] == 4 && bytes[1] == 3) {
|
||||
vp->fmt = PIX_FMT_ABGR;
|
||||
} else if (bytes[0] == 1) {
|
||||
vp->fmt = PIX_FMT_RGBA;
|
||||
} else {
|
||||
vp->fmt = PIX_FMT_BGRA;
|
||||
}
|
||||
|
||||
pixel = SDL_MapRGBA(surf->format, 0, 0, 0, 255);
|
||||
SDL_FillRect(surf, NULL, pixel);
|
||||
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
vp->allocated = 1;
|
||||
SDL_CondSignal(is->pictq_cond);
|
||||
@@ -1143,10 +1169,13 @@ static void alloc_picture(void *opaque, PyObject *pysurf)
|
||||
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
|
||||
{
|
||||
VideoPicture *vp;
|
||||
|
||||
#if 0
|
||||
int dst_pix_fmt;
|
||||
AVPicture pict;
|
||||
static struct SwsContext *img_convert_ctx;
|
||||
|
||||
#endif
|
||||
|
||||
/* wait until we have space to put a new picture */
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
|
||||
@@ -1161,13 +1190,12 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
|
||||
vp = &is->pictq[is->pictq_windex];
|
||||
|
||||
/* alloc or resize hardware picture buffer */
|
||||
if (!vp->bmp ||
|
||||
if (!vp->surf ||
|
||||
vp->width != is->video_st->codec->width ||
|
||||
vp->height != is->video_st->codec->height) {
|
||||
SDL_Event event;
|
||||
|
||||
vp->allocated = 0;
|
||||
|
||||
is->needs_alloc = 1;
|
||||
|
||||
/* the allocation must be done in the main thread to avoid
|
||||
@@ -1175,7 +1203,6 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
|
||||
event.type = FF_ALLOC_EVENT;
|
||||
event.user.data1 = is;
|
||||
SDL_PushEvent(&event);
|
||||
|
||||
|
||||
/* wait until the picture is allocated */
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
@@ -1188,42 +1215,47 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if the frame is not skipped, then display it */
|
||||
if (vp->bmp) {
|
||||
/* get a pointer on the bitmap */
|
||||
SDL_LockYUVOverlay (vp->bmp);
|
||||
vp->frame = src_frame;
|
||||
vp->pts = pts;
|
||||
|
||||
dst_pix_fmt = PIX_FMT_YUV420P;
|
||||
pict.data[0] = vp->bmp->pixels[0];
|
||||
pict.data[1] = vp->bmp->pixels[2];
|
||||
pict.data[2] = vp->bmp->pixels[1];
|
||||
|
||||
pict.linesize[0] = vp->bmp->pitches[0];
|
||||
pict.linesize[1] = vp->bmp->pitches[2];
|
||||
pict.linesize[2] = vp->bmp->pitches[1];
|
||||
// sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
|
||||
img_convert_ctx = sws_getCachedContext(img_convert_ctx,
|
||||
is->video_st->codec->width, is->video_st->codec->height,
|
||||
is->video_st->codec->pix_fmt,
|
||||
is->video_st->codec->width, is->video_st->codec->height,
|
||||
dst_pix_fmt, sws_flags, NULL, NULL, NULL);
|
||||
if (img_convert_ctx == NULL) {
|
||||
fprintf(stderr, "Cannot initialize the conversion context\n");
|
||||
}
|
||||
sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
|
||||
0, is->video_st->codec->height, pict.data, pict.linesize);
|
||||
/* update the bitmap content */
|
||||
SDL_UnlockYUVOverlay(vp->bmp);
|
||||
/* now we can update the picture count */
|
||||
if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
|
||||
is->pictq_windex = 0;
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
is->pictq_size++;
|
||||
SDL_UnlockMutex(is->pictq_mutex);
|
||||
|
||||
/* /\* if the frame is not skipped, then display it *\/ */
|
||||
/* if (vp->bmp) { */
|
||||
/* /\* get a pointer on the bitmap *\/ */
|
||||
/* SDL_LockYUVOverlay (vp->bmp); */
|
||||
|
||||
vp->pts = pts;
|
||||
/* dst_pix_fmt = PIX_FMT_YUV420P; */
|
||||
/* pict.data[0] = vp->bmp->pixels[0]; */
|
||||
/* pict.data[1] = vp->bmp->pixels[2]; */
|
||||
/* pict.data[2] = vp->bmp->pixels[1]; */
|
||||
|
||||
/* now we can update the picture count */
|
||||
if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
|
||||
is->pictq_windex = 0;
|
||||
SDL_LockMutex(is->pictq_mutex);
|
||||
is->pictq_size++;
|
||||
SDL_UnlockMutex(is->pictq_mutex);
|
||||
}
|
||||
/* pict.linesize[0] = vp->bmp->pitches[0]; */
|
||||
/* pict.linesize[1] = vp->bmp->pitches[2]; */
|
||||
/* pict.linesize[2] = vp->bmp->pitches[1]; */
|
||||
/* // sws_flags = av_get_int(sws_opts, "sws_flags", NULL); */
|
||||
/* img_convert_ctx = sws_getCachedContext(img_convert_ctx, */
|
||||
/* is->video_st->codec->width, is->video_st->codec->height, */
|
||||
/* is->video_st->codec->pix_fmt, */
|
||||
/* is->video_st->codec->width, is->video_st->codec->height, */
|
||||
/* dst_pix_fmt, sws_flags, NULL, NULL, NULL); */
|
||||
/* if (img_convert_ctx == NULL) { */
|
||||
/* fprintf(stderr, "Cannot initialize the conversion context\n"); */
|
||||
/* } */
|
||||
/* sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize, */
|
||||
/* 0, is->video_st->codec->height, pict.data, pict.linesize); */
|
||||
/* /\* update the bitmap content *\/ */
|
||||
/* SDL_UnlockYUVOverlay(vp->bmp); */
|
||||
|
||||
/* vp->pts = pts; */
|
||||
|
||||
/* } */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1271,10 +1303,12 @@ static int video_thread(void *arg)
|
||||
VideoState *is = arg;
|
||||
AVPacket pkt1, *pkt = &pkt1;
|
||||
int len1, got_picture;
|
||||
AVFrame *frame= avcodec_alloc_frame();
|
||||
AVFrame *frame;
|
||||
double pts;
|
||||
|
||||
for(;;) {
|
||||
frame = avcodec_alloc_frame();
|
||||
|
||||
while (is->paused && !is->videoq.abort_request) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
@@ -1311,7 +1345,6 @@ static int video_thread(void *arg)
|
||||
av_free_packet(pkt);
|
||||
}
|
||||
the_end:
|
||||
av_free(frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2268,11 +2301,10 @@ void ffpy_stream_close(VideoState *is)
|
||||
SDL_WaitThread(is->parse_tid, NULL);
|
||||
|
||||
/* free all pictures */
|
||||
for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
|
||||
for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
|
||||
vp = &is->pictq[i];
|
||||
if (vp->bmp) {
|
||||
SDL_FreeYUVOverlay(vp->bmp);
|
||||
vp->bmp = NULL;
|
||||
if (vp->frame) {
|
||||
av_free(vp->frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
dist/msvcr90.dll
|
||||
@@ -1 +0,0 @@
|
||||
dist/python26.dll
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -Rf spline_editor/*~
|
||||
rm -Rf spline_editor/game/*~
|
||||
rm -Rf spline_editor/game/*.rpyc
|
||||
rm -Rf spline_editor/game/*.rpyb
|
||||
rm -Rf spline_editor/game/saves
|
||||
|
||||
rm spline_editor.zip
|
||||
zip -9r spline_editor.zip spline_editor -x \*.svn\*
|
||||
|
||||
|
||||
|
||||
@@ -1,877 +0,0 @@
|
||||
# Ren'Py Visual Novel Engine
|
||||
# Copyright (C) 2009 PyTom <pytom@bishoujo.us>
|
||||
# This file is distributed under the same license as the Ren'Py package.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mainline\n"
|
||||
"Report-Msgid-Bugs-To: PyTom <pytom@bishoujo.us>\n"
|
||||
"POT-Creation-Date: 2009-06-27 23:09-0400\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
|
||||
#: common/00developer.rpy:18
|
||||
#, python-format
|
||||
msgid "Developer Menu"
|
||||
msgstr ""
|
||||
|
||||
#: common/00developer.rpy:190 common/00developer.rpy:78
|
||||
#, python-format
|
||||
msgid "Return to the developer menu"
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:221
|
||||
#, python-format
|
||||
msgid "Skip Mode"
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:224
|
||||
#, python-format
|
||||
msgid "Fast Skip Mode"
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:307
|
||||
#, python-format
|
||||
msgid "While Ren'Py games may be playable without the renpy module, some features may be disabled. For more information, read the module/README.txt file or go to http://www.bishoujo.us/renpy/."
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:310
|
||||
#, python-format
|
||||
msgid "renpy module not found."
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:311
|
||||
#, python-format
|
||||
msgid "The renpy module could not be loaded on your system."
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:313
|
||||
#, python-format
|
||||
msgid "Old renpy module found."
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:314
|
||||
#, python-format
|
||||
msgid "An old version (%d) of the Ren'Py module was found on your system, while this game requires version %d."
|
||||
msgstr ""
|
||||
|
||||
#: common/00library.rpy:498
|
||||
#, python-format
|
||||
msgid "Please click to continue."
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:14 common/_compat/mainmenu.rpym:7
|
||||
#, python-format
|
||||
msgid "Start Game"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:15 common/00menus.rpy:25 common/_compat/gamemenu.rpym:13
|
||||
#, python-format
|
||||
msgid "Load Game"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:16 common/00menus.rpy:23 common/_compat/gamemenu.rpym:11 common/_compat/mainmenu.rpym:9
|
||||
#, python-format
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:17 common/00menus.rpy:27
|
||||
#, python-format
|
||||
msgid "Help"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:18 common/00menus.rpy:28 common/_compat/gamemenu.rpym:15 common/_compat/mainmenu.rpym:10
|
||||
#, python-format
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:22 common/_compat/gamemenu.rpym:9 launcher2/archiver.rpy:170 launcher2/distribute.rpy:534 launcher2/interface.rpy:189
|
||||
#, python-format
|
||||
msgid "Return"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:24 common/_compat/gamemenu.rpym:12
|
||||
#, python-format
|
||||
msgid "Save Game"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:26 common/_compat/gamemenu.rpym:14
|
||||
#, python-format
|
||||
msgid "Main Menu"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:34 common/_compat/gamemenu.rpym:427
|
||||
#, python-format
|
||||
msgid "Are you sure you want to quit?"
|
||||
msgstr ""
|
||||
|
||||
#: common/00menus.rpy:40 common/_compat/gamemenu.rpym:439
|
||||
#, python-format
|
||||
msgid "Are you sure you want to return to the main menu?\nThis will lose unsaved progress."
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:10 common/_layout/classic_preferences.rpym:65 common/_layout/classic_preferences_common.rpym:339 common/_layout/one_column_preferences.rpym:52 common/_layout/two_column_preferences.rpym:59
|
||||
#, python-format
|
||||
msgid "Begin Skipping"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:177 common/_layout/classic_load_save.rpym:115 common/_layout/imagemap_load_save.rpym:95 common/_layout/scrolling_load_save.rpym:171
|
||||
#, python-format
|
||||
msgid "Empty Slot."
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:334 common/_layout/classic_load_save.rpym:250
|
||||
#, python-format
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:341 common/_layout/classic_load_save.rpym:257
|
||||
#, python-format
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:412 common/_layout/classic_yesno_prompt.rpym:46 launcher2/interface.rpy:223
|
||||
#, python-format
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:413 common/_layout/classic_yesno_prompt.rpym:47 launcher2/interface.rpy:224
|
||||
#, python-format
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:464 common/_layout/classic_load_save.rpym:328 common/_layout/imagemap_load_save.rpym:325 common/_layout/scrolling_load_save.rpym:214
|
||||
#, python-format
|
||||
msgid "Loading will lose unsaved progress.\nAre you sure you want to do this?"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:478 common/_layout/classic_load_save.rpym:314 common/_layout/imagemap_load_save.rpym:312 common/_layout/scrolling_load_save.rpym:200
|
||||
#, python-format
|
||||
msgid "Are you sure you want to overwrite your save?"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:494
|
||||
#, python-format
|
||||
msgid "The error message was:"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:496
|
||||
#, python-format
|
||||
msgid "You may want to try saving in a different slot, or playing for a while and trying again later."
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/gamemenu.rpym:498
|
||||
#, python-format
|
||||
msgid "Save Failed."
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/mainmenu.rpym:8
|
||||
#, python-format
|
||||
msgid "Continue Game"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:225 common/_layout/classic_preferences_common.rpym:179 common/_layout/classic_preferences_common.rpym:190 launcher2/choose_theme.rpy:228
|
||||
#, python-format
|
||||
msgid "Test"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:34 common/_layout/classic_joystick_preferences.rpym:32
|
||||
#, python-format
|
||||
msgid "Left"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:35 common/_layout/classic_joystick_preferences.rpym:33
|
||||
#, python-format
|
||||
msgid "Right"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:36 common/_layout/classic_joystick_preferences.rpym:34
|
||||
#, python-format
|
||||
msgid "Up"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:37 common/_layout/classic_joystick_preferences.rpym:35
|
||||
#, python-format
|
||||
msgid "Down"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:377 common/_compat/preferences.rpym:428 common/_layout/classic_joystick_preferences.rpym:51 common/_layout/classic_joystick_preferences.rpym:93
|
||||
#, python-format
|
||||
msgid "Not Assigned"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:38 common/_layout/classic_joystick_preferences.rpym:36
|
||||
#, python-format
|
||||
msgid "Select/Dismiss"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:39 common/_layout/classic_joystick_preferences.rpym:37
|
||||
#, python-format
|
||||
msgid "Rollback"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:40 common/_layout/classic_joystick_preferences.rpym:38
|
||||
#, python-format
|
||||
msgid "Hold to Skip"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:408 common/_layout/classic_joystick_preferences.rpym:73
|
||||
#, python-format
|
||||
msgid "Joystick Mapping"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:409 common/_layout/classic_joystick_preferences.rpym:74
|
||||
#, python-format
|
||||
msgid "Move the joystick or press a joystick button to create the mapping. Click the mouse to remove the mapping."
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:41 common/_layout/classic_joystick_preferences.rpym:39
|
||||
#, python-format
|
||||
msgid "Toggle Skip"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:42 common/_layout/classic_joystick_preferences.rpym:40
|
||||
#, python-format
|
||||
msgid "Hide Text"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:43 common/_layout/classic_joystick_preferences.rpym:41
|
||||
#, python-format
|
||||
msgid "Menu"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:482 common/_compat/preferences.rpym:557 common/_layout/classic_preferences.rpym:57 common/_layout/classic_preferences_common.rpym:321 common/_layout/one_column_preferences.rpym:49 common/_layout/two_column_preferences.rpym:56 launcher2/choose_theme.rpy:208
|
||||
#, python-format
|
||||
msgid "Display"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:483 common/_layout/classic_preferences_common.rpym:322 launcher2/choose_theme.rpy:209
|
||||
#, python-format
|
||||
msgid "Window"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:484 common/_layout/classic_preferences_common.rpym:323 launcher2/choose_theme.rpy:210
|
||||
#, python-format
|
||||
msgid "Fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:487 common/_compat/preferences.rpym:558 common/_layout/classic_preferences.rpym:58 common/_layout/classic_preferences_common.rpym:326 common/_layout/one_column_preferences.rpym:50 common/_layout/two_column_preferences.rpym:57
|
||||
#, python-format
|
||||
msgid "Transitions"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:488 common/_layout/classic_preferences_common.rpym:327
|
||||
#, python-format
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:489 common/_layout/classic_preferences_common.rpym:328
|
||||
#, python-format
|
||||
msgid "Some"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:490 common/_layout/classic_preferences_common.rpym:329
|
||||
#, python-format
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:495 common/_compat/preferences.rpym:563 common/_layout/classic_preferences.rpym:64 common/_layout/classic_preferences_common.rpym:334 common/_layout/one_column_preferences.rpym:51 common/_layout/two_column_preferences.rpym:58
|
||||
#, python-format
|
||||
msgid "Skip"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:496 common/_layout/classic_preferences_common.rpym:335
|
||||
#, python-format
|
||||
msgid "Seen Messages"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:497 common/_layout/classic_preferences_common.rpym:336
|
||||
#, python-format
|
||||
msgid "All Messages"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:504 common/_compat/preferences.rpym:564 common/_layout/classic_preferences.rpym:66 common/_layout/classic_preferences_common.rpym:345 common/_layout/one_column_preferences.rpym:53 common/_layout/two_column_preferences.rpym:60
|
||||
#, python-format
|
||||
msgid "After Choices"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:505 common/_layout/classic_preferences_common.rpym:346
|
||||
#, python-format
|
||||
msgid "Stop Skipping"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:506 common/_layout/classic_preferences_common.rpym:347
|
||||
#, python-format
|
||||
msgid "Keep Skipping"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:526 common/_compat/preferences.rpym:565 common/_layout/classic_preferences.rpym:59 common/_layout/classic_preferences_common.rpym:352 common/_layout/one_column_preferences.rpym:54 common/_layout/two_column_preferences.rpym:61
|
||||
#, python-format
|
||||
msgid "Text Speed"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:544 common/_compat/preferences.rpym:566 common/_layout/classic_preferences.rpym:67 common/_layout/classic_preferences_common.rpym:353 common/_layout/one_column_preferences.rpym:55 common/_layout/two_column_preferences.rpym:62
|
||||
#, python-format
|
||||
msgid "Auto-Forward Time"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:549 common/_compat/preferences.rpym:570 common/_layout/classic_preferences.rpym:71 common/_layout/classic_preferences_common.rpym:357 common/_layout/one_column_preferences.rpym:56 common/_layout/two_column_preferences.rpym:66
|
||||
#, python-format
|
||||
msgid "Music Volume"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:550 common/_compat/preferences.rpym:571 common/_layout/classic_preferences.rpym:72 common/_layout/classic_preferences_common.rpym:360 common/_layout/one_column_preferences.rpym:57 common/_layout/two_column_preferences.rpym:67
|
||||
#, python-format
|
||||
msgid "Sound Volume"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:552 common/_compat/preferences.rpym:559 common/_layout/classic_preferences.rpym:60 common/_layout/classic_preferences_common.rpym:370 common/_layout/one_column_preferences.rpym:59 common/_layout/two_column_preferences.rpym:69
|
||||
#, python-format
|
||||
msgid "Joystick..."
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:554 common/_compat/preferences.rpym:575
|
||||
#, python-format
|
||||
msgid "Joystick Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: common/_compat/preferences.rpym:580 common/_layout/classic_preferences.rpym:73 common/_layout/classic_preferences_common.rpym:364 common/_layout/one_column_preferences.rpym:58 common/_layout/two_column_preferences.rpym:68
|
||||
#, python-format
|
||||
msgid "Voice Volume"
|
||||
msgstr ""
|
||||
|
||||
#: common/_layout/classic_load_save.rpym:126
|
||||
#, python-format
|
||||
msgid "Auto"
|
||||
msgstr ""
|
||||
|
||||
#: common/_layout/classic_load_save.rpym:129
|
||||
#, python-format
|
||||
msgid "Quick"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:135
|
||||
#, python-format
|
||||
msgid "The patterns did not match any files, so no archive was created."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:138
|
||||
#, python-format
|
||||
msgid "Archiving Files..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:165 launcher2/distribute.rpy:529
|
||||
#, python-format
|
||||
msgid "Success"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:166
|
||||
#, python-format
|
||||
msgid "The files have been added to the archive, and moved into the \"archived\" directory. Future runs of the archiver will archive files in both the \"game\" and \"archived\" directories."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:30
|
||||
#, python-format
|
||||
msgid "Archive Name:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:31
|
||||
#, python-format
|
||||
msgid "The name of the archive to create."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:33
|
||||
#, python-format
|
||||
msgid "Include Patterns:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:34
|
||||
#, python-format
|
||||
msgid "Files matching these patterns are included in the archive."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:36
|
||||
#, python-format
|
||||
msgid "Exclude Patterns:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:37
|
||||
#, python-format
|
||||
msgid "Files matching these patterns are excluded from the archive."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:41
|
||||
#, python-format
|
||||
msgid "Archive"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:41
|
||||
#, python-format
|
||||
msgid "Build the archive."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:42 launcher2/distribute.rpy:304 launcher2/interface.rpy:159
|
||||
#, python-format
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:50
|
||||
#, python-format
|
||||
msgid "Archive Name"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:51
|
||||
#, python-format
|
||||
msgid "The name of the archive file to create, without the .rpa extension.\n\nThe \"data\" archive is loaded automatically. Other archives must be added to config.archives."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:56 launcher2/archiver.rpy:62
|
||||
#, python-format
|
||||
msgid "Include Patterns"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:57
|
||||
#, python-format
|
||||
msgid "This is a space-separated list of file patterns. Files matching these patterns are added to the archive.\n\nAsterisks (*) can be used as a wildcard."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:63
|
||||
#, python-format
|
||||
msgid "This is a space-separated list of file patterns. Files matching these patterns are excluded from the archive. If a file is matched by both an exclude and include pattern, the exclude takes precedence.\n\nAsterisks (*) can be used as a wildcard."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/archiver.rpy:98
|
||||
#, python-format
|
||||
msgid "Scanning Files..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:155
|
||||
#, python-format
|
||||
msgid "Could not modify options.rpy. Perhaps it was changed too much."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:157
|
||||
#, python-format
|
||||
msgid "Theme changed to %s."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:211
|
||||
#, python-format
|
||||
msgid "Planetarium"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:245
|
||||
#, python-format
|
||||
msgid "The options.rpy file does not exist in the game directory, so this launcher cannot change the theme."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:254
|
||||
#, python-format
|
||||
msgid "Themes control the basic look of interface elements. You'll be able to pick a color scheme next."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:258 launcher2/script.rpy:45
|
||||
#, python-format
|
||||
msgid "Choose Theme"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:296
|
||||
#, python-format
|
||||
msgid "Please choose a color scheme for your project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/choose_theme.rpy:303
|
||||
#, python-format
|
||||
msgid "Choose Color Scheme"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:270
|
||||
#, python-format
|
||||
msgid "Base Name:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:271
|
||||
#, python-format
|
||||
msgid "Used to generate the names of directories and archive files."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:273
|
||||
#, python-format
|
||||
msgid "Executable Name:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:274
|
||||
#, python-format
|
||||
msgid "Used to generate the names of executables and runnable programs."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:276
|
||||
#, python-format
|
||||
msgid "Ignore Extensions:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:277
|
||||
#, python-format
|
||||
msgid "Files with these extensions will not be included in the distributions."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:279
|
||||
#, python-format
|
||||
msgid "Documentation Extensions:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:280
|
||||
#, python-format
|
||||
msgid "Files with these extensions will be treated as documentation, when building the Macintosh application."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:282
|
||||
#, python-format
|
||||
msgid "Distributions to Build:"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:285
|
||||
#, python-format
|
||||
msgid "Windows x86"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:286
|
||||
#, python-format
|
||||
msgid "Zip distribution for the 32-bit Windows platform."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:289
|
||||
#, python-format
|
||||
msgid "Linux x86"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:290
|
||||
#, python-format
|
||||
msgid "Tar.Bz2 distribution for the Linux x86 platform."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:293
|
||||
#, python-format
|
||||
msgid "Macintosh Universal"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:294
|
||||
#, python-format
|
||||
msgid "Single application distribution for the Macintosh x86 and ppc platforms."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:297
|
||||
#, python-format
|
||||
msgid "Windows/Linux/Mac Combined"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:298
|
||||
#, python-format
|
||||
msgid "Zip distribution for the Windows x86, Linux x86, Macintosh x86 and Macintosh ppc platforms."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:303
|
||||
#, python-format
|
||||
msgid "Build"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:303
|
||||
#, python-format
|
||||
msgid "Start building the distributions."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:321
|
||||
#, python-format
|
||||
msgid "Base Name"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:322
|
||||
#, python-format
|
||||
msgid "Please enter in the base name for your distribution. This name is used to generate the names of directories and archive files. Usually, this is the name of your game, plus a version number, like \"moonlight-1.0\"."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:328
|
||||
#, python-format
|
||||
msgid "Executable Name"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:329
|
||||
#, python-format
|
||||
msgid "Please enter a name for the executables in your distribution. This should not include an extension, as that will be added automatically."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:335
|
||||
#, python-format
|
||||
msgid "Ignore Extensions"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:336
|
||||
#, python-format
|
||||
msgid "Please enter a space-separated list of file extensions. Files with these extensions will not be included in the built distributions."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:342
|
||||
#, python-format
|
||||
msgid "Documentation Extensions"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:343
|
||||
#, python-format
|
||||
msgid "Please enter a space separated list of documentation extensions. Files in the base directory with these extensions will have a second copy stored outside of the Macintosh application."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:368
|
||||
#, python-format
|
||||
msgid "Scanning..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:476
|
||||
#, python-format
|
||||
msgid "Building Windows..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:483
|
||||
#, python-format
|
||||
msgid "Building Linux..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:510
|
||||
#, python-format
|
||||
msgid "Building Macintosh..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:518
|
||||
#, python-format
|
||||
msgid "Building Combined..."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:524
|
||||
#, python-format
|
||||
msgid "Thank you for choosing Ren'Py."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/distribute.rpy:530
|
||||
#, python-format
|
||||
msgid "The distributions have been built. Be sure to test them before release.\n\nNote that unpacking and repacking the Macintosh, Linux, or Combined distributions on Windows is not supported.\n\nPlease announce your release at the {a=http://lemmasoft.renai.us/forums/}Lemma Soft Forums{/a}, so we can add it to the Ren'Py web site."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/interface.rpy:179
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/interface.rpy:237
|
||||
#, python-format
|
||||
msgid "Press enter when done."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/interface.rpy:255
|
||||
#, python-format
|
||||
msgid "The string cannot be empty. Please enter some text."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/interface.rpy:26
|
||||
#, python-format
|
||||
msgid "Welcome!"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/interface.rpy:264
|
||||
#, python-format
|
||||
msgid "Non-ASCII filenames are not allowed. This is because Zip files cannot reliably represent non-ASCII filenames."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/interface.rpy:292
|
||||
#, python-format
|
||||
msgid "Processed %d of %d files."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/options.rpy:26
|
||||
#, python-format
|
||||
msgid "%s Launcher"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:173 launcher2/script.rpy:67
|
||||
#, python-format
|
||||
msgid "Select Project"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:201
|
||||
#, python-format
|
||||
msgid "%s has been launched."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:221
|
||||
#, python-format
|
||||
msgid "Opening game directory:\n%s"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:244
|
||||
#, python-format
|
||||
msgid "No files to edit."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:247
|
||||
#, python-format
|
||||
msgid "Launching the editor failed. You may need Java, which can be downloaded for free from {a=http://www.java.com}java.com{/a}."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:249
|
||||
#, python-format
|
||||
msgid "Launched editor with %d script files."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:282
|
||||
#, python-format
|
||||
msgid "Lint complete."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:292
|
||||
#, python-format
|
||||
msgid "Deleting persistent data."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:292 launcher2/script.rpy:49
|
||||
#, python-format
|
||||
msgid "Delete Persistent"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/project.rpy:301
|
||||
#, python-format
|
||||
msgid "Persistent data has been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:113
|
||||
#, python-format
|
||||
msgid "Now showing the Ren'Py documentation in your web browser."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:28
|
||||
#, python-format
|
||||
msgid "Launch"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:30
|
||||
#, python-format
|
||||
msgid "Launches the project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:32
|
||||
#, python-format
|
||||
msgid "Edit Script"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:34
|
||||
#, python-format
|
||||
msgid "Edits the script of the project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:36
|
||||
#, python-format
|
||||
msgid "Game Directory"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:38
|
||||
#, python-format
|
||||
msgid "Opens the project's game directory."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:40
|
||||
#, python-format
|
||||
msgid "Check Script (Lint)"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:42
|
||||
#, python-format
|
||||
msgid "Checks the script of the project for likely errors."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:47
|
||||
#, python-format
|
||||
msgid "Changes the theme used by the project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:51
|
||||
#, python-format
|
||||
msgid "Deletes the persistent data associated with the project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:53
|
||||
#, python-format
|
||||
msgid "Archive Files"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:55
|
||||
#, python-format
|
||||
msgid "Archives files found in the game and archived directories."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:57
|
||||
#, python-format
|
||||
msgid "Build Distributions"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:59
|
||||
#, python-format
|
||||
msgid "Builds distributions of the project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:69
|
||||
#, python-format
|
||||
msgid "Select a project to work with."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:71
|
||||
#, python-format
|
||||
msgid "New Project"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:73
|
||||
#, python-format
|
||||
msgid "Create a new project."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:81
|
||||
#, python-format
|
||||
msgid "Project Directory"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:83
|
||||
#, python-format
|
||||
msgid "Select the directory in which the project can be found."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:85
|
||||
#, python-format
|
||||
msgid "Select Editor"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:87
|
||||
#, python-format
|
||||
msgid "Select the text editor to use."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:89
|
||||
#, python-format
|
||||
msgid "Add-ons"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:91
|
||||
#, python-format
|
||||
msgid "Download additional components for use with Ren'Py."
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:93
|
||||
#, python-format
|
||||
msgid "Ren'Py Help"
|
||||
msgstr ""
|
||||
|
||||
#: launcher2/script.rpy:95
|
||||
#, python-format
|
||||
msgid "Open the Ren'Py documentation in a web browser."
|
||||
msgstr ""
|
||||
@@ -83,8 +83,8 @@ def path_to_renpy_base():
|
||||
##############################################################################
|
||||
|
||||
# The version of the Mac Launcher and py4renpy that we require.
|
||||
macos_version = (6, 10, 1)
|
||||
linux_version = (6, 10, 1)
|
||||
macos_version = (6, 11, 1)
|
||||
linux_version = (6, 11, 1)
|
||||
|
||||
# Doing the version check this way also doubles as an import of ast,
|
||||
# which helps py2exe et al.
|
||||
|
||||
@@ -27,10 +27,14 @@
|
||||
# ***** ***** ***** ***** ***** ***** **** ***** ***** ***** *****
|
||||
# Be sure to change script_version in launcher/script_version.rpy, too!
|
||||
# Also check to see if we have to update renpy.py.
|
||||
version = "Ren'Py 6.11.0b"
|
||||
version = "Ren'Py 6.11.2b"
|
||||
script_version = 5003000
|
||||
savegame_suffix = "-LT1.save"
|
||||
|
||||
# True if this is the first time we've started - even including
|
||||
# utter restarts.
|
||||
first_utter_start = True
|
||||
|
||||
def import_all():
|
||||
|
||||
# Should probably be early, as we will add it as a base to serialized things.
|
||||
@@ -81,10 +85,6 @@ def import_all():
|
||||
import renpy.display.error
|
||||
|
||||
import renpy.display.swdraw
|
||||
|
||||
import renpy.display.glshader
|
||||
import renpy.display.glenviron
|
||||
import renpy.display.gltexture
|
||||
import renpy.display.gldraw
|
||||
|
||||
# Note: For windows to work, renpy.audio.audio needs to be after
|
||||
|
||||
@@ -104,17 +104,16 @@ class PyCode(object):
|
||||
'bytecode',
|
||||
]
|
||||
|
||||
# All PyCodes known to the system.
|
||||
extent = [ ]
|
||||
|
||||
def __getstate__(self):
|
||||
return (1, self.source, self.location, self.mode)
|
||||
|
||||
def __setstate__(self, state):
|
||||
(_, self.source, self.location, self.mode) = state
|
||||
self.bytecode = None
|
||||
renpy.game.script.all_pycode.append(self)
|
||||
|
||||
|
||||
if renpy.game.script.record_pycode:
|
||||
renpy.game.script.all_pycode.append(self)
|
||||
|
||||
def __init__(self, source, loc=('<none>', 1), mode='exec'):
|
||||
|
||||
if isinstance(source, PyExpr):
|
||||
@@ -131,7 +130,8 @@ class PyCode(object):
|
||||
# This will be initialized later on, after we are serialized.
|
||||
self.bytecode = None
|
||||
|
||||
renpy.game.script.all_pycode.append(self)
|
||||
if renpy.game.script.record_pycode:
|
||||
renpy.game.script.all_pycode.append(self)
|
||||
|
||||
def chain_block(block, next):
|
||||
"""
|
||||
@@ -332,6 +332,13 @@ class Say(Node):
|
||||
else:
|
||||
who = None
|
||||
|
||||
if not (
|
||||
(who is None) or
|
||||
callable(who) or
|
||||
isinstance(who, basestring) ):
|
||||
|
||||
raise Exception("Sayer %s is not a function or string." % self.who.encode("utf-8"))
|
||||
|
||||
what = self.what
|
||||
if renpy.config.say_menu_text_filter:
|
||||
what = renpy.config.say_menu_text_filter(what) # E1102
|
||||
@@ -948,7 +955,7 @@ class With(Node):
|
||||
|
||||
|
||||
return [ self.next ]
|
||||
|
||||
|
||||
|
||||
class Call(Node):
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ class ATLTransformBase(renpy.object.Object):
|
||||
|
||||
if t.atl is not self.atl:
|
||||
return
|
||||
|
||||
|
||||
self.done = t.done
|
||||
self.block = t.block
|
||||
self.atl_state = t.atl_state
|
||||
@@ -334,7 +334,7 @@ class ATLTransformBase(renpy.object.Object):
|
||||
if self.child.transform_event != self.last_child_transform_event:
|
||||
self.last_child_transform_event = self.child.transform_event
|
||||
self.transform_event = self.child.transform_event
|
||||
|
||||
|
||||
# Hide request.
|
||||
if trans.hide_request:
|
||||
self.transform_event = "hide"
|
||||
@@ -355,7 +355,7 @@ class ATLTransformBase(renpy.object.Object):
|
||||
timebase = at
|
||||
else:
|
||||
timebase = st
|
||||
|
||||
|
||||
action, arg, pause = self.block.execute(trans, timebase, self.atl_state, event)
|
||||
|
||||
renpy.game.exception_info = old_exception_info
|
||||
@@ -846,10 +846,10 @@ class Interpolation(Statement):
|
||||
# Now, the things we change linearly are in the difference
|
||||
# between the new and old states.
|
||||
linear = trans.state.diff(newts)
|
||||
|
||||
|
||||
revolution = None
|
||||
splines = [ ]
|
||||
|
||||
|
||||
# Clockwise revolution.
|
||||
if self.revolution is not None:
|
||||
|
||||
@@ -900,12 +900,19 @@ class Interpolation(Statement):
|
||||
|
||||
state = (linear, revolution, splines)
|
||||
|
||||
# Ensure that we set things, even if they don't actually
|
||||
# change from the old state.
|
||||
for k, v in self.properties:
|
||||
if k not in linear:
|
||||
setattr(trans.state, k, v)
|
||||
|
||||
else:
|
||||
linear, revolution, splines = state
|
||||
|
||||
|
||||
# Linearly interpolate between the things in linear.
|
||||
for k, (old, new) in linear.iteritems():
|
||||
value = interpolate(complete, old, new, PROPERTIES[k])
|
||||
|
||||
setattr(trans.state, k, value)
|
||||
|
||||
# Handle the revolution.
|
||||
@@ -914,6 +921,7 @@ class Interpolation(Statement):
|
||||
trans.state.angle = interpolate(complete, startangle, endangle, float)
|
||||
trans.state.radius = interpolate(complete, startradius, endradius, float)
|
||||
|
||||
|
||||
# Handle any splines we might have.
|
||||
for name, values in splines:
|
||||
value = interpolate_spline(complete, values)
|
||||
@@ -1145,7 +1153,6 @@ class On(Statement):
|
||||
else:
|
||||
name, start, cstate = state
|
||||
|
||||
|
||||
# If we have an external event, and we have a handler for it,
|
||||
# handle it.
|
||||
if event in self.handlers:
|
||||
@@ -1156,6 +1163,7 @@ class On(Statement):
|
||||
name = event
|
||||
start = st
|
||||
cstate = None
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
@@ -1167,7 +1175,7 @@ class On(Statement):
|
||||
|
||||
# If we get a continue, save our state.
|
||||
if action == "continue":
|
||||
|
||||
|
||||
# If it comes from a hide block, indicate that.
|
||||
if name == "hide" or name == "replaced":
|
||||
trans.hide_response = False
|
||||
@@ -1179,7 +1187,7 @@ class On(Statement):
|
||||
# event, unless we're already in default, in which case we
|
||||
# go to None.
|
||||
elif action == "next":
|
||||
if name == "default" or name == "hide":
|
||||
if name == "default" or name == "hide" or name == "replaced":
|
||||
name = None
|
||||
else:
|
||||
name = "default"
|
||||
|
||||
@@ -186,7 +186,7 @@ class Channel(object):
|
||||
This stores information about the currently-playing music.
|
||||
"""
|
||||
|
||||
def __init__(self, name, default_loop, stop_on_mute, tight, file_prefix, file_suffix):
|
||||
def __init__(self, name, default_loop, stop_on_mute, tight, file_prefix, file_suffix, buffer_queue):
|
||||
|
||||
# The name assigned to this channel. This is used to look up
|
||||
# information about the channel in the MusicContext object.
|
||||
@@ -253,6 +253,9 @@ class Channel(object):
|
||||
# A prefix and suffix that are used to create the full filenames.
|
||||
self.file_prefix = file_prefix
|
||||
self.file_suffix = file_suffix
|
||||
|
||||
# Should we buffer upcoming music/video in the queue?
|
||||
self.buffer_queue = buffer_queue
|
||||
|
||||
if default_loop is None:
|
||||
# By default, should we loop the music?
|
||||
@@ -343,6 +346,11 @@ class Channel(object):
|
||||
if depth >= 2:
|
||||
break
|
||||
|
||||
# If we can't buffer things, and we're playing something
|
||||
# give up here.
|
||||
if not self.buffer_queue and depth >= 1:
|
||||
break
|
||||
|
||||
# We can't queue anything if the depth is > 0 and we're
|
||||
# waiting for a synchro_start.
|
||||
if self.synchro_start and depth:
|
||||
@@ -493,8 +501,18 @@ class Channel(object):
|
||||
if not pcm_ok:
|
||||
return None
|
||||
|
||||
return pss.playing_name(self.number)
|
||||
rv = pss.playing_name(self.number)
|
||||
|
||||
if rv is None and self.queue:
|
||||
rv = self.queue[0].filename
|
||||
|
||||
if rv is None and self.loop:
|
||||
rv = self.loop[0]
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
|
||||
|
||||
def set_volume(self, volume):
|
||||
self.chan_volume = volume
|
||||
@@ -531,7 +549,7 @@ all_channels = [ ]
|
||||
channels = { }
|
||||
|
||||
|
||||
def register_channel(name, mixer=None, loop=None, stop_on_mute=True, tight=False, file_prefix="", file_suffix=""):
|
||||
def register_channel(name, mixer=None, loop=None, stop_on_mute=True, tight=False, file_prefix="", file_suffix="", buffer_queue=True):
|
||||
"""
|
||||
:doc: other
|
||||
|
||||
@@ -563,15 +581,16 @@ def register_channel(name, mixer=None, loop=None, stop_on_mute=True, tight=False
|
||||
`file_suffix`
|
||||
A suffix that is appended to the filenames of the sound files being
|
||||
played on this channel.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
`buffer_queue`
|
||||
Should we buffer the first second or so of a queued file? This should
|
||||
be True for audio, and False for movie playback.
|
||||
"""
|
||||
|
||||
if not renpy.game.init_phase:
|
||||
raise Exception("Can't register channel outside of init phase.")
|
||||
|
||||
c = Channel(name, loop, stop_on_mute, tight, file_prefix, file_suffix)
|
||||
c = Channel(name, loop, stop_on_mute, tight, file_prefix, file_suffix, buffer_queue)
|
||||
c.mixer = mixer
|
||||
all_channels.append(c)
|
||||
channels[name] = c
|
||||
@@ -813,7 +832,24 @@ def rollback():
|
||||
|
||||
ALLOC_EVENT = pygame.USEREVENT
|
||||
REFRESH_EVENT = pygame.USEREVENT + 1
|
||||
|
||||
|
||||
# The last surface we allocated.
|
||||
last_alloc_surface = None
|
||||
|
||||
def alloc_surface(force):
|
||||
|
||||
global last_alloc_surface
|
||||
|
||||
if renpy.display.video.fullscreen and renpy.display.draw.fullscreen_surface:
|
||||
surf = renpy.display.draw.fullscreen_surface
|
||||
else:
|
||||
surf = renpy.display.video.surface
|
||||
|
||||
if (surf is not last_alloc_surface) or force:
|
||||
last_alloc_surface = surf
|
||||
pss.alloc_event(surf)
|
||||
|
||||
def event(ev):
|
||||
"""
|
||||
Handles an event generated by pss (really, the ffdecode
|
||||
@@ -824,24 +860,20 @@ def event(ev):
|
||||
if not pcm_ok:
|
||||
return False
|
||||
|
||||
|
||||
if renpy.display.video.fullscreen or not renpy.display.video.surface:
|
||||
surf = renpy.display.draw.fullscreen_surface
|
||||
else:
|
||||
surf = renpy.display.video.surface
|
||||
|
||||
if ev.type == ALLOC_EVENT:
|
||||
pss.alloc_event(surf)
|
||||
|
||||
alloc_surface(True)
|
||||
|
||||
return True
|
||||
|
||||
if ev.type == REFRESH_EVENT:
|
||||
elif ev.type == REFRESH_EVENT:
|
||||
|
||||
alloc_surface(False)
|
||||
|
||||
if renpy.audio.music.get_playing("movie"):
|
||||
pss.refresh_event()
|
||||
|
||||
renpy.display.draw.mutated_surface(surf)
|
||||
|
||||
if surf is renpy.display.draw.fullscreen_surface:
|
||||
renpy.game.interface.force_redraw = True
|
||||
renpy.game.interface.force_redraw = True
|
||||
|
||||
# Return False, as a Movie should get this to know when to
|
||||
# redraw itself.
|
||||
|
||||