Compare commits
254 Commits
6.99
...
6.99.0.254
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d4ef2df96 | |||
| 2b20ef7834 | |||
| e4fe7f3586 | |||
| 7cfc6ad1ba | |||
| 57c27cfde4 | |||
| 3ceec0b62d | |||
| fe1d1e5499 | |||
| ca944b5089 | |||
| 92163cd704 | |||
| edfd705a52 | |||
| 4a1557edf3 | |||
| 4c55cab9fc | |||
| 8a9eb86bac | |||
| 077c7818ec | |||
| 136db345c9 | |||
| 31b711b672 | |||
| 7aeed18720 | |||
| 7da86f27e9 | |||
| e851096b77 | |||
| 91cdebd401 | |||
| 939034a481 | |||
| 4ae3092877 | |||
| db23bd0f91 | |||
| 5e0de94e9a | |||
| cdfbfcd481 | |||
| 5d49b6b75b | |||
| f9a7b7dc21 | |||
| 61b7550157 | |||
| fc7fcc8db9 | |||
| 2cdb8adb64 | |||
| a22b406f46 | |||
| cff0b43f96 | |||
| 0a2bee8a78 | |||
| 0e53af427f | |||
| 3120b5e438 | |||
| 01689fc02a | |||
| afc9a2d97c | |||
| df5d891ee7 | |||
| d7ba76f44f | |||
| 10cda2103f | |||
| 616cdbd218 | |||
| 2199a4db1c | |||
| c4b673099f | |||
| c61b01ee0c | |||
| 24f26acea4 | |||
| f4e5e0f297 | |||
| a78d9bbccf | |||
| 89ec94a72b | |||
| cf495ac494 | |||
| 0eb54ef113 | |||
| 3043543901 | |||
| 6f56cbb12e | |||
| a7542015ab | |||
| 3e20a92c80 | |||
| 93812b4a1b | |||
| 4f3a0c546f | |||
| 097978b044 | |||
| da041e5170 | |||
| 9b626fe039 | |||
| c51db4ce64 | |||
| 01b66c6197 | |||
| 2a31925ef7 | |||
| 9480b544fb | |||
| 8c989bb684 | |||
| d9dd895775 | |||
| a149858701 | |||
| 3a1105935c | |||
| c5fa5ca98b | |||
| e40e780834 | |||
| 5f23501413 | |||
| 0631221d98 | |||
| 87fc8b0468 | |||
| b6d16ef601 | |||
| 72704eb945 | |||
| 23c202e25f | |||
| 253cf2a5c7 | |||
| dfce28b881 | |||
| 013cfdadea | |||
| 71545e6d3a | |||
| 8282084f48 | |||
| 5d53028f62 | |||
| c43f364eab | |||
| 93b25e9627 | |||
| 3051687b4c | |||
| 94cca9458b | |||
| c63e58f170 | |||
| 3aa40537e9 | |||
| 495fa5512c | |||
| f561b1ce04 | |||
| 7def90322f | |||
| 75c8861de9 | |||
| 9b5de49aae | |||
| 3e5197f909 | |||
| 152ba2d7e5 | |||
| 1d4d093a88 | |||
| 955e02ce26 | |||
| b499d95390 | |||
| df36d206d3 | |||
| 9af5e19054 | |||
| 8492045273 | |||
| 49a3b15816 | |||
| f015bb7b81 | |||
| 44aa9c6fc8 | |||
| d4eebdff49 | |||
| f42572c1f8 | |||
| 356c6e346a | |||
| 22eb62afff | |||
| 7d17c87ed0 | |||
| 7c8e93a046 | |||
| 86d250079b | |||
| b2cb51a61b | |||
| 4cfe681d00 | |||
| c670a25f8b | |||
| db5ee1e91f | |||
| ca1f1f1032 | |||
| 32800f1c48 | |||
| 66544cd4b2 | |||
| 94df2f93b7 | |||
| 4c1269c62e | |||
| a94989eb06 | |||
| 0cc2df8800 | |||
| d62f28d849 | |||
| 31de055d6f | |||
| a3daed1409 | |||
| d7ccd581ae | |||
| f559367d6a | |||
| 064d24e838 | |||
| ec894fc458 | |||
| 845f802a59 | |||
| 6680a16db6 | |||
| d838a3d07a | |||
| 1e35f405fb | |||
| 9900bf6ecc | |||
| ab36e3d59a | |||
| d370760071 | |||
| 0310e60b1c | |||
| 54614e2b83 | |||
| 92032f123b | |||
| f799dfcb31 | |||
| 99698fdd06 | |||
| 4bf0b7ca67 | |||
| 685fd09a75 | |||
| 75825e7c2c | |||
| 052ec96f54 | |||
| a4ab8fa083 | |||
| 75e5a29470 | |||
| 04db67cad7 | |||
| 0550a85716 | |||
| 91d5f6cc21 | |||
| 82433d3dc0 | |||
| 663cac933f | |||
| 520ff08595 | |||
| 95e12cab07 | |||
| 52093520fd | |||
| f92e459801 | |||
| b8d08dda5a | |||
| f8453fc4fd | |||
| c5c3a57f9d | |||
| 83245c7432 | |||
| 5715bdec00 | |||
| c57253cfce | |||
| 85fa790711 | |||
| c379dd6bc3 | |||
| e42d04ad9e | |||
| f361f7d0ef | |||
| 69bd85f98f | |||
| b4cee2db25 | |||
| b16e7ebf8e | |||
| 4f9dcd4fdc | |||
| 3dc33d4238 | |||
| aa16b64225 | |||
| f93d3b9fc9 | |||
| 250103bf4e | |||
| bc6767bdf4 | |||
| 15a6b39a40 | |||
| 83352e3e29 | |||
| c8c52477c9 | |||
| 042ae30b62 | |||
| b9f3bbe950 | |||
| 2fd1416ce4 | |||
| 722c99ed04 | |||
| b59c94ad7f | |||
| 547a504f7b | |||
| 51a168c12f | |||
| 3573a42ef7 | |||
| 23d69c7c8e | |||
| 77e44a5ab5 | |||
| b892ca4791 | |||
| 4775d4f082 | |||
| 2148a68df8 | |||
| 52a8fd1b63 | |||
| 422db61d71 | |||
| 749462beec | |||
| 8726c6d50b | |||
| 6ae531e893 | |||
| dc117ffbe1 | |||
| 40e3eaaf64 | |||
| 72e4607e82 | |||
| cfdaa95bea | |||
| 2be0638602 | |||
| 6ec5a0c122 | |||
| fd1902ecd2 | |||
| ec77844b1a | |||
| 8c238ae4ff | |||
| 4c909922d4 | |||
| 8358539667 | |||
| 5c87617652 | |||
| a102a7dca9 | |||
| a2e8758965 | |||
| 5914e9317c | |||
| 094dbe7386 | |||
| 84debf31c7 | |||
| 5afacd4dec | |||
| 4221eb049f | |||
| 4971ff139f | |||
| e5a50b4b4d | |||
| 5222a47b9d | |||
| 98afd6402c | |||
| 24fdc18a47 | |||
| e5632b27b2 | |||
| 14db5d588f | |||
| dbb990c0f7 | |||
| a34bed7e11 | |||
| 7c61befcb0 | |||
| 9381c7399b | |||
| 439365977f | |||
| 5b3a7bf02e | |||
| 1be45fb2d4 | |||
| a327517cf8 | |||
| f9204ad5a0 | |||
| 5b5a7ab907 | |||
| 634bb3ad64 | |||
| 329d8d3ee1 | |||
| 24c7e845c3 | |||
| 3f01f49da3 | |||
| 6d7c28560c | |||
| 23931a5676 | |||
| b4dd9f6878 | |||
| 2903b81360 | |||
| 942cf82354 | |||
| 4dcdd1ad65 | |||
| a2a3c284a3 | |||
| 4497d5e30f | |||
| 9c5e037db6 | |||
| 2b6c7941d6 | |||
| 4e11d77258 | |||
| 9791e379e3 | |||
| b59dc7906c | |||
| 253726c433 | |||
| 06e3a75515 | |||
| 2925e1e64f | |||
| ead574ae6b | |||
| 1f4d4cd974 | |||
| 2deaf3689a |
@@ -10,6 +10,7 @@
|
||||
saves
|
||||
tmp
|
||||
cache
|
||||
env
|
||||
|
||||
log.txt
|
||||
/errors.txt
|
||||
|
||||
@@ -34,22 +34,34 @@ else:
|
||||
tag = False
|
||||
|
||||
|
||||
def check_dirty():
|
||||
if args.no_tag:
|
||||
return
|
||||
SOURCE = [
|
||||
"/home/tom/ab/renpy",
|
||||
"/home/tom/ab/android/",
|
||||
"/home/tom/ab/android/python-for-android",
|
||||
"/home/tom/ab/ripe/renios",
|
||||
"/home/tom/ab/renpy-deps",
|
||||
"/home/tom/ab/pygame_sdl2",
|
||||
]
|
||||
|
||||
if subprocess.check_call([ "git", "diff", "--quiet", "HEAD" ]):
|
||||
print "Directory not checked in: {}".format(os.getcwd())
|
||||
sys.exit(1)
|
||||
if tag:
|
||||
for i in SOURCE:
|
||||
os.chdir(i)
|
||||
|
||||
os.chdir("/home/tom/ab/renpy")
|
||||
check_dirty()
|
||||
if subprocess.call([ "git", "diff", "--quiet", "HEAD" ]):
|
||||
print "Directory not checked in: {}".format(os.getcwd())
|
||||
sys.exit(1)
|
||||
|
||||
os.chdir("/home/tom/ab/renpy/android")
|
||||
check_dirty()
|
||||
for i in SOURCE:
|
||||
|
||||
os.chdir(i)
|
||||
|
||||
if i == SOURCE[0]:
|
||||
tag = version
|
||||
else:
|
||||
tag = "renpy-" + version
|
||||
|
||||
subprocess.check_call([ "git", "tag", "-a", tag, "-m", "Tagging Ren'Py + " + version + " release." ])
|
||||
|
||||
if not args.no_tag:
|
||||
subprocess.check_call([ "git", "tag", "-a", "rapt-" + version, "-m", "Tagging RAPT release." ])
|
||||
|
||||
os.chdir("/home/tom/ab/renpy/dl")
|
||||
|
||||
@@ -58,11 +70,5 @@ for i in links:
|
||||
os.unlink(i)
|
||||
os.symlink(short_version, i)
|
||||
|
||||
os.chdir("/home/tom/ab/renpy")
|
||||
|
||||
if tag and not args.no_tag:
|
||||
cmd = [ "git", "tag", "-a", version, "-m", "Ren'Py " + version ]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
os.chdir("/home/tom/ab/website")
|
||||
subprocess.check_call("./upload.sh")
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
lib\windows-i686\python.exe -OO renpy.py
|
||||
lib\windows-i686\python.exe -OO renpy.py tutorial
|
||||
pause
|
||||
|
||||
+9
-2
@@ -45,6 +45,7 @@ def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("version")
|
||||
ap.add_argument("--fast", action="store_true")
|
||||
ap.add_argument("--pygame", action="store", default=None)
|
||||
|
||||
args = ap.parse_args()
|
||||
|
||||
@@ -123,11 +124,17 @@ def main():
|
||||
|
||||
android = os.path.abspath("android")
|
||||
|
||||
rapt_build = subprocess.Popen([
|
||||
rapt_cmd = [
|
||||
os.path.join(android, "build_renpy.sh"),
|
||||
"renpy",
|
||||
ROOT,
|
||||
],
|
||||
]
|
||||
|
||||
if args.pygame:
|
||||
rapt_cmd.append(args.pygame)
|
||||
|
||||
rapt_build = subprocess.Popen(
|
||||
rapt_cmd,
|
||||
cwd = android,
|
||||
stdout=out,
|
||||
stderr=out)
|
||||
|
||||
@@ -2,131 +2,160 @@
|
||||
<head>
|
||||
<title>README</title>
|
||||
<style>
|
||||
|
||||
BODY {
|
||||
background: #fff;
|
||||
color: #444;
|
||||
padding-left: 20%;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
padding-right: 20%;
|
||||
font-family: sans-serif;
|
||||
line-height: 1.6em;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
padding-left: 20%;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
padding-right: 20%;
|
||||
font-family: sans-serif;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
DT {
|
||||
font-weight: bold;
|
||||
margin-top: .33em;
|
||||
font-weight: bold;
|
||||
margin-top: .33em;
|
||||
}
|
||||
|
||||
H2 {
|
||||
color: #000;
|
||||
margin-left: -2.5em;
|
||||
color: #000;
|
||||
margin-left: -2.5em;
|
||||
}
|
||||
|
||||
H3 {
|
||||
color: #000;
|
||||
margin-left: -1.5em;
|
||||
color: #000;
|
||||
margin-left: -1.5em;
|
||||
}
|
||||
|
||||
.editsection {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="renpy_help"></div>
|
||||
<h2>Basic Help</h2>
|
||||
<p>
|
||||
To advance through the game, <tt>left-click</tt> or press the <tt>space</tt>
|
||||
or <tt>enter</tt> keys. When at a menu, <tt>left-click</tt> to make
|
||||
a choice, or use the arrow keys to select a choice and <tt>enter</tt>
|
||||
to activate it.
|
||||
</p>
|
||||
|
||||
<h3>Game Menu</h3>
|
||||
<p>
|
||||
When playing a game, <tt>right-click</tt> or press the <tt>escape</tt>
|
||||
key to enter the game menu. The game menu gives the following
|
||||
choices:
|
||||
</p>
|
||||
<dl>
|
||||
<dt>Return</dt>
|
||||
<dd>Returns to the game.</dd>
|
||||
<dt>Save Game</dt>
|
||||
<dd>Allows you to save a game by clicking on a save slot.</dd>
|
||||
<dt>Load Game</dt>
|
||||
<dd>Allows you to load a game by clicking on a save slot.
|
||||
Clicking on "Auto" accesses the automatic save slots.</dd>
|
||||
<dt>Preferences</dt>
|
||||
<dd>
|
||||
Changes the game preferences (options/configuration):
|
||||
<dl>
|
||||
<dt>Display</dt>
|
||||
<dd>Switches between fullscreen and windowed mode.</dd>
|
||||
<dt>Transitions</dt>
|
||||
<dd>Controls the display of transitions between game
|
||||
screens.</dd>
|
||||
<dt>Text Speed</dt>
|
||||
<dd>Controls the rate at which text displays. The further
|
||||
to the right this slider is, the faster the text will display.
|
||||
All the way to the right causes text to be shown instantly.</dd>
|
||||
<dt>Joystick</dt>
|
||||
<dd>Lets you control the game using a joystick.</dd>
|
||||
<dt>Skip</dt>
|
||||
<dd>Chooses between skipping messages that have been
|
||||
already seen (in any play through the game), and skipping all
|
||||
messages.</dd>
|
||||
<dt>Begin Skipping</dt>
|
||||
<dd>Returns to the game, while skipping.</dd>
|
||||
<dt>After Choices</dt>
|
||||
<dd>Controls if skipping stops upon reaching a menu.</dd>
|
||||
<dt>Auto-Forward Time</dt>
|
||||
<dd>Controls automatic advance. The further to the left
|
||||
this slider is, the shorter the amount of time before the game
|
||||
advances. All the way to the right means text will never
|
||||
auto-forward.</dd>
|
||||
<dt>Music, Sound, and Voice Volume</dt>
|
||||
<dd>Controls the volume of the Music, Sound effect, and
|
||||
Voice channels, respectively. The further to the right these
|
||||
are, the louder the volume.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Main Menu</dt>
|
||||
<dd>Returns to the main menu, ending the current game.</dd>
|
||||
<dt>Help</dt>
|
||||
<dd>Shows this help screen.</dd>
|
||||
<dt>Quit</dt>
|
||||
<dd>Exits the game; the game will be closed and ended.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Key and Mouse Bindings</h3>
|
||||
<dl>
|
||||
<dt>Left-click, Enter</dt>
|
||||
<dd>Advances through the game, activates menu choices, buttons,
|
||||
and sliders.</dd>
|
||||
<dt>Space</dt>
|
||||
<dd>Advances through the game, but does not activate choices.</dd>
|
||||
<dt>Arrow Keys</dt>
|
||||
<dd>Selects menu choices, buttons, and sliders.</dd>
|
||||
<dt>Ctrl</dt>
|
||||
<dd>Causes skipping to occur while the ctrl key is held down.</dd>
|
||||
<dt>Tab</dt>
|
||||
<dd>Toggles skipping, causing it to occur until tab is pressed
|
||||
again.</dd>
|
||||
<dt>Mousewheel-Up, PageUp</dt>
|
||||
<dd>Causes rollback to occur. Rollback reverses the game back
|
||||
in time, showing prior text and even allowing menu choices to be
|
||||
changed.</dd>
|
||||
<dt>Mousewheel-Down, PageDown</dt>
|
||||
<dd>Causes rollforward to occur, canceling out a previous
|
||||
rollback.</dd>
|
||||
<dt>Right-click, Escape</dt>
|
||||
<dd>Enters the game menu. When in the game menu, returns to the
|
||||
game.</dd>
|
||||
<dt>Middle-click, H</dt>
|
||||
<dd>Hides the text window and other transient displays.</dd>
|
||||
<dt>F</dt>
|
||||
<dd>Toggles fullscreen mode</dd>
|
||||
<dt>S</dt>
|
||||
<dd>Takes a screenshot, saving it in a file named
|
||||
screenshotxxxx.png, where xxxx is a serial number.</dd>
|
||||
<dt>Alt-M, Command-H</dt>
|
||||
<dd>Hides (iconifies) the window.</dd>
|
||||
<dt>Alt-F4, Command-Q</dt>
|
||||
<dd>Quits the game.</dd>
|
||||
<dt>Delete</dt>
|
||||
<dd>When a save slot is selected, deletes that save slot.</dd>
|
||||
<dt>v</dt>
|
||||
<dd>
|
||||
Toggles self-voicing mode, which reads text to the user using an
|
||||
os-supplied speech synthesizer. For more information, please read
|
||||
the <a href="http://www.renpy.org/doc/html/self_voicing.html">self-voicing</a>
|
||||
documentation.
|
||||
</dd>
|
||||
<dt>Shift+C</dt>
|
||||
<dd>Toggles clipboard-voicing mode, which copies text to the
|
||||
clipboard so it can be read by a screen reader.</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<p><a name="Basic_Help" id="Basic_Help"></a></p>
|
||||
<h2><span class="editsection">[<a href="/w/index.php?title=renpy/Help&action=edit&section=1" title="Edit section: Basic Help">edit</a>]</span> <span class="mw-headline">Basic Help</span></h2>
|
||||
<p>To advance through the game, <tt>left-click</tt> or press the <tt>space</tt> or <tt>enter</tt> keys. When at a menu, <tt>left-click</tt> to make a choice, or use the arrow keys to select a choice and <tt>enter</tt> to activate it.</p>
|
||||
<p><a name="Game_Menu" id="Game_Menu"></a></p>
|
||||
<h3><span class="editsection">[<a href="/w/index.php?title=renpy/Help&action=edit&section=2" title="Edit section: Game Menu">edit</a>]</span> <span class="mw-headline">Game Menu</span></h3>
|
||||
<p>When playing a game, <tt>right-click</tt> or press the <tt>escape</tt> key to enter the game menu. The game menu gives the following choices:</p>
|
||||
<dl>
|
||||
<dt>Return</dt>
|
||||
<dd>Returns to the game.</dd>
|
||||
<dt>Save Game</dt>
|
||||
<dd>Allows you to save a game by clicking on a save slot.</dd>
|
||||
<dt>Load Game</dt>
|
||||
<dd>Allows you to load a game by clicking on a save slot. Clicking on "Auto" accesses the automatic save slots.</dd>
|
||||
<dt>Preferences</dt>
|
||||
<dd>Changes the game preferences (options/configuration):
|
||||
<dl>
|
||||
<dt>Display</dt>
|
||||
<dd>Switches between fullscreen and windowed mode.</dd>
|
||||
<dt>Transitions</dt>
|
||||
<dd>Controls the display of transitions between game screens.</dd>
|
||||
<dt>Text Speed</dt>
|
||||
<dd>Controls the rate at which text displays. The further to the right this slider is, the faster the text will display. All the way to the right causes text to be shown instantly.</dd>
|
||||
<dt>Joystick</dt>
|
||||
<dd>Lets you control the game using a joystick.</dd>
|
||||
<dt>Skip</dt>
|
||||
<dd>Chooses between skipping messages that have been already seen (in any play through the game), and skipping all messages.</dd>
|
||||
<dt>Begin Skipping</dt>
|
||||
<dd>Returns to the game, while skipping.</dd>
|
||||
<dt>After Choices</dt>
|
||||
<dd>Controls if skipping stops upon reaching a menu.</dd>
|
||||
<dt>Auto-Forward Time</dt>
|
||||
<dd>Controls automatic advance. The further to the left this slider is, the shorter the amount of time before the game advances. All the way to the right means text will never auto-forward.</dd>
|
||||
<dt>Music, Sound, and Voice Volume</dt>
|
||||
<dd>Controls the volume of the Music, Sound effect, and Voice channels, respectively. The further to the right these are, the louder the volume.</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Main Menu</dt>
|
||||
<dd>Returns to the main menu, ending the current game.</dd>
|
||||
<dt>Help</dt>
|
||||
<dd>Shows this help screen.</dd>
|
||||
<dt>Quit</dt>
|
||||
<dd>Exits the game; the game will be closed and ended.</dd>
|
||||
</dl>
|
||||
<p><a name="Key_and_Mouse_Bindings" id="Key_and_Mouse_Bindings"></a></p>
|
||||
<h3><span class="editsection">[<a href="/w/index.php?title=renpy/Help&action=edit&section=3" title="Edit section: Key and Mouse Bindings">edit</a>]</span> <span class="mw-headline">Key and Mouse Bindings</span></h3>
|
||||
<dl>
|
||||
<dt>Left-click, Enter</dt>
|
||||
<dd>Advances through the game, activates menu choices, buttons, and sliders.</dd>
|
||||
<dt>Space</dt>
|
||||
<dd>Advances through the game, but does not activate choices.</dd>
|
||||
<dt>Arrow Keys</dt>
|
||||
<dd>Selects menu choices, buttons, and sliders.</dd>
|
||||
<dt>Ctrl</dt>
|
||||
<dd>Causes skipping to occur while the ctrl key is held down.</dd>
|
||||
<dt>Tab</dt>
|
||||
<dd>Toggles skipping, causing it to occur until tab is pressed again.</dd>
|
||||
<dt>Mousewheel-Up, PageUp</dt>
|
||||
<dd>Causes rollback to occur. Rollback reverses the game back in time, showing prior text and even allowing menu choices to be changed.</dd>
|
||||
<dt>Mousewheel-Down, PageDown</dt>
|
||||
<dd>Causes rollforward to occur, cancelling out a previous rollback.</dd>
|
||||
<dt>Right-click, Escape</dt>
|
||||
<dd>Enters the game menu. When in the game menu, returns to the game.</dd>
|
||||
<dt>Middle-click, H</dt>
|
||||
<dd>Hides the text window and other transient displays.</dd>
|
||||
<dt>F</dt>
|
||||
<dd>Toggles fullscreen mode</dd>
|
||||
<dt>S</dt>
|
||||
<dd>Takes a screenshot, saving it in a file named screenshotxxxx.png, where xxxx is a serial number.</dd>
|
||||
<dt>Alt-M, Command-H</dt>
|
||||
<dd>Hides (iconifies) the window.</dd>
|
||||
<dt>Alt-F4, Command-Q</dt>
|
||||
<dd>Quits the game.</dd>
|
||||
<dt>Delete</dt>
|
||||
<dd>When a save slot is selected, deletes that save slot.</dd>
|
||||
<dt>v</dt>
|
||||
<dd>Toggles self-voicing mode, which reads text to the user using an os-supplied
|
||||
speech synthesizer. For more information, please read the <a href="http://www.renpy.org/dev-doc/html/self_voicing.html">self-voicing</a>
|
||||
documentation.</dd>
|
||||
</dl>
|
||||
<p><a name="Legal_Notice" id="Legal_Notice"></a></p>
|
||||
<h2><span class="editsection">[<a href="/w/index.php?title=renpy/Help&action=edit&section=4" title="Edit section: Legal Notice">edit</a>]</span> <span class="mw-headline">Legal Notice</span></h2>
|
||||
<p>This game uses source code from a number of open source projects. For a list, and a location where the source code can be downloaded from, please view the LICENSE.txt file in the renpy directory, or visit <a href="http://www.renpy.org/wiki/renpy/License" class="external free" title="http://www.renpy.org/wiki/renpy/License" rel="nofollow">http://www.renpy.org/wiki/renpy/License</a> .</p>
|
||||
|
||||
|
||||
<h2>Legal Notice</h2>
|
||||
<p>
|
||||
This program contains free software licensed under a number of
|
||||
licenses, including the GNU Lesser Public License. A complete list
|
||||
of software is available at <a
|
||||
href="http://www.renpy.org/doc/html/license.html"
|
||||
>http://www.renpy.org/doc/html/license.html</a>.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
+27
-206
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -43,6 +43,7 @@ init python:
|
||||
PLAY_KEYS_TEXT = _("Opens the file containing the Google Play keys in the editor.\n\nThis is only needed if the application is using an expansion APK. Read the documentation for more details.")
|
||||
BUILD_TEXT = _("Builds the Android package.")
|
||||
BUILD_AND_INSTALL_TEXT = _("Builds the Android package, and installs it on an Android device connected to your computer.")
|
||||
BUILD_INSTALL_AND_LAUNCH_TEXT = _("Builds the Android package, installs it on an Android device connected to your computer, then launches the app on your device.")
|
||||
|
||||
CONNECT_TEXT = _("Connects to an Android device running ADB in TCP/IP mode.")
|
||||
DISCONNECT_TEXT = _("Disconnects from an Android device running ADB in TCP/IP mode.")
|
||||
@@ -66,7 +67,6 @@ init python:
|
||||
sys.path.insert(0, os.path.join(RAPT_PATH, "buildlib"))
|
||||
else:
|
||||
RAPT_PATH = None
|
||||
RAPT_PATH is None
|
||||
|
||||
find_rapt()
|
||||
|
||||
@@ -79,6 +79,8 @@ init python:
|
||||
import rapt.install_sdk
|
||||
import rapt.plat
|
||||
import rapt.interface
|
||||
|
||||
rapt.plat.renpy = True
|
||||
else:
|
||||
rapt = None
|
||||
|
||||
@@ -131,184 +133,6 @@ init python:
|
||||
else:
|
||||
return None
|
||||
|
||||
class AndroidInterface(object):
|
||||
|
||||
def __init__(self):
|
||||
self.process = None
|
||||
self.filename = project.current.temp_filename("android.txt")
|
||||
|
||||
self.info_msg = ""
|
||||
|
||||
with open(self.filename, "w"):
|
||||
pass
|
||||
|
||||
def log(self, msg):
|
||||
with open(self.filename, "a") as f:
|
||||
f.write("\n")
|
||||
f.write(msg)
|
||||
f.write("\n")
|
||||
|
||||
def info(self, prompt):
|
||||
self.info_msg = prompt
|
||||
interface.processing(prompt, pause=False)
|
||||
self.log(prompt)
|
||||
|
||||
def yesno(self, prompt, submessage=None):
|
||||
return interface.yesno(prompt, submessage=submessage)
|
||||
|
||||
def yesno_choice(self, prompt, default=None):
|
||||
choices = [ (True, "Yes"), (False, "No") ]
|
||||
return interface.choice(prompt, choices, default)
|
||||
|
||||
def terms(self, url, prompt):
|
||||
submessage = _("{a=%s}%s{/a}") % (url, url)
|
||||
|
||||
if not interface.yesno(prompt, submessage=submessage):
|
||||
self.fail("You must accept the terms and conditions to proceed.", edit=False)
|
||||
|
||||
|
||||
def input(self, prompt, empty=None):
|
||||
|
||||
if empty is None:
|
||||
empty = ''
|
||||
|
||||
while True:
|
||||
rv = interface.input(_("QUESTION"), prompt, default=empty, cancel=Jump("android"))
|
||||
|
||||
rv = rv.strip()
|
||||
|
||||
if rv:
|
||||
return rv
|
||||
|
||||
def choice(self, prompt, choices, default):
|
||||
return interface.choice(prompt, choices, default, cancel=Jump("android"))
|
||||
|
||||
def fail(self, prompt, edit=True):
|
||||
self.log(prompt)
|
||||
prompt = re.sub(r'(http://\S+)', r'{a=\1}\1{/a}', prompt)
|
||||
|
||||
# Open android.txt in the editor.
|
||||
if edit:
|
||||
editor.EditAbsolute(self.filename)()
|
||||
|
||||
interface.error(prompt, label="android")
|
||||
|
||||
def success(self, prompt):
|
||||
self.log(prompt)
|
||||
interface.info(prompt, pause=False)
|
||||
|
||||
def final_success(self, prompt):
|
||||
self.log(prompt)
|
||||
interface.info(prompt, label="android")
|
||||
|
||||
def run_yes_thread(self):
|
||||
import time
|
||||
|
||||
try:
|
||||
while self.run_yes:
|
||||
self.process.stdin.write('y\n')
|
||||
self.process.stdin.flush()
|
||||
time.sleep(.2)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def call(self, cmd, cancel=False, use_path=False, yes=False):
|
||||
|
||||
print
|
||||
print " ".join(cmd)
|
||||
|
||||
self.cmd = cmd
|
||||
|
||||
f = open(self.filename, "a")
|
||||
|
||||
f.write("\n\n\n")
|
||||
|
||||
if cancel:
|
||||
cancel_action = self.cancel
|
||||
else:
|
||||
cancel_action = None
|
||||
|
||||
startupinfo = None
|
||||
if renpy.windows:
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
|
||||
self.yes_thread = None
|
||||
|
||||
try:
|
||||
interface.processing(self.info_msg, show_screen=True, cancel=cancel_action)
|
||||
|
||||
kwargs = { }
|
||||
if yes:
|
||||
kwargs["stdin"] = subprocess.PIPE
|
||||
|
||||
try:
|
||||
self.process = subprocess.Popen(cmd, cwd=RAPT_PATH, stdout=f, stderr=f, startupinfo=startupinfo, **kwargs)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc(file=f)
|
||||
raise
|
||||
|
||||
if yes:
|
||||
import threading
|
||||
self.run_yes = True
|
||||
self.yes_thread = threading.Thread(target=self.run_yes_thread)
|
||||
self.yes_thread.daemon = True
|
||||
self.yes_thread.start()
|
||||
|
||||
renpy.call_screen("android_process", interface=self)
|
||||
finally:
|
||||
f.close()
|
||||
interface.hide_screen()
|
||||
|
||||
if yes and self.yes_thread:
|
||||
self.run_yes = False
|
||||
self.yes_thread.join()
|
||||
|
||||
self.process = None
|
||||
self.yes_thread = None
|
||||
|
||||
def check_process(self):
|
||||
rv = self.process.poll()
|
||||
|
||||
if rv is not None:
|
||||
if rv:
|
||||
raise subprocess.CalledProcessError(rv, self.cmd)
|
||||
else:
|
||||
return True
|
||||
|
||||
def download(self, url, dest):
|
||||
try:
|
||||
d = Downloader(url, dest)
|
||||
cancel_action = [ d.cancel, Jump("android") ]
|
||||
interface.processing(self.info_msg, show_screen=True, cancel=cancel_action, bar_value=DownloaderValue(d))
|
||||
ui.timer(.1, action=d.check, repeat=True)
|
||||
ui.interact()
|
||||
finally:
|
||||
interface.hide_screen()
|
||||
|
||||
def background(self, f):
|
||||
try:
|
||||
t = threading.Thread(target=f)
|
||||
t.start()
|
||||
|
||||
interface.processing(self.info_msg, show_screen=True)
|
||||
|
||||
while t.is_alive():
|
||||
renpy.pause(0)
|
||||
t.join(0.25)
|
||||
|
||||
finally:
|
||||
interface.hide_screen()
|
||||
|
||||
|
||||
def cancel(self):
|
||||
if self.process:
|
||||
self.process.terminate()
|
||||
|
||||
renpy.jump("android")
|
||||
|
||||
|
||||
class AndroidBuild(Action):
|
||||
"""
|
||||
@@ -321,22 +145,6 @@ init python:
|
||||
def __call__(self):
|
||||
renpy.jump(self.label)
|
||||
|
||||
class LaunchEmulator(Action):
|
||||
|
||||
def __init__(self, emulator, variants):
|
||||
self.emulator = emulator
|
||||
self.variants = variants
|
||||
|
||||
def __call__(self):
|
||||
|
||||
env = {
|
||||
"RENPY_EMULATOR" : self.emulator,
|
||||
"RENPY_VARIANT" : self.variants,
|
||||
}
|
||||
|
||||
p = project.current
|
||||
p.launch(env=env)
|
||||
|
||||
def update_android_json(p, gui):
|
||||
"""
|
||||
Updates .android.json to include the google play information.
|
||||
@@ -372,7 +180,7 @@ init python:
|
||||
with open(filename, "w") as f:
|
||||
json.dump(android_json, f)
|
||||
|
||||
def android_build(command, p=None, gui=True):
|
||||
def android_build(command, p=None, gui=True, launch=False):
|
||||
"""
|
||||
This actually builds the package.
|
||||
"""
|
||||
@@ -389,7 +197,7 @@ init python:
|
||||
|
||||
if gui:
|
||||
reporter = distribute.GuiReporter()
|
||||
rapt_interface = AndroidInterface()
|
||||
rapt_interface = MobileInterface("android")
|
||||
else:
|
||||
reporter = distribute.TextReporter()
|
||||
rapt_interface = rapt.interface.Interface()
|
||||
@@ -404,7 +212,7 @@ init python:
|
||||
)
|
||||
|
||||
with interface.nolinks():
|
||||
rapt.build.build(rapt_interface, dist, command)
|
||||
rapt.build.build(rapt_interface, dist, command, launch=launch)
|
||||
|
||||
# The android support can stick unicode into os.environ. Fix that.
|
||||
init 100 python:
|
||||
@@ -468,7 +276,8 @@ screen android:
|
||||
|
||||
frame style "l_indent":
|
||||
|
||||
has vbox
|
||||
has hbox:
|
||||
spacing 15
|
||||
|
||||
textbutton _("Phone"):
|
||||
action LaunchEmulator("touch", "small phone touch android")
|
||||
@@ -478,7 +287,7 @@ screen android:
|
||||
action LaunchEmulator("touch", "medium tablet touch android")
|
||||
hovered tt.Action(TABLET_TEXT)
|
||||
|
||||
textbutton _("Television / OUYA"):
|
||||
textbutton _("Television"):
|
||||
action LaunchEmulator("tv", "small tv ouya android")
|
||||
hovered tt.Action(OUYA_TEXT)
|
||||
|
||||
@@ -514,6 +323,10 @@ screen android:
|
||||
action AndroidIfState(state, ANDROID_OK, AndroidBuild("android_build_and_install"))
|
||||
hovered tt.Action(BUILD_AND_INSTALL_TEXT)
|
||||
|
||||
textbutton _("Build, Install & Launch"):
|
||||
action AndroidIfState(state, ANDROID_OK, AndroidBuild("android_build_install_and_launch"))
|
||||
hovered tt.Action(BUILD_INSTALL_AND_LAUNCH_TEXT)
|
||||
|
||||
add SPACER
|
||||
add SEPARATOR2
|
||||
|
||||
@@ -576,7 +389,7 @@ label android_installsdk:
|
||||
|
||||
python:
|
||||
with interface.nolinks():
|
||||
rapt.install_sdk.install_sdk(AndroidInterface())
|
||||
rapt.install_sdk.install_sdk(MobileInterface("android"))
|
||||
|
||||
jump android
|
||||
|
||||
@@ -584,7 +397,7 @@ label android_installsdk:
|
||||
label android_configure:
|
||||
|
||||
python:
|
||||
rapt.configure.configure(AndroidInterface(), project.current.path)
|
||||
rapt.configure.configure(MobileInterface("android", edit=False), project.current.path)
|
||||
|
||||
jump android
|
||||
|
||||
@@ -602,6 +415,13 @@ label android_build_and_install:
|
||||
|
||||
jump android
|
||||
|
||||
label android_build_install_and_launch:
|
||||
|
||||
$ android_build([ 'release', 'install' ], launch=True)
|
||||
|
||||
jump android
|
||||
|
||||
|
||||
label android_connect:
|
||||
|
||||
python hide:
|
||||
@@ -641,7 +461,7 @@ label android_connect:
|
||||
|
||||
persistent.connect_address = address
|
||||
|
||||
rapt_interface = AndroidInterface()
|
||||
rapt_interface = MobileInterface("android")
|
||||
rapt.build.connect(rapt_interface, address)
|
||||
|
||||
jump android
|
||||
@@ -650,7 +470,7 @@ label android_disconnect:
|
||||
|
||||
python hide:
|
||||
|
||||
rapt_interface = AndroidInterface()
|
||||
rapt_interface = MobileInterface("android")
|
||||
rapt.build.disconnect(rapt_interface)
|
||||
|
||||
jump android
|
||||
@@ -661,12 +481,13 @@ init python:
|
||||
ap = renpy.arguments.ArgumentParser()
|
||||
ap.add_argument("project", help="The path to the project directory.")
|
||||
ap.add_argument("command", help="Commands to pass to ant. (Try 'release' 'install'.)", nargs='+')
|
||||
ap.add_argument("--launch", action="store_true", help="Launches the app after build and install compete.")
|
||||
|
||||
args = ap.parse_args()
|
||||
|
||||
p = project.Project(args.project)
|
||||
|
||||
android_build(args.command, p=p, gui=False)
|
||||
android_build(args.command, p=p, gui=False, launch=args.launch)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
init python:
|
||||
|
||||
|
||||
def choose_directory(path):
|
||||
"""
|
||||
Pops up a directory chooser.
|
||||
|
||||
`path`
|
||||
The directory that is selected by default. If None, config.renpy_base
|
||||
is selected.
|
||||
|
||||
Returns a (path, is_default) tuple, where path is the chosen directory,
|
||||
and is_default is true if and only if it was chosen by default mechanism
|
||||
rather than user choice.
|
||||
"""
|
||||
|
||||
if path:
|
||||
default_path = path
|
||||
else:
|
||||
try:
|
||||
default_path = os.path.dirname(os.path.abspath(config.renpy_base))
|
||||
except:
|
||||
default_path = os.path.abspath(config.renpy_base)
|
||||
|
||||
if EasyDialogs:
|
||||
|
||||
choice = EasyDialogs.AskFolder(defaultLocation=default_path, wanted=unicode)
|
||||
|
||||
if choice is not None:
|
||||
path = choice
|
||||
else:
|
||||
path = None
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
|
||||
cmd = [ "/usr/bin/python", os.path.join(config.gamedir, "tkaskdir.py"), renpy.fsencode(default_path) ]
|
||||
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
choice = p.stdout.read()
|
||||
code = p.wait()
|
||||
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
code = 0
|
||||
choice = ""
|
||||
path = None
|
||||
|
||||
interface.error(_("Ren'Py was unable to run python with tkinter to choose the directory. Please install the python-tk or tkinter package."), label=None)
|
||||
|
||||
if code:
|
||||
interface.error(_("Ren'Py was unable to run python with tkinter to choose the directory. Please install the python-tk or tkinter package."), label=None)
|
||||
|
||||
elif choice:
|
||||
path = choice.decode("utf-8")
|
||||
|
||||
is_default = False
|
||||
|
||||
if path is None:
|
||||
path = default_path
|
||||
is_default = True
|
||||
|
||||
path = renpy.fsdecode(path)
|
||||
|
||||
if not os.path.isdir(path):
|
||||
path = os.path.abspath(config.renpy_base)
|
||||
is_default = True
|
||||
|
||||
return path, is_default
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -399,13 +399,13 @@ init python in distribute:
|
||||
# Add Python (with the same name as our executables)
|
||||
self.add_python()
|
||||
|
||||
# Build the mac app.
|
||||
# Build the mac app and windows exes.
|
||||
self.add_mac_files()
|
||||
self.add_windows_files()
|
||||
|
||||
# Add generated/special files.
|
||||
if not build['renpy']:
|
||||
self.add_renpy_files()
|
||||
self.add_windows_files()
|
||||
|
||||
# Assign the x-bit as necessary.
|
||||
self.mark_executable()
|
||||
@@ -630,6 +630,9 @@ init python in distribute:
|
||||
],
|
||||
)
|
||||
|
||||
if self.build.get('allow_integrated_gpu', False):
|
||||
plist["NSSupportsAutomaticGraphicsSwitching"] = True
|
||||
|
||||
rv = self.temp_filename("Info.plist")
|
||||
plistlib.writePlist(plist, rv)
|
||||
return rv
|
||||
@@ -663,10 +666,10 @@ init python in distribute:
|
||||
os.path.join(config.renpy_base, "lib/darwin-x86_64/pythonw"),
|
||||
True)
|
||||
|
||||
self.add_file(
|
||||
windows,
|
||||
"lib/windows-i686/" + self.executable_name + ".exe",
|
||||
os.path.join(config.renpy_base, "lib/windows-i686/pythonw.exe"))
|
||||
# self.add_file(
|
||||
# windows,
|
||||
# "lib/windows-i686/" + self.executable_name + ".exe",
|
||||
# os.path.join(config.renpy_base, "lib/windows-i686/renpy.exe"))
|
||||
|
||||
def add_mac_files(self):
|
||||
"""
|
||||
@@ -700,19 +703,31 @@ init python in distribute:
|
||||
Adds windows-specific files.
|
||||
"""
|
||||
|
||||
if self.build['renpy']:
|
||||
windows = 'binary'
|
||||
else:
|
||||
windows = 'windows'
|
||||
|
||||
icon_fn = os.path.join(self.project.path, "icon.ico")
|
||||
old_exe_fn = os.path.join(config.renpy_base, "renpy.exe")
|
||||
old_main_fn = os.path.join(config.renpy_base, "lib/windows-i686/renpy.exe")
|
||||
|
||||
if os.path.exists(icon_fn):
|
||||
exe_fn = self.temp_filename("renpy.exe")
|
||||
main_fn = self.temp_filename("main.exe")
|
||||
|
||||
with open(exe_fn, "wb") as f:
|
||||
f.write(change_icons(old_exe_fn, icon_fn))
|
||||
|
||||
with open(main_fn, "wb") as f:
|
||||
f.write(change_icons(old_main_fn, icon_fn))
|
||||
|
||||
else:
|
||||
exe_fn = old_exe_fn
|
||||
main_fn = old_main_fn
|
||||
|
||||
self.add_file("windows", "renpy.exe", exe_fn)
|
||||
self.add_file(windows, self.exe, exe_fn)
|
||||
self.add_file(windows, "lib/windows-i686/" + self.exe, main_fn)
|
||||
|
||||
def mark_executable(self):
|
||||
"""
|
||||
@@ -737,9 +752,7 @@ init python in distribute:
|
||||
parts = fn.split('/')
|
||||
p = parts[0]
|
||||
|
||||
if p == "renpy.exe":
|
||||
p = self.exe
|
||||
elif p == "renpy.sh":
|
||||
if p == "renpy.sh":
|
||||
p = self.sh
|
||||
elif p == "renpy.py":
|
||||
p = self.py
|
||||
@@ -866,7 +879,7 @@ init python in distribute:
|
||||
if not data:
|
||||
break
|
||||
|
||||
sums.write(struct.pack("I", zlib.adler32(data) & 0xffffffff))
|
||||
sums.write(struct.pack("<I", zlib.adler32(data) & 0xffffffff))
|
||||
|
||||
if self.include_update and not self.build_update and not dlc:
|
||||
os.unlink(update_fn)
|
||||
@@ -888,12 +901,15 @@ init python in distribute:
|
||||
with open(fn, "rb") as f:
|
||||
digest = hashlib.sha256(f.read()).hexdigest()
|
||||
|
||||
sums_size = os.path.getsize(self.destination + "/" + self.base_name + "-" + variant + ".sums")
|
||||
|
||||
index[variant] = {
|
||||
"version" : self.update_version,
|
||||
"pretty_version" : self.pretty_version,
|
||||
"digest" : digest,
|
||||
"zsync_url" : self.base_name + "-" + variant + ".zsync",
|
||||
"sums_url" : self.base_name + "-" + variant + ".sums",
|
||||
"sums_size" : sums_size,
|
||||
"json_url" : self.base_name + "-" + variant + ".update.json",
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -191,6 +191,7 @@ screen build_distributions:
|
||||
has vbox
|
||||
|
||||
textbutton _("Edit options.rpy") action editor.Edit("game/options.rpy", check=True)
|
||||
textbutton _("Add from clauses to calls, once") action Jump("add_from")
|
||||
textbutton _("Refresh") action Jump("build_distributions")
|
||||
|
||||
|
||||
@@ -219,14 +220,44 @@ screen build_distributions:
|
||||
$ description = pkg["description"]
|
||||
textbutton "[description!q]" action PackageToggle(pkg["name"]) style "l_checkbox"
|
||||
|
||||
add SPACER
|
||||
add SPACER
|
||||
add HALF_SPACER
|
||||
add SEPARATOR2
|
||||
|
||||
frame:
|
||||
style "l_indent"
|
||||
has vbox
|
||||
|
||||
text _("Options:")
|
||||
|
||||
add HALF_SPACER
|
||||
|
||||
if project.current.dump["build"]["include_update"]:
|
||||
textbutton _("Build Updates") action DataToggle("build_update") style "l_checkbox"
|
||||
|
||||
textbutton _("Add from clauses to calls") action DataToggle("add_from") style "l_checkbox"
|
||||
|
||||
|
||||
textbutton _("Back") action Jump("front_page") style "l_left_button"
|
||||
textbutton _("Build") action Jump("distribute") style "l_right_button"
|
||||
textbutton _("Build") action Jump("start_distribute") style "l_right_button"
|
||||
|
||||
label add_from_common:
|
||||
python:
|
||||
interface.processing(_("Adding from clauses to call statements that do not have them."))
|
||||
project.current.launch([ "add_from" ], wait=True)
|
||||
|
||||
return
|
||||
|
||||
label add_from:
|
||||
call add_from_common
|
||||
jump build_distributions
|
||||
|
||||
|
||||
label start_distribute:
|
||||
if project.current.data["add_from"]:
|
||||
call add_from_common
|
||||
|
||||
jump distribute
|
||||
|
||||
label build_update_dump:
|
||||
python:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -197,18 +197,19 @@ screen front_page_project:
|
||||
textbutton _("base") action OpenDirectory(".")
|
||||
# textbutton _("images") action OpenDirectory("game/images") style "l_list"
|
||||
# textbutton _("save") action None style "l_list"
|
||||
|
||||
|
||||
vbox:
|
||||
if persistent.show_edit_funcs:
|
||||
|
||||
label _("Edit File") style "l_label_small"
|
||||
label _("Edit File") style "l_label_small"
|
||||
|
||||
frame style "l_indent":
|
||||
has vbox
|
||||
frame style "l_indent":
|
||||
has vbox
|
||||
|
||||
textbutton "script.rpy" action editor.Edit("game/script.rpy", check=True)
|
||||
textbutton "options.rpy" action editor.Edit("game/options.rpy", check=True)
|
||||
textbutton "screens.rpy" action editor.Edit("game/screens.rpy", check=True)
|
||||
textbutton _("All script files") action editor.EditAll()
|
||||
textbutton "script.rpy" action editor.Edit("game/script.rpy", check=True)
|
||||
textbutton "options.rpy" action editor.Edit("game/options.rpy", check=True)
|
||||
textbutton "screens.rpy" action editor.Edit("game/screens.rpy", check=True)
|
||||
textbutton _("All script files") action editor.EditAll()
|
||||
|
||||
add SPACER
|
||||
add SEPARATOR
|
||||
@@ -242,6 +243,7 @@ screen front_page_project:
|
||||
textbutton _("Build Distributions") action Jump("build_distributions")
|
||||
|
||||
textbutton _("Android") action Jump("android")
|
||||
textbutton _("iOS") action Jump("ios")
|
||||
textbutton _("Generate Translations") action Jump("translate")
|
||||
textbutton _("Extract Dialogue") action Jump("extract_dialogue")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
init python:
|
||||
IOS_NO_RENIOS = 0
|
||||
IOS_NO_DIRECTORY = 1
|
||||
IOS_NO_PROJECT = 2
|
||||
IOS_OK = 3
|
||||
|
||||
IOS_NO_RENIOS_TEXT = _("To build iOS packages, please download renios, unzip it, and place it into the Ren'Py directory. Then restart the Ren'Py launcher.")
|
||||
IOS_NO_DIRECTORY_TEXT = _("The directory in where Xcode projects will be placed has not been selected. Choose 'Select Directory' to select it.")
|
||||
IOS_NO_PROJECT_TEXT = _("There is no Xcode project corresponding to the current Ren'Py project. Choose 'Create Xcode Project' to create one.")
|
||||
IOS_OK_TEXT = _("An Xcode project exists. Choose 'Update Xcode Project' to update it with the latest game files, or use Xcode to build and install it.")
|
||||
|
||||
IPHONE_TEXT = _("Attempts to emulate an iPhone.\n\nTouch input is emulated through the mouse, but only when the button is held down.")
|
||||
IPAD_TEXT = _("Attempts to emulate an iPad.\n\nTouch input is emulated through the mouse, but only when the button is held down.")
|
||||
|
||||
IOS_SELECT_DIRECTORY_TEXT = _("Selects the directory where Xcode projects will be placed.")
|
||||
IOS_CREATE_PROJECT_TEXT = _("Creates an Xcode project corresponding to the current Ren'Py project.")
|
||||
IOS_UPDATE_PROJECT_TEXT = _("Updates the Xcode project with the latest game files. This must be done each time the Ren'Py project changes.")
|
||||
IOS_XCODE_TEXT = _("Opens the Xcode project in Xcode.")
|
||||
|
||||
IOS_OPEN_DIRECTORY_TEXT = _("Opens the directory containing Xcode projects.")
|
||||
|
||||
def find_renios():
|
||||
|
||||
global RENIOS_PATH
|
||||
|
||||
candidates = [ ]
|
||||
|
||||
RENIOS_PATH = os.path.join(config.renpy_base, "renios")
|
||||
|
||||
if os.path.isdir(RENIOS_PATH):
|
||||
import sys
|
||||
sys.path.insert(0, os.path.join(RENIOS_PATH, "buildlib"))
|
||||
else:
|
||||
RENIOS_PATH = None
|
||||
|
||||
find_renios()
|
||||
|
||||
if RENIOS_PATH:
|
||||
import renios.create
|
||||
|
||||
def IOSState():
|
||||
if not RENIOS_PATH:
|
||||
return IOS_NO_RENIOS
|
||||
elif not persistent.xcode_projects_directory:
|
||||
return IOS_NO_DIRECTORY
|
||||
elif not os.path.exists(xcode_project()):
|
||||
return IOS_NO_PROJECT
|
||||
else:
|
||||
return IOS_OK
|
||||
|
||||
def IOSStateText(state):
|
||||
if state == IOS_NO_RENIOS:
|
||||
return IOS_NO_RENIOS_TEXT
|
||||
elif state == IOS_NO_DIRECTORY:
|
||||
return IOS_NO_DIRECTORY_TEXT
|
||||
elif state == IOS_NO_PROJECT:
|
||||
return IOS_NO_PROJECT_TEXT
|
||||
else:
|
||||
return IOS_OK_TEXT
|
||||
|
||||
def IOSIfState(state, needed, action):
|
||||
"""
|
||||
If `state` is `needed` or better, `action` is returned. Otherwise,
|
||||
returns None, disabling the button.
|
||||
"""
|
||||
|
||||
if state >= needed:
|
||||
return action
|
||||
else:
|
||||
return None
|
||||
|
||||
xcode_name_cache = { }
|
||||
|
||||
def xcode_name(s):
|
||||
"""
|
||||
Returns a version of `s` that's safe to use in Xcode.
|
||||
"""
|
||||
|
||||
if s in xcode_name_cache:
|
||||
return xcode_name_cache[s]
|
||||
|
||||
s = re.sub(r'[^\w\-\.]', '', s)
|
||||
xcode_name_cache[s] = s
|
||||
return s
|
||||
|
||||
def xcode_project(p=None):
|
||||
"""
|
||||
Return the path to the Xcode project corresponding to `p`, or the current
|
||||
project if `p` is None
|
||||
"""
|
||||
|
||||
if p is None:
|
||||
p = project.current
|
||||
|
||||
if persistent.xcode_projects_directory is None:
|
||||
raise Exception("The Xcode projects directory has not been set.")
|
||||
|
||||
return os.path.join(persistent.xcode_projects_directory, xcode_name(p.name))
|
||||
|
||||
def ios_create(p=None, gui=True):
|
||||
|
||||
dest = xcode_project(p)
|
||||
|
||||
if os.path.exists(dest):
|
||||
interface.yesno(_("The Xcode project already exists. Would you like to rename the old project, and replace it with a new one?"), no=Jump("ios"))
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
i += 1
|
||||
backup = dest + "." + str(i)
|
||||
if not os.path.exists(backup):
|
||||
break
|
||||
|
||||
os.rename(dest, backup)
|
||||
|
||||
iface = MobileInterface("ios")
|
||||
renios.create.create_project(iface, dest)
|
||||
|
||||
ios_populate(p, gui=gui)
|
||||
|
||||
def ios_populate(p=None, gui=True):
|
||||
"""
|
||||
This actually builds the package.
|
||||
"""
|
||||
|
||||
import shutil
|
||||
|
||||
if p is None:
|
||||
p = project.current
|
||||
|
||||
dist = os.path.join(xcode_project(p), "base")
|
||||
|
||||
if os.path.exists(dist):
|
||||
shutil.rmtree(dist)
|
||||
|
||||
if gui:
|
||||
reporter = distribute.GuiReporter()
|
||||
else:
|
||||
reporter = distribute.TextReporter()
|
||||
|
||||
distribute.Distributor(p,
|
||||
reporter=reporter,
|
||||
packages=[ 'ios' ],
|
||||
build_update=False,
|
||||
noarchive=True,
|
||||
packagedest=dist,
|
||||
report_success=False,
|
||||
)
|
||||
|
||||
for fn in os.listdir(dist):
|
||||
if fn.endswith(".py"):
|
||||
os.rename(
|
||||
os.path.join(dist, fn),
|
||||
os.path.join(dist, "main.py"),
|
||||
)
|
||||
|
||||
break
|
||||
|
||||
def launch_xcode():
|
||||
dist = xcode_project(None)
|
||||
base = os.path.basename(dist)
|
||||
xcodeproj = "{}/{}.xcodeproj".format(dist, base)
|
||||
|
||||
subprocess.call([ 'open', renpy.fsencode(xcodeproj) ])
|
||||
|
||||
screen ios:
|
||||
|
||||
default tt = Tooltip(None)
|
||||
$ state = IOSState()
|
||||
|
||||
frame:
|
||||
style_group "l"
|
||||
style "l_root"
|
||||
|
||||
window:
|
||||
|
||||
has vbox
|
||||
|
||||
label _("iOS: [project.current.name!q]")
|
||||
|
||||
add HALF_SPACER
|
||||
|
||||
hbox:
|
||||
|
||||
# Left side.
|
||||
frame:
|
||||
style "l_indent"
|
||||
xmaximum ONEHALF
|
||||
xfill True
|
||||
|
||||
has vbox
|
||||
|
||||
add SEPARATOR2
|
||||
|
||||
frame:
|
||||
style "l_indent"
|
||||
has vbox
|
||||
|
||||
text _("Emulation:")
|
||||
|
||||
add HALF_SPACER
|
||||
|
||||
frame style "l_indent":
|
||||
|
||||
has hbox:
|
||||
spacing 15
|
||||
|
||||
textbutton _("iPhone"):
|
||||
action LaunchEmulator("ios-touch", "small phone touch ios")
|
||||
hovered tt.Action(IPHONE_TEXT)
|
||||
|
||||
textbutton _("iPad"):
|
||||
action LaunchEmulator("ios-touch", "medium tablet touch ios")
|
||||
hovered tt.Action(IPAD_TEXT)
|
||||
|
||||
|
||||
add SPACER
|
||||
add SEPARATOR2
|
||||
|
||||
frame:
|
||||
style "l_indent"
|
||||
has vbox
|
||||
|
||||
text _("Build:")
|
||||
|
||||
add HALF_SPACER
|
||||
|
||||
frame style "l_indent":
|
||||
|
||||
has vbox
|
||||
|
||||
textbutton _("Select Xcode Projects Directory"):
|
||||
action IOSIfState(state, IOS_NO_DIRECTORY, Jump("select_xcode_projects_directory"))
|
||||
hovered tt.Action(IOS_SELECT_DIRECTORY_TEXT)
|
||||
|
||||
textbutton _("Create Xcode Project"):
|
||||
action IOSIfState(state, IOS_NO_PROJECT, Jump("create_xcode_project"))
|
||||
hovered tt.Action(IOS_CREATE_PROJECT_TEXT)
|
||||
|
||||
textbutton _("Update Xcode Project"):
|
||||
action IOSIfState(state, IOS_NO_PROJECT, Jump("update_xcode_project"))
|
||||
hovered tt.Action(IOS_UPDATE_PROJECT_TEXT)
|
||||
|
||||
if renpy.macintosh:
|
||||
textbutton _("Launch Xcode"):
|
||||
action IOSIfState(state, IOS_OK, launch_xcode)
|
||||
hovered tt.Action(IOS_XCODE_TEXT)
|
||||
|
||||
# textbutton _("Configure"):
|
||||
# action AndroidIfState(state, ANDROID_NO_CONFIG, Jump("android_configure"))
|
||||
# hovered tt.Action(CONFIGURE_TEXT)
|
||||
#
|
||||
# textbutton _("Build Package"):
|
||||
# action AndroidIfState(state, ANDROID_OK, AndroidBuild("android_build"))
|
||||
# hovered tt.Action(BUILD_TEXT)
|
||||
#
|
||||
# textbutton _("Build & Install"):
|
||||
# action AndroidIfState(state, ANDROID_OK, AndroidBuild("android_build_and_install"))
|
||||
# hovered tt.Action(BUILD_AND_INSTALL_TEXT)
|
||||
#
|
||||
# textbutton _("Build, Install & Launch"):
|
||||
# action AndroidIfState(state, ANDROID_OK, AndroidBuild("android_build_install_and_launch"))
|
||||
# hovered tt.Action(BUILD_INSTALL_AND_LAUNCH_TEXT)
|
||||
|
||||
add SPACER
|
||||
add SEPARATOR2
|
||||
|
||||
frame:
|
||||
style "l_indent"
|
||||
has vbox
|
||||
|
||||
text _("Other:")
|
||||
|
||||
add HALF_SPACER
|
||||
|
||||
frame style "l_indent":
|
||||
|
||||
has vbox
|
||||
|
||||
textbutton _("Open Xcode Projects Directory"):
|
||||
action IOSIfState(state, IOS_NO_PROJECT, OpenDirectory(persistent.xcode_projects_directory, absolute=True))
|
||||
hovered tt.Action(IOS_OPEN_DIRECTORY_TEXT)
|
||||
|
||||
|
||||
# Right side.
|
||||
frame:
|
||||
style "l_indent"
|
||||
xmaximum ONEHALF
|
||||
xfill True
|
||||
|
||||
has vbox
|
||||
|
||||
add SEPARATOR2
|
||||
|
||||
frame:
|
||||
style "l_indent"
|
||||
has vbox
|
||||
|
||||
add SPACER
|
||||
|
||||
if tt.value:
|
||||
text tt.value
|
||||
else:
|
||||
text IOSStateText(state)
|
||||
|
||||
|
||||
textbutton _("Back") action Jump("front_page") style "l_left_button"
|
||||
|
||||
|
||||
label ios:
|
||||
|
||||
if RENIOS_PATH is None:
|
||||
$ interface.yesno(_("Before packaging iOS apps, you'll need to download renios, Ren'Py's iOS support. Would you like to download renios now?"), no=Jump("front_page"))
|
||||
$ add_dlc("renios", restart=True)
|
||||
|
||||
call screen ios
|
||||
|
||||
label select_xcode_projects_directory:
|
||||
|
||||
python hide:
|
||||
|
||||
interface.interaction(_("XCODE PROJECTS DIRECTORY"), _("Please choose the Xcode Projects Directory using the directory chooser.\n{b}The directory chooser may have opened behind this window.{/b}"))
|
||||
|
||||
path, is_default = choose_directory(persistent.xcode_projects_directory)
|
||||
|
||||
if is_default:
|
||||
interface.info(_("Ren'Py has set the Xcode Projects Directory to:"), "[path!q]", path=path)
|
||||
|
||||
persistent.xcode_projects_directory = path
|
||||
|
||||
jump ios
|
||||
|
||||
label create_xcode_project:
|
||||
|
||||
$ ios_create(None, True)
|
||||
|
||||
jump ios
|
||||
|
||||
label update_xcode_project:
|
||||
$ ios_populate(None, True)
|
||||
|
||||
jump ios
|
||||
@@ -0,0 +1,234 @@
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# This file contains mobile build things that are shared by the android
|
||||
# and iOS builds.
|
||||
|
||||
init python:
|
||||
|
||||
class LaunchEmulator(Action):
|
||||
|
||||
def __init__(self, emulator, variants):
|
||||
self.emulator = emulator
|
||||
self.variants = variants
|
||||
|
||||
def __call__(self):
|
||||
|
||||
env = {
|
||||
"RENPY_EMULATOR" : self.emulator,
|
||||
"RENPY_VARIANT" : self.variants,
|
||||
}
|
||||
|
||||
p = project.current
|
||||
p.launch(env=env)
|
||||
|
||||
class MobileInterface(object):
|
||||
"""
|
||||
This is used to interface between the launcher and RAPT/RENIOS.
|
||||
"""
|
||||
|
||||
def __init__(self, platform, edit=True):
|
||||
"""
|
||||
`platform`
|
||||
The name of the platform we're using for. Used for libraries,
|
||||
cancel labels, and logfiles.
|
||||
|
||||
`edit`
|
||||
If true, we launch the log file in the editor on failure.
|
||||
"""
|
||||
|
||||
self.platform = platform
|
||||
self.edit = edit
|
||||
|
||||
self.process = None
|
||||
self.filename = project.current.temp_filename(platform + ".txt")
|
||||
|
||||
self.info_msg = ""
|
||||
|
||||
with open(self.filename, "w"):
|
||||
pass
|
||||
|
||||
def log(self, msg):
|
||||
with open(self.filename, "a") as f:
|
||||
f.write("\n")
|
||||
f.write(msg)
|
||||
f.write("\n")
|
||||
|
||||
def info(self, prompt):
|
||||
self.info_msg = prompt
|
||||
interface.processing(prompt, pause=False)
|
||||
self.log(prompt)
|
||||
|
||||
def yesno(self, prompt, submessage=None):
|
||||
return interface.yesno(prompt, submessage=submessage)
|
||||
|
||||
def yesno_choice(self, prompt, default=None):
|
||||
choices = [ (True, "Yes"), (False, "No") ]
|
||||
return interface.choice(prompt, choices, default)
|
||||
|
||||
def terms(self, url, prompt):
|
||||
submessage = _("{a=%s}%s{/a}") % (url, url)
|
||||
|
||||
if not interface.yesno(prompt, submessage=submessage):
|
||||
self.fail("You must accept the terms and conditions to proceed.", edit=False)
|
||||
|
||||
|
||||
def input(self, prompt, empty=None):
|
||||
|
||||
if empty is None:
|
||||
empty = ''
|
||||
|
||||
while True:
|
||||
rv = interface.input(_("QUESTION"), prompt, default=empty, cancel=Jump("android"))
|
||||
|
||||
rv = rv.strip()
|
||||
|
||||
if rv:
|
||||
return rv
|
||||
|
||||
def choice(self, prompt, choices, default):
|
||||
return interface.choice(prompt, choices, default, cancel=Jump("android"))
|
||||
|
||||
def fail(self, prompt, edit=True):
|
||||
self.log(prompt)
|
||||
prompt = re.sub(r'(http://\S+)', r'{a=\1}\1{/a}', prompt)
|
||||
|
||||
# Open android.txt in the editor.
|
||||
if edit and self.edit:
|
||||
editor.EditAbsolute(self.filename)()
|
||||
|
||||
interface.error(prompt, label="android")
|
||||
|
||||
def success(self, prompt):
|
||||
self.log(prompt)
|
||||
interface.info(prompt, pause=False)
|
||||
|
||||
def final_success(self, prompt):
|
||||
self.log(prompt)
|
||||
interface.info(prompt, label="android")
|
||||
|
||||
def run_yes_thread(self):
|
||||
import time
|
||||
|
||||
try:
|
||||
while self.run_yes:
|
||||
self.process.stdin.write('y\n')
|
||||
self.process.stdin.flush()
|
||||
time.sleep(.2)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def call(self, cmd, cancel=False, use_path=False, yes=False):
|
||||
|
||||
cmd = [ renpy.fsencode(i) for i in cmd ]
|
||||
|
||||
self.cmd = cmd
|
||||
|
||||
f = open(self.filename, "a")
|
||||
|
||||
f.write("\n\n\n")
|
||||
|
||||
if cancel:
|
||||
cancel_action = self.cancel
|
||||
else:
|
||||
cancel_action = None
|
||||
|
||||
startupinfo = None
|
||||
if renpy.windows:
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
|
||||
self.yes_thread = None
|
||||
|
||||
try:
|
||||
interface.processing(self.info_msg, show_screen=True, cancel=cancel_action)
|
||||
|
||||
kwargs = { }
|
||||
if yes:
|
||||
kwargs["stdin"] = subprocess.PIPE
|
||||
|
||||
try:
|
||||
self.process = subprocess.Popen(cmd, cwd=renpy.fsencode(RAPT_PATH), stdout=f, stderr=f, startupinfo=startupinfo, **kwargs)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc(file=f)
|
||||
raise
|
||||
|
||||
if yes:
|
||||
import threading
|
||||
self.run_yes = True
|
||||
self.yes_thread = threading.Thread(target=self.run_yes_thread)
|
||||
self.yes_thread.daemon = True
|
||||
self.yes_thread.start()
|
||||
|
||||
renpy.call_screen("android_process", interface=self)
|
||||
finally:
|
||||
f.close()
|
||||
interface.hide_screen()
|
||||
|
||||
if yes and self.yes_thread:
|
||||
self.run_yes = False
|
||||
self.yes_thread.join()
|
||||
|
||||
self.process = None
|
||||
self.yes_thread = None
|
||||
|
||||
def check_process(self):
|
||||
rv = self.process.poll()
|
||||
|
||||
if rv is not None:
|
||||
if rv:
|
||||
raise subprocess.CalledProcessError(rv, self.cmd)
|
||||
else:
|
||||
return True
|
||||
|
||||
def download(self, url, dest):
|
||||
try:
|
||||
d = Downloader(url, dest)
|
||||
cancel_action = [ d.cancel, Jump(self.platform) ]
|
||||
interface.processing(self.info_msg, show_screen=True, cancel=cancel_action, bar_value=DownloaderValue(d))
|
||||
ui.timer(.1, action=d.check, repeat=True)
|
||||
ui.interact()
|
||||
finally:
|
||||
interface.hide_screen()
|
||||
|
||||
def background(self, f):
|
||||
try:
|
||||
t = threading.Thread(target=f)
|
||||
t.start()
|
||||
|
||||
interface.processing(self.info_msg, show_screen=True)
|
||||
|
||||
while t.is_alive():
|
||||
renpy.pause(0)
|
||||
t.join(0.25)
|
||||
|
||||
finally:
|
||||
interface.hide_screen()
|
||||
|
||||
|
||||
def cancel(self):
|
||||
if self.process:
|
||||
self.process.terminate()
|
||||
|
||||
renpy.jump(self.platform)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -245,13 +245,22 @@ init python:
|
||||
|
||||
## Now, add the Ren'Py distribution in using classify_renpy.
|
||||
|
||||
build.classify_renpy("rapt/**", "rapt")
|
||||
|
||||
build.classify_renpy("**~", None)
|
||||
build.classify_renpy("**/#*", None)
|
||||
build.classify_renpy("**/thumbs.db", None)
|
||||
build.classify_renpy("**/.*", None)
|
||||
|
||||
build.classify_renpy("rapt/**", "rapt")
|
||||
|
||||
build.classify_renpy("renios/prototype/base/", None)
|
||||
build.classify_renpy("renios/prototype/prototype.xcodeproj/*.xcworkspace/", None)
|
||||
build.classify_renpy("renios/prototype/prototype.xcodeproj/xcuserdata/", None)
|
||||
build.classify_renpy("renios/prototype/**", "renios")
|
||||
build.classify_renpy("renios/buildlib/**", "renios")
|
||||
build.classify_renpy("renios/ios.py", "renios")
|
||||
build.classify_renpy("renios/", "renios")
|
||||
|
||||
build.classify_renpy("**.old", None)
|
||||
build.classify_renpy("**.new", None)
|
||||
build.classify_renpy("**.bak", None)
|
||||
@@ -310,11 +319,12 @@ init python:
|
||||
build.classify_renpy("module/pysdlsound/*.pyx", "source")
|
||||
|
||||
# all-platforms binary.
|
||||
build.classify_renpy("lib/**/_renpysteam*", None)
|
||||
build.classify_renpy("lib/**/*steam_api*", None)
|
||||
build.classify_renpy("lib/*/renpy", None)
|
||||
build.classify_renpy("lib/*/renpy.exe", None)
|
||||
build.classify_renpy("lib/**", "binary")
|
||||
build.classify_renpy("renpy.sh", "binary")
|
||||
build.classify_renpy("renpy.exe", "binary")
|
||||
# renpy.app is now built from scratch from distribute.rpy.
|
||||
|
||||
# jedit rules.
|
||||
@@ -343,4 +353,4 @@ init python:
|
||||
build.package("editra-mac", "zip", "editra-all editra-mac", dlc=True)
|
||||
build.package("editra-windows", "zip", "editra-all editra-windows", dlc=True)
|
||||
build.package("rapt", "zip", "rapt", dlc=True)
|
||||
|
||||
build.package("renios", "zip", "renios", dlc=True)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -107,7 +107,28 @@ init python in distribute:
|
||||
"""
|
||||
|
||||
def __init__(self, filename):
|
||||
self.zipfile = ZipFile(filename, "w", zipfile.ZIP_DEFLATED)
|
||||
self.zipfile = ZipFile(filename, "w", zipfile.ZIP_DEFLATED, True)
|
||||
|
||||
def get_date_time(self, path):
|
||||
"""
|
||||
Gets the datetime for a file. If the time doesn't exist or is
|
||||
weird, use the current time instead.
|
||||
"""
|
||||
|
||||
try:
|
||||
s = os.stat(path)
|
||||
rv = time.gmtime(s.st_mtime)[:6]
|
||||
|
||||
# Check that the time is sensible.
|
||||
if rv[0] < 2000:
|
||||
rv = None
|
||||
except:
|
||||
rv = None
|
||||
|
||||
if rv is None:
|
||||
rv = time.gmtime()[:6]
|
||||
|
||||
return rv
|
||||
|
||||
def add_file(self, name, path, xbit):
|
||||
|
||||
@@ -115,13 +136,7 @@ init python in distribute:
|
||||
raise Exception("path for " + name + " must not be None.")
|
||||
|
||||
zi = zipfile.ZipInfo(name)
|
||||
|
||||
try:
|
||||
s = os.stat(path)
|
||||
zi.date_time = time.gmtime(s.st_mtime)[:6]
|
||||
except:
|
||||
zi.date_time = time.gmtime()[:6]
|
||||
|
||||
zi.date_time = self.get_date_time(path)
|
||||
zi.compress_type = zipfile.ZIP_DEFLATED
|
||||
zi.create_system = 3
|
||||
|
||||
@@ -137,9 +152,7 @@ init python in distribute:
|
||||
return
|
||||
|
||||
zi = zipfile.ZipInfo(name + "/")
|
||||
|
||||
s = os.stat(path)
|
||||
zi.date_time = time.gmtime(s.st_mtime)[:6]
|
||||
zi.date_time = self.get_date_time(path)
|
||||
zi.compress_type = zipfile.ZIP_STORED
|
||||
zi.create_system = 3
|
||||
zi.external_attr = (long(0040755) << 16) | 0x10
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -25,6 +25,9 @@ init python:
|
||||
|
||||
config.gl_enable = persistent.gl_enable
|
||||
|
||||
if persistent.show_edit_funcs is None:
|
||||
persistent.show_edit_funcs = True
|
||||
|
||||
if persistent.windows_console is None:
|
||||
persistent.windows_console = False
|
||||
|
||||
@@ -168,7 +171,9 @@ screen preferences:
|
||||
|
||||
textbutton _("Hardware rendering") style "l_checkbox" action ToggleField(persistent, "gl_enable")
|
||||
textbutton _("Show templates") style "l_checkbox" action ToggleField(persistent, "show_templates")
|
||||
textbutton _("Show edit buttons") style "l_checkbox" action ToggleField(persistent, "show_edit_funcs")
|
||||
textbutton _("Large fonts") style "l_checkbox" action [ ToggleField(persistent, "large_print"), renpy.utter_restart ]
|
||||
textbutton _("Generate empty strings for translations") style "l_checkbox" action ToggleField(persistent, "generate_empty_strings")
|
||||
|
||||
if renpy.windows:
|
||||
textbutton _("Console output") style "l_checkbox" action ToggleField(persistent, "windows_console")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -121,6 +121,7 @@ init python in project:
|
||||
|
||||
data.setdefault("build_update", False)
|
||||
data.setdefault("packages", [ "all" ])
|
||||
data.setdefault("add_from", True)
|
||||
|
||||
def make_tmp(self):
|
||||
"""
|
||||
@@ -553,62 +554,12 @@ label choose_projects_directory:
|
||||
|
||||
interface.interaction(_("PROJECTS DIRECTORY"), _("Please choose the projects directory using the directory chooser.\n{b}The directory chooser may have opened behind this window.{/b}"), _("This launcher will scan for projects in this directory, will create new projects in this directory, and will place built projects into this directory."),)
|
||||
|
||||
path = persistent.projects_directory
|
||||
path, is_default = choose_directory(persistent.projects_directory)
|
||||
|
||||
if path:
|
||||
default_path = path
|
||||
else:
|
||||
try:
|
||||
default_path = os.path.dirname(os.path.abspath(config.renpy_base))
|
||||
except:
|
||||
default_path = os.path.abspath(config.renpy_base)
|
||||
|
||||
|
||||
if EasyDialogs:
|
||||
|
||||
choice = EasyDialogs.AskFolder(defaultLocation=default_path, wanted=unicode)
|
||||
|
||||
if choice is not None:
|
||||
path = choice
|
||||
else:
|
||||
path = None
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
|
||||
cmd = [ "/usr/bin/python", os.path.join(config.gamedir, "tkaskdir.py"), renpy.fsencode(default_path) ]
|
||||
|
||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
choice = p.stdout.read()
|
||||
code = p.wait()
|
||||
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
code = 0
|
||||
choice = ""
|
||||
path = None
|
||||
|
||||
interface.error(_("Ren'Py was unable to run python with tkinter to choose the projects directory. Please install the python-tk or tkinter package."), label=None)
|
||||
|
||||
if code:
|
||||
interface.error(_("Ren'Py was unable to run python with tkinter to choose the projects directory. Please install the python-tk or tkinter package."), label=None)
|
||||
|
||||
elif choice:
|
||||
path = choice.decode("utf-8")
|
||||
|
||||
if path is None:
|
||||
path = default_path
|
||||
if is_default:
|
||||
interface.info(_("Ren'Py has set the projects directory to:"), "[path!q]", path=path)
|
||||
|
||||
path = renpy.fsdecode(path)
|
||||
|
||||
if os.path.isdir(path):
|
||||
persistent.projects_directory = path
|
||||
else:
|
||||
path = os.path.abspath(config.renpy_base)
|
||||
persistent.projects_directory = path
|
||||
|
||||
project.manager.scan()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -104,9 +104,9 @@ init 1 python:
|
||||
|
||||
def checkbox(full, color):
|
||||
if full:
|
||||
return im.Twocolor("images/checkbox_full.png", color, color, yalign=0.5)
|
||||
return im.Twocolor("images/checkbox_full.png", color, color, style="l_checkbox_box")
|
||||
else:
|
||||
return im.Twocolor("images/checkbox_empty.png", color, color, yalign=0.5)
|
||||
return im.Twocolor("images/checkbox_empty.png", color, color, style="l_checkbox_box")
|
||||
|
||||
init 1:
|
||||
|
||||
@@ -322,6 +322,10 @@ init 1:
|
||||
selected_hover_background checkbox(True, HOVER)
|
||||
insensitive_background checkbox(False, DISABLED)
|
||||
|
||||
style l_checkbox_box:
|
||||
yanchor 0.5
|
||||
ypos 11
|
||||
|
||||
style l_checkbox_text is l_button_text:
|
||||
selected_font LIGHT
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -3,11 +3,11 @@ translate japanese strings:
|
||||
|
||||
# game/android.rpy:12
|
||||
old "To build Android packages, please download RAPT (from {a=http://www.renpy.org/dl/android}here{/a}), unzip it, and place it into the Ren'Py directory. Then restart the Ren'Py launcher."
|
||||
new "Androidパッケージをビルドするためには{a=http://www.renpy.org/dl/android}RAPT{/a}をダウンロードして解凍し、Ren'Py ディレクトリーに配置してからランチャーを再起動してください。"
|
||||
new "Androidパッケージをビルドするためには{a=http://www.renpy.org/dl/android}RAPT{/a}をダウンロードして解凍し、Ren'Py ディレクトリーに配置してランチャーを再起動してください。"
|
||||
|
||||
# game/android.rpy:13
|
||||
old "RAPT has been installed, but you'll need to install the Android SDK before you can build Android packages. Choose Install SDK to do this."
|
||||
new "RAPT はインストールされましたが、Androidパッケージをビルドする前に Android SDK もインストールする必要があります。このためにSDKをインストールしてください。"
|
||||
new "RAPT はインストールされましたが、Androidパッケージをビルドする前に Android SDK もインストールする必要があります。SDKをインストールしてください。"
|
||||
|
||||
# game/android.rpy:14
|
||||
old "RAPT has been installed, but a key hasn't been configured. Please create a new key, or restore android.keystore."
|
||||
@@ -15,7 +15,7 @@ translate japanese strings:
|
||||
|
||||
# game/android.rpy:15
|
||||
old "The current project has not been configured. Use \"Configure\" to configure it before building."
|
||||
new "現在のプロジェクトは設定されていません。「設定」を利用してビルド前に設定してください。"
|
||||
new "現在のプロジェクトは設定がされていません。「設定」を使用してビルド前に設定してください。"
|
||||
|
||||
# game/android.rpy:16
|
||||
old "Choose \"Build\" to build the current project, or attach an Android device and choose \"Build & Install\" to build and install it on the device."
|
||||
@@ -23,23 +23,23 @@ translate japanese strings:
|
||||
|
||||
# game/android.rpy:18
|
||||
old "Attempts to emulate an Android phone.\n\nTouch input is emulated through the mouse, but only when the button is held down. Escape is mapped to the menu button, and PageUp is mapped to the back button."
|
||||
new "Android Phoneをエミュレートします。\n\nタッチ入力はマウスを利用してエミュレートされますが、ボタン押下時のみです。Escapeはメニューボタン、PageUpはバックボタンにマップされています。"
|
||||
new "Android Phoneをエミュレートします。\n\nタッチ入力はマウスを利用してエミュレートされますが、ボタン押下時のみ反応します。Escapeはメニューボタン、PageUpはバックボタンに割り当てられています。"
|
||||
|
||||
# game/android.rpy:19
|
||||
old "Attempts to emulate an Android tablet.\n\nTouch input is emulated through the mouse, but only when the button is held down. Escape is mapped to the menu button, and PageUp is mapped to the back button."
|
||||
new "Android tabletをエミュレートします。\n\nタッチ入力はマウスを利用してエミュレートされますが、ボタン押下時のみです。Escapeはメニューボタン、PageUpはバックボタンにマップされています。"
|
||||
new "Android tabletをエミュレートします。\n\nタッチ入力はマウスを利用してエミュレートされますが、ボタン押下時のみ反応します。Escapeはメニューボタン、PageUpはバックボタンに割り当てられています。"
|
||||
|
||||
# game/android.rpy:20
|
||||
old "Attempts to emulate an OUYA console.\n\nController input is mapped to the arrow keys, Enter is mapped to the select button, Escape is mapped to the menu button, and PageUp is mapped to the back button."
|
||||
new "Android OUYAをエミュレートします。\n\nコントローラーの入力は矢印キー、Enterはセレクトボタン、Escapeはメニューボタン、PageUpはバックボタンにマップされています。"
|
||||
new "Android OUYAをエミュレートします。\n\nコントローラーの入力は矢印キー、Enterはセレクトボタン、Escapeはメニューボタン、PageUpはバックボタンに割り当てられています。"
|
||||
|
||||
# game/android.rpy:22
|
||||
old "Downloads and installs the Android SDK and supporting packages. Optionally, generates the keys required to sign the package."
|
||||
new "Android SDKをダウンロード後インストールします。任意でサインに必要なキーを生成します。"
|
||||
new "Android SDKをダウンロード後インストールします。サインに必要なキーを任意で生成します。"
|
||||
|
||||
# game/android.rpy:23
|
||||
old "Configures the package name, version, and other information about this project."
|
||||
new "このプロジェクトについてパッケージ名、バージョン、その他の情報を設定してください。"
|
||||
new "このプロジェクトについてパッケージ名とバージョン、その他の情報を設定してください。"
|
||||
|
||||
# game/android.rpy:24
|
||||
old "Opens the file containing the Google Play keys in the editor.\n\nThis is only needed if the application is using an expansion APK. Read the documentation for more details."
|
||||
@@ -115,7 +115,7 @@ translate japanese strings:
|
||||
|
||||
# game/android.rpy:39
|
||||
old "Attempts to emulate a televison-based Android console, like the OUYA or Fire TV.\n\nController input is mapped to the arrow keys, Enter is mapped to the select button, Escape is mapped to the menu button, and PageUp is mapped to the back button."
|
||||
new "OUYAやFire TVのようなテレビで動作する Android デバイスをエミュレートします。\n\nコントローラーの入力は矢印キー、Enterはセレクトボタン、Escapeはメニューボタン、PageUpはバックボタンにマップされています。"
|
||||
new "OUYAやFire TVのようなテレビで動作する Android デバイスをエミュレートします。\n\nコントローラーの入力は矢印キー、Enterはセレクトボタン、Escapeはメニューボタン、PageUpはバックボタンに割り当てられています。"
|
||||
|
||||
# game/android.rpy:47
|
||||
old "Connects to an Android device running ADB in TCP/IP mode."
|
||||
@@ -161,3 +161,15 @@ translate japanese strings:
|
||||
old "The port must be a number."
|
||||
new "ポートは数字でなければなりません。"
|
||||
|
||||
# game/android.rpy:46
|
||||
old "Builds the Android package, installs it on an Android device connected to your computer, then launches the app on your device."
|
||||
new "Android パッケージをビルドして、接続された Android にインストール、 そのデバイスでアプリを起動します。"
|
||||
|
||||
# game/android.rpy:288
|
||||
old "Television"
|
||||
new "Television"
|
||||
|
||||
# game/android.rpy:324
|
||||
old "Build, Install & Launch"
|
||||
new "ビルドとインストール、起動"
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# game/choose_directory.rpy:73
|
||||
old "Ren'Py was unable to run python with tkinter to choose the directory. Please install the python-tk or tkinter package."
|
||||
new "Ren'Py は tkinter でディレクトリーを選択出来ません。 python-tk か tkinter をインストールしてください。"
|
||||
|
||||
Regular → Executable
+493
-499
@@ -1,499 +1,493 @@
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00action_file.rpy:124
|
||||
old "%b %d, %H:%M"
|
||||
new "%m月%d日, %H:%M"
|
||||
|
||||
# renpy/common/00action_file.rpy:587
|
||||
old "Quick save complete."
|
||||
new "クイックセーブ完了。"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00gallery.rpy:521
|
||||
old "Image [index] of [count] locked."
|
||||
new "画像 [index] / [count] はロックされています。"
|
||||
|
||||
# renpy/common/00gallery.rpy:539
|
||||
old "prev"
|
||||
new "前へ"
|
||||
|
||||
# renpy/common/00gallery.rpy:540
|
||||
old "next"
|
||||
new "次へ"
|
||||
|
||||
# renpy/common/00gallery.rpy:541
|
||||
old "slideshow"
|
||||
new "スライドショー"
|
||||
|
||||
# renpy/common/00gallery.rpy:542
|
||||
old "return"
|
||||
new "戻る"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00gltest.rpy:50
|
||||
old "Graphics Acceleration"
|
||||
new "グラフィック・アクセラレーション"
|
||||
|
||||
# renpy/common/00gltest.rpy:54
|
||||
old "Automatically Choose"
|
||||
new "自動選択"
|
||||
|
||||
# renpy/common/00gltest.rpy:59
|
||||
old "Force Angle/DirectX Renderer"
|
||||
new "Angle/DirectX による描画を強制"
|
||||
|
||||
# renpy/common/00gltest.rpy:63
|
||||
old "Force OpenGL Renderer"
|
||||
new "OpenGL による描画を強制"
|
||||
|
||||
# renpy/common/00gltest.rpy:67
|
||||
old "Force Software Renderer"
|
||||
new "ソフトウェアによる描画を強制"
|
||||
|
||||
# renpy/common/00gltest.rpy:73
|
||||
old "Changes will take effect the next time this program is run."
|
||||
new "変更は、次にプログラムを起動した時に反映されます。"
|
||||
|
||||
# renpy/common/00gltest.rpy:77
|
||||
old "Quit"
|
||||
new "終了"
|
||||
|
||||
# renpy/common/00gltest.rpy:82
|
||||
old "Return"
|
||||
new "戻る"
|
||||
|
||||
# renpy/common/00gltest.rpy:112
|
||||
old "Performance Warning"
|
||||
new "パフォーマンスに関する注意"
|
||||
|
||||
# renpy/common/00gltest.rpy:117
|
||||
old "This computer is using software rendering."
|
||||
new "このコンピュータはソフトウェアレンダリングを使用しています。"
|
||||
|
||||
# renpy/common/00gltest.rpy:119
|
||||
old "This computer is not using shaders."
|
||||
new "このコンピューターはシェーダーを使用していません。"
|
||||
|
||||
# renpy/common/00gltest.rpy:121
|
||||
old "This computer is displaying graphics slowly."
|
||||
new "このコンピューターは描画速度が遅いです。"
|
||||
|
||||
# renpy/common/00gltest.rpy:123
|
||||
old "This computer has a problem displaying graphics: [problem]."
|
||||
new "このコンピューターはグラフィックスの表示に問題があります: [problem]。"
|
||||
|
||||
# renpy/common/00gltest.rpy:128
|
||||
old "Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display. Updating DirectX could fix this problem."
|
||||
new "グラフィックドライバーは古いか、あるいは正常に動作していません。これはグラフィックスの表示が遅くなったり、正常に表示されない原因となります。DirectXをアップデートするとこの問題を解決できます。"
|
||||
|
||||
# renpy/common/00gltest.rpy:130
|
||||
old "Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display."
|
||||
new "グラフィックドライバーは古いか、あるいは正常に動作していません。これはグラフィックスの表示が遅くなったり、正常に表示されない原因となります。"
|
||||
|
||||
# renpy/common/00gltest.rpy:135
|
||||
old "Update DirectX"
|
||||
new "DirectXのアップデート"
|
||||
|
||||
# renpy/common/00gltest.rpy:141
|
||||
old "Continue, Show this warning again"
|
||||
new "今後も、この注意を表示する"
|
||||
|
||||
# renpy/common/00gltest.rpy:145
|
||||
old "Continue, Don't show warning again"
|
||||
new "今後は、この注意を表示しない"
|
||||
|
||||
# renpy/common/00gltest.rpy:171
|
||||
old "Updating DirectX."
|
||||
new "DirectXのアップデート中"
|
||||
|
||||
# renpy/common/00gltest.rpy:175
|
||||
old "DirectX web setup has been started. It may start minimized in the taskbar. Please follow the prompts to install DirectX."
|
||||
new "DirectXウェブセットアップが開始されました。タスクバーに最小化された状態で開始したので、画面に従ってDirectXをインストールして下さい。"
|
||||
|
||||
# renpy/common/00gltest.rpy:179
|
||||
old "{b}Note:{/b} Microsoft's DirectX web setup program will, by default, install the Bing toolbar. If you do not want this toolbar, uncheck the appropriate box."
|
||||
new "{b}メモ:{/b} MicrosoftのDirectXウェブセットアッププログラムは、デフォルトでBingツールバーをインストールします。このツールバーが不要な場合は、対応したチェックボックスを解除して下さい。"
|
||||
|
||||
# renpy/common/00gltest.rpy:183
|
||||
old "When setup finishes, please click below to restart this program."
|
||||
new "セットアップが完了したら、以下をクリックしてプログラムを再起動して下さい。"
|
||||
|
||||
# renpy/common/00gltest.rpy:185
|
||||
old "Restart"
|
||||
new "再起動"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00keymap.rpy:168
|
||||
old "Saved screenshot as %s."
|
||||
new "スクリーンショットを %s に保存しました。"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00layout.rpy:421
|
||||
old "Are you sure?"
|
||||
new "本当にいいですか?"
|
||||
|
||||
# renpy/common/00layout.rpy:422
|
||||
old "Are you sure you want to delete this save?"
|
||||
new "この保存データを本当に削除しますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:423
|
||||
old "Are you sure you want to overwrite your save?"
|
||||
new "本当に保存データを上書きしますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:424
|
||||
old "Loading will lose unsaved progress.\nAre you sure you want to do this?"
|
||||
new "読み込みによって未保存のゲームが失われます。\n本当に読み込みますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:425
|
||||
old "Are you sure you want to quit?"
|
||||
new "本当にゲームを終了しますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:426
|
||||
old "Are you sure you want to return to the main menu?\nThis will lose unsaved progress."
|
||||
new "本当にメインメニューに戻りますか?\nこれによって未保存のゲームが失われます。"
|
||||
|
||||
# renpy/common/00layout.rpy:427
|
||||
old "Are you sure you want to begin skipping?"
|
||||
new "本当にスキップモードを開始しますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:428
|
||||
old "Are you sure you want to skip to the next choice?"
|
||||
new "本当に次の選択肢までスキップしますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:429
|
||||
old "Are you sure you want to skip to unseen dialogue or the next choice?"
|
||||
new "本当に未読の会話、もしくは次の選択肢までスキップしますか?"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00library.rpy:77
|
||||
old "Skip Mode"
|
||||
new "スキップモード"
|
||||
|
||||
# renpy/common/00library.rpy:80
|
||||
old "Fast Skip Mode"
|
||||
new "高速スキップモード"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00updater.rpy:1258
|
||||
old "Updater"
|
||||
new "アップデーター"
|
||||
|
||||
# renpy/common/00updater.rpy:1267
|
||||
old "This program is up to date."
|
||||
new "このプログラムは最新版です。"
|
||||
|
||||
# renpy/common/00updater.rpy:1269
|
||||
old "[u.version] is available. Do you want to install it?"
|
||||
new "[u.version] が利用可能です。インストールしますか?"
|
||||
|
||||
# renpy/common/00updater.rpy:1271
|
||||
old "Preparing to download the updates."
|
||||
new "アップデートをダウンロードする準備をしています。"
|
||||
|
||||
# renpy/common/00updater.rpy:1273
|
||||
old "Downloading the updates."
|
||||
new "アップデートをダウンロードしています。"
|
||||
|
||||
# renpy/common/00updater.rpy:1275
|
||||
old "Unpacking the updates."
|
||||
new "アップデートを展開しています。"
|
||||
|
||||
# renpy/common/00updater.rpy:1279
|
||||
old "The updates have been installed. The program will restart."
|
||||
new "アップデートがインストールされました。プログラムを再起動します。"
|
||||
|
||||
# renpy/common/00updater.rpy:1281
|
||||
old "The updates have been installed."
|
||||
new "アップデートがインストールされました。"
|
||||
|
||||
# renpy/common/00updater.rpy:1283
|
||||
old "The updates were cancelled."
|
||||
new "アップデートがキャンセルされました。"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/_compat/gamemenu.rpym:180
|
||||
old "Empty Slot."
|
||||
new "空のスロット"
|
||||
|
||||
# renpy/common/_compat/gamemenu.rpym:337
|
||||
old "Previous"
|
||||
new "前へ"
|
||||
|
||||
# renpy/common/_compat/gamemenu.rpym:344
|
||||
old "Next"
|
||||
new "次へ"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/_compat/preferences.rpym:411
|
||||
old "Joystick Mapping"
|
||||
new "ジョイスティックのマッピング"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/_errorhandling.rpym:408
|
||||
old "An exception has occurred."
|
||||
new "例外が発生しました。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:434
|
||||
old "Rollback"
|
||||
new "ロールバック"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:436
|
||||
old "Attempts a roll back to a prior time, allowing you to save or choose a different choice."
|
||||
new "一つ前へのロールバックを試み、セーブまたは他の選択肢を選ぶことを許可します。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:439
|
||||
old "Ignore"
|
||||
new "無視"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:441
|
||||
old "Ignores the exception, allowing you to continue. This often leads to additional errors."
|
||||
new "例外を無視し、ゲームの継続を許可します。この場合、付加的なエラーが発生する原因となることがあります。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:444
|
||||
old "Reload"
|
||||
new "再読み込み"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:446
|
||||
old "Reloads the game from disk, saving and restoring game state if possible."
|
||||
new "ディスクからゲームを再読み込みし、可能であればゲームの保存と復元をします。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:448
|
||||
old "Open Traceback"
|
||||
new "トレースバックを開く"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:450
|
||||
old "Opens the traceback.txt file in a text editor."
|
||||
new "テキストエディターで traceback.txt を開きます。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:456
|
||||
old "Quits the game."
|
||||
new "ゲームを終了します。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:483
|
||||
old "Parsing the script failed."
|
||||
new "スクリプトの変換に失敗しました。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:510
|
||||
old "Open Parse Errors"
|
||||
new "変換エラーを開く"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:512
|
||||
old "Opens the errors.txt file in a text editor."
|
||||
new "テキストエディターで errors.txt を開きます。"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/_layout/classic_load_save.rpym:152
|
||||
old "a"
|
||||
new "a"
|
||||
|
||||
# renpy/common/_layout/classic_load_save.rpym:161
|
||||
old "q"
|
||||
new "q"
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00console.rpy:179
|
||||
old "%(version)s console, originally by Shiz, C, and delta.\n"
|
||||
new "%(version)s コンソール, 作成者: Shiz, C, delta\n"
|
||||
|
||||
# renpy/common/00console.rpy:180
|
||||
old "Press <esc> to exit console. Type help for help.\n"
|
||||
new "<esc> を押して終了。help と入力してヘルプを表示。\n"
|
||||
|
||||
# renpy/common/00console.rpy:184
|
||||
old "Ren'Py script enabled."
|
||||
new "Ren'Py スクリプト有効。"
|
||||
|
||||
# renpy/common/00console.rpy:186
|
||||
old "Ren'Py script disabled."
|
||||
new "Ren'Py スクリプト無効。"
|
||||
|
||||
# renpy/common/00console.rpy:392
|
||||
old "help: show this help"
|
||||
new "help: このヘルプを表示"
|
||||
|
||||
# renpy/common/00console.rpy:397
|
||||
old "commands:\n"
|
||||
new "コマンド:\n"
|
||||
|
||||
# renpy/common/00console.rpy:407
|
||||
old " <renpy script statement>: run the statement\n"
|
||||
new " <Ren'Py スクリプトステートメント>: ステートメントを実行\n"
|
||||
|
||||
# renpy/common/00console.rpy:409
|
||||
old " <python expression or statement>: run the expression or statement"
|
||||
new " <Python 式またはステートメント>: 式またはステートメントを実行"
|
||||
|
||||
# renpy/common/00console.rpy:417
|
||||
old "clear: clear the console history"
|
||||
new "clear: コンソール履歴を消去"
|
||||
|
||||
# renpy/common/00console.rpy:421
|
||||
old "exit: exit the console"
|
||||
new "exit: コンソールを終了"
|
||||
|
||||
# renpy/common/00console.rpy:429
|
||||
old "load <slot>: loads the game from slot"
|
||||
new "load <スロット>: スロットからゲームをロード"
|
||||
|
||||
# renpy/common/00console.rpy:442
|
||||
old "save <slot>: saves the game in slot"
|
||||
new "save <スロット>: スロットにゲームを保存"
|
||||
|
||||
# renpy/common/00console.rpy:453
|
||||
old "reload: reloads the game, refreshing the scripts"
|
||||
new "reload: ゲームをリロードしてスクリプトを再読み込み"
|
||||
|
||||
# renpy/common/00console.rpy:461
|
||||
old "watch <expression>: watch a python expression"
|
||||
new "watch <式>: Python 式をウォッチ"
|
||||
|
||||
# renpy/common/00console.rpy:470
|
||||
old "unwatch <expression>: stop watching an expression"
|
||||
new "unwatch <式>: Python 式のウォッチを解除"
|
||||
|
||||
# renpy/common/00console.rpy:478
|
||||
old "unwatchall: stop watching all expressions"
|
||||
new "unwatchall: すべての式のウォッチを解除"
|
||||
|
||||
# renpy/common/00console.rpy:484
|
||||
old "jump <label>: jumps to label"
|
||||
new "jump <ラベル>: ラベルにジャンプ"
|
||||
|
||||
# renpy/common/00keymap.rpy:332
|
||||
old "Autoreload"
|
||||
new "オートリロード"
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/_developer/developer.rpym:65
|
||||
old "Developer Menu"
|
||||
new "開発者メニュー"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:67
|
||||
old "Reload Game (Shift+R)"
|
||||
new "ゲームのリロード (Shift+R)"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:69
|
||||
old "Console (Shift+O)"
|
||||
new "コンソール (Shift+D)"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:71
|
||||
old "Variable Viewer"
|
||||
new "変数ビューアー"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:73
|
||||
old "Theme Test"
|
||||
new "テーマのテスト"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:75
|
||||
old "Image Location Picker"
|
||||
new "画像位置ピッカー"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:77
|
||||
old "Filename List"
|
||||
new "ファイル名のリスト"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:81
|
||||
old "Show Image Load Log"
|
||||
new "画像ロード履歴の表示"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:84
|
||||
old "Hide Image Load Log"
|
||||
new "画像ロード履歴の非表示"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:149
|
||||
old "No variables have changed since the game started."
|
||||
new "ゲーム起動時から変更された変数はありません。"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:152
|
||||
old "Return to the developer menu"
|
||||
new "開発者メニューに戻ります"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:309
|
||||
old "Undefined Images"
|
||||
new "未定義の画像"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:409
|
||||
old "Rectangle: %r"
|
||||
new "矩形: %r"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:414
|
||||
old "Mouse position: %r"
|
||||
new "マウス位置: %r"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:416
|
||||
old "Right-click or escape to quit."
|
||||
new "右クリックまたはEscで終了。"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:467
|
||||
old "Done"
|
||||
new "完了"
|
||||
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:43
|
||||
old "Displayable Inspector"
|
||||
new "Displayable インスペクター"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:49
|
||||
old "Nothing to inspect."
|
||||
new "インスペクトするものがありません"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:58
|
||||
old "Size"
|
||||
new "サイズ"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:63
|
||||
old "Style"
|
||||
new "スタイル"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:123
|
||||
old "Inspecting Styles of [displayable_name!q]"
|
||||
new "[displayable_name!q] のスタイルをインスペクト中"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:135
|
||||
old "displayable:"
|
||||
new "Displayable:"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:142
|
||||
old " (no properties affect the displayable)"
|
||||
new " (Displayable に影響しているプロパティーはありません)"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:144
|
||||
old " (default properties omitted)"
|
||||
new " (デフォルトのプロパティーは省略します)"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:174
|
||||
old "<repr() failed>"
|
||||
new "<repr() 失敗>"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:273
|
||||
old "{b}Missing Images{/b}"
|
||||
new "{b}M画像が見付かりません{/b}"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:80
|
||||
old "Location"
|
||||
new "ファイル"
|
||||
# Translation updated at 2013-02-18 11:40
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# renpy/common/00library.rpy:77
|
||||
old "Skip Mode"
|
||||
new "スキップモード"
|
||||
|
||||
# renpy/common/00library.rpy:80
|
||||
old "Fast Skip Mode"
|
||||
new "高速スキップモード"
|
||||
|
||||
# renpy/common/00updater.rpy:1255
|
||||
old "Updater"
|
||||
new "アップデーター"
|
||||
|
||||
# renpy/common/00updater.rpy:1264
|
||||
old "This program is up to date."
|
||||
new "このプログラムは最新の状態です。"
|
||||
|
||||
# renpy/common/00updater.rpy:1266
|
||||
old "[u.version] is available. Do you want to install it?"
|
||||
new "[u.version] が利用可能です。インストールしますか?"
|
||||
|
||||
# renpy/common/00updater.rpy:1268
|
||||
old "Preparing to download the updates."
|
||||
new "ダウンロードする準備をしています。"
|
||||
|
||||
# renpy/common/00updater.rpy:1270
|
||||
old "Downloading the updates."
|
||||
new "アップデートをダウンロードしています。"
|
||||
|
||||
# renpy/common/00updater.rpy:1272
|
||||
old "Unpacking the updates."
|
||||
new "アップデートを展開しています。"
|
||||
|
||||
# renpy/common/00updater.rpy:1276
|
||||
old "The updates have been installed. The program will restart."
|
||||
new "アップデートがインストールされました。プログラムを再起動します。"
|
||||
|
||||
# renpy/common/00updater.rpy:1278
|
||||
old "The updates have been installed."
|
||||
new "アップデートが完了しました。"
|
||||
|
||||
# renpy/common/00updater.rpy:1280
|
||||
old "The updates were cancelled."
|
||||
new "アップデートがキャンセルされました。"
|
||||
|
||||
# renpy/common/_compat/preferences.rpym:411
|
||||
old "Joystick Mapping"
|
||||
new "ジョイスティックの割り当て"
|
||||
|
||||
# renpy/common/00layout.rpy:421
|
||||
old "Are you sure?"
|
||||
new "続けますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:422
|
||||
old "Are you sure you want to delete this save?"
|
||||
new "このセーブデータを消去しますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:423
|
||||
old "Are you sure you want to overwrite your save?"
|
||||
new "このセーブデータに上書きしますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:424
|
||||
old "Loading will lose unsaved progress.\nAre you sure you want to do this?"
|
||||
new "セーブされていないデータは失われます\n続けますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:425
|
||||
old "Are you sure you want to quit?"
|
||||
new "終了しますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:426
|
||||
old "Are you sure you want to return to the main menu?\nThis will lose unsaved progress."
|
||||
new "メインメニューに戻りますか?\nセーブされていないデータは破棄されます"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:408
|
||||
old "An exception has occurred."
|
||||
new "例外が発生しました。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:434
|
||||
old "Rollback"
|
||||
new "ロールバック"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:436
|
||||
old "Attempts a roll back to a prior time, allowing you to save or choose a different choice."
|
||||
new "セーブまたは他の選択肢が選べるように、ロールバックを使って直前に戻ります。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:439
|
||||
old "Ignore"
|
||||
new "無視"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:441
|
||||
old "Ignores the exception, allowing you to continue. This often leads to additional errors."
|
||||
new "例外を無視してゲームを続行します。連鎖的にエラーが発生する可能性があります。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:444
|
||||
old "Reload"
|
||||
new "リロード"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:446
|
||||
old "Reloads the game from disk, saving and restoring game state if possible."
|
||||
new "ディスクからゲームをリロードして、現在の状況を保存、可能であれば復元します。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:448
|
||||
old "Open Traceback"
|
||||
new "トレースバックを開く"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:450
|
||||
old "Opens the traceback.txt file in a text editor."
|
||||
new "テキストエディターで traceback.txt を開きます。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:456
|
||||
old "Quits the game."
|
||||
new "ゲームを終了します。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:483
|
||||
old "Parsing the script failed."
|
||||
new "スクリプトの変換に失敗しました。"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:510
|
||||
old "Open Parse Errors"
|
||||
new "変換エラーを開く"
|
||||
|
||||
# renpy/common/_errorhandling.rpym:512
|
||||
old "Opens the errors.txt file in a text editor."
|
||||
new "テキストエディターで errors.txt を開きます。"
|
||||
|
||||
# renpy/common/00keymap.rpy:167
|
||||
old "Saved screenshot as %s."
|
||||
new "スクリーンショットを %s に保存しました。"
|
||||
|
||||
# renpy/common/00gltest.rpy:50
|
||||
old "Graphics Acceleration"
|
||||
new "グラフィック・アクセラレーション"
|
||||
|
||||
# renpy/common/00gltest.rpy:54
|
||||
old "Automatically Choose"
|
||||
new "自動で選択する"
|
||||
|
||||
# renpy/common/00gltest.rpy:59
|
||||
old "Force Angle/DirectX Renderer"
|
||||
new "Angle/DirectX レンダラーを使う"
|
||||
|
||||
# renpy/common/00gltest.rpy:63
|
||||
old "Force OpenGL Renderer"
|
||||
new "OpenGL レンダラーを使う"
|
||||
|
||||
# renpy/common/00gltest.rpy:67
|
||||
old "Force Software Renderer"
|
||||
new "ソフトウェアレンダラーを使う"
|
||||
|
||||
# renpy/common/00gltest.rpy:73
|
||||
old "Changes will take effect the next time this program is run."
|
||||
new "変更は次回起動時から適用されます"
|
||||
|
||||
# renpy/common/00gltest.rpy:112
|
||||
old "Performance Warning"
|
||||
new "パフォーマンスに関する注意"
|
||||
|
||||
# renpy/common/00gltest.rpy:117
|
||||
old "This computer is using software rendering."
|
||||
new "このコンピューターはソフトウェアレンダリングを使用しています。"
|
||||
|
||||
# renpy/common/00gltest.rpy:119
|
||||
old "This computer is not using shaders."
|
||||
new "このコンピューターはシェーダーを使用していません。"
|
||||
|
||||
# renpy/common/00gltest.rpy:121
|
||||
old "This computer is displaying graphics slowly."
|
||||
new "このコンピューターは描画速度が遅いです。"
|
||||
|
||||
# renpy/common/00gltest.rpy:123
|
||||
old "This computer has a problem displaying graphics: [problem]."
|
||||
new "このコンピューターではグラフィックに以下の問題があります:[problem] "
|
||||
|
||||
# renpy/common/00gltest.rpy:128
|
||||
old "Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display. Updating DirectX could fix this problem."
|
||||
new "グラフィックドライバーが古いか、正常に動作していません。表示が遅れたり、正しく表示されない可能性があります。DirectX を更新すると解決することがあります。"
|
||||
|
||||
# renpy/common/00gltest.rpy:130
|
||||
old "Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display."
|
||||
new "グラフィックドライバーが古いか、正常に動作していません。表示が遅れたり、正しく表示されない可能性があります。"
|
||||
|
||||
# renpy/common/00gltest.rpy:135
|
||||
old "Update DirectX"
|
||||
new "DirectXのアップデート"
|
||||
|
||||
# renpy/common/00gltest.rpy:141
|
||||
old "Continue, Show this warning again"
|
||||
new "次回もこの注意を表示する。"
|
||||
|
||||
# renpy/common/00gltest.rpy:145
|
||||
old "Continue, Don't show warning again"
|
||||
new "次回はこの注意を表示しない。"
|
||||
|
||||
# renpy/common/00gltest.rpy:171
|
||||
old "Updating DirectX."
|
||||
new "DirectXのアップデート中"
|
||||
|
||||
# renpy/common/00gltest.rpy:175
|
||||
old "DirectX web setup has been started. It may start minimized in the taskbar. Please follow the prompts to install DirectX."
|
||||
new "DirectX ウェブセットアップを開始しました。タスクバーに最小化されていることがありますが、指示通りにインストールしてください。"
|
||||
|
||||
# renpy/common/00gltest.rpy:179
|
||||
old "{b}Note:{/b} Microsoft's DirectX web setup program will, by default, install the Bing toolbar. If you do not want this toolbar, uncheck the appropriate box."
|
||||
new "{b}注意:{/b} MicrosoftのDirectXウェブセットアッププログラムは、デフォルトでBingツールバーをインストールします。このツールバーが不要な場合は、対応したチェックボックスを解除して下さい。"
|
||||
|
||||
# renpy/common/00gltest.rpy:183
|
||||
old "When setup finishes, please click below to restart this program."
|
||||
new "セットアップが完了したら、下のボタンを押して再起動してください。"
|
||||
|
||||
# renpy/common/00gltest.rpy:185
|
||||
old "Restart"
|
||||
new "再起動"
|
||||
|
||||
# renpy/common/_layout/imagemap_load_save.rpym:115
|
||||
old "a"
|
||||
new "a"
|
||||
|
||||
# renpy/common/_layout/imagemap_load_save.rpym:124
|
||||
old "q"
|
||||
new "q"
|
||||
|
||||
# renpy/common/00action_file.rpy:118
|
||||
old "%b %d, %H:%M"
|
||||
new "%m月%d日, %H:%M"
|
||||
|
||||
# renpy/common/00layout.rpy:427
|
||||
old "Are you sure you want to begin skipping?"
|
||||
new "スキップを開始しますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:428
|
||||
old "Are you sure you want to skip to the next choice?"
|
||||
new "次の選択肢までスキップしますか?"
|
||||
|
||||
# renpy/common/00layout.rpy:429
|
||||
old "Are you sure you want to skip to unseen dialogue or the next choice?"
|
||||
new "次の選択肢または未読までスキップしますか?"
|
||||
|
||||
# renpy/common/00gallery.rpy:521
|
||||
old "Image [index] of [count] locked."
|
||||
new "画像 [index] / [count] はロックされています。"
|
||||
|
||||
# renpy/common/00gallery.rpy:539
|
||||
old "prev"
|
||||
new "前へ"
|
||||
|
||||
# renpy/common/00gallery.rpy:540
|
||||
old "next"
|
||||
new "次へ"
|
||||
|
||||
# renpy/common/00gallery.rpy:541
|
||||
old "slideshow"
|
||||
new "スライドショー"
|
||||
|
||||
# renpy/common/00gallery.rpy:542
|
||||
old "return"
|
||||
new "戻る"
|
||||
|
||||
# renpy/common/00action_file.rpy:587
|
||||
old "Quick save complete."
|
||||
new "クイックセーブ完了。"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:43
|
||||
old "Displayable Inspector"
|
||||
new "Displayable インスペクター"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:49
|
||||
old "Nothing to inspect."
|
||||
new "インスペクトするものがありません"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:58
|
||||
old "Size"
|
||||
new "サイズ"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:63
|
||||
old "Style"
|
||||
new "スタイル"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:123
|
||||
old "Inspecting Styles of [displayable_name!q]"
|
||||
new "[displayable_name!q] のスタイルをインスペクト中"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:135
|
||||
old "displayable:"
|
||||
new "Displayable:"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:142
|
||||
old " (no properties affect the displayable)"
|
||||
new " (Displayable に影響しているプロパティーはありません)"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:144
|
||||
old " (default properties omitted)"
|
||||
new " (デフォルトのプロパティーは省略します)"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:174
|
||||
old "<repr() failed>"
|
||||
new "<repr() 失敗>"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:65
|
||||
old "Developer Menu"
|
||||
new "開発者メニュー"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:67
|
||||
old "Reload Game (Shift+R)"
|
||||
new "ゲームのリロード (Shift+R)"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:69
|
||||
old "Console (Shift+O)"
|
||||
new "コンソール (Shift+D)"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:71
|
||||
old "Variable Viewer"
|
||||
new "変数ビューアー"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:73
|
||||
old "Theme Test"
|
||||
new "テーマのテスト"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:75
|
||||
old "Image Location Picker"
|
||||
new "画像位置ピッカー"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:77
|
||||
old "Filename List"
|
||||
new "ファイル名のリスト"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:81
|
||||
old "Show Image Load Log"
|
||||
new "画像ロード履歴の表示"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:84
|
||||
old "Hide Image Load Log"
|
||||
new "画像ロード履歴の非表示"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:149
|
||||
old "No variables have changed since the game started."
|
||||
new "ゲーム起動時から変更された変数はありません。"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:152
|
||||
old "Return to the developer menu"
|
||||
new "開発者メニューに戻ります"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:309
|
||||
old "Undefined Images"
|
||||
new "未定義の画像"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:409
|
||||
old "Rectangle: %r"
|
||||
new "矩形: %r"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:414
|
||||
old "Mouse position: %r"
|
||||
new "マウス位置: %r"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:416
|
||||
old "Right-click or escape to quit."
|
||||
new "右クリックまたはEscで終了。"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:467
|
||||
old "Done"
|
||||
new "完了"
|
||||
|
||||
# renpy/common/00console.rpy:179
|
||||
old "%(version)s console, originally by Shiz, C, and delta.\n"
|
||||
new "%(version)s コンソール, 作成者: Shiz, C, delta\n"
|
||||
|
||||
# renpy/common/00console.rpy:180
|
||||
old "Press <esc> to exit console. Type help for help.\n"
|
||||
new "<esc> を押して終了。help と入力してヘルプを表示。\n"
|
||||
|
||||
# renpy/common/00console.rpy:184
|
||||
old "Ren'Py script enabled."
|
||||
new "Ren'Py スクリプト有効。"
|
||||
|
||||
# renpy/common/00console.rpy:186
|
||||
old "Ren'Py script disabled."
|
||||
new "Ren'Py スクリプト無効。"
|
||||
|
||||
# renpy/common/00console.rpy:392
|
||||
old "help: show this help"
|
||||
new "help: このヘルプを表示"
|
||||
|
||||
# renpy/common/00console.rpy:397
|
||||
old "commands:\n"
|
||||
new "コマンド:\n"
|
||||
|
||||
# renpy/common/00console.rpy:407
|
||||
old " <renpy script statement>: run the statement\n"
|
||||
new " <Ren'Py スクリプトステートメント>: ステートメントを実行\n"
|
||||
|
||||
# renpy/common/00console.rpy:409
|
||||
old " <python expression or statement>: run the expression or statement"
|
||||
new " <Python 式またはステートメント>: 式またはステートメントを実行"
|
||||
|
||||
# renpy/common/00console.rpy:417
|
||||
old "clear: clear the console history"
|
||||
new "clear: コンソール履歴を消去"
|
||||
|
||||
# renpy/common/00console.rpy:421
|
||||
old "exit: exit the console"
|
||||
new "exit: コンソールを終了"
|
||||
|
||||
# renpy/common/00console.rpy:429
|
||||
old "load <slot>: loads the game from slot"
|
||||
new "load <スロット>: スロットからゲームをロード"
|
||||
|
||||
# renpy/common/00console.rpy:442
|
||||
old "save <slot>: saves the game in slot"
|
||||
new "save <スロット>: スロットにゲームを保存"
|
||||
|
||||
# renpy/common/00console.rpy:453
|
||||
old "reload: reloads the game, refreshing the scripts"
|
||||
new "reload: ゲームをリロードしてスクリプトを再読み込み"
|
||||
|
||||
# renpy/common/00console.rpy:461
|
||||
old "watch <expression>: watch a python expression"
|
||||
new "watch <式>: Python 式をウォッチ"
|
||||
|
||||
# renpy/common/00console.rpy:470
|
||||
old "unwatch <expression>: stop watching an expression"
|
||||
new "unwatch <式>: Python 式のウォッチを解除"
|
||||
|
||||
# renpy/common/00console.rpy:478
|
||||
old "unwatchall: stop watching all expressions"
|
||||
new "unwatchall: すべての式のウォッチを解除"
|
||||
|
||||
# renpy/common/00console.rpy:484
|
||||
old "jump <label>: jumps to label"
|
||||
new "jump <ラベル>: ラベルにジャンプ"
|
||||
|
||||
# renpy/common/00keymap.rpy:332
|
||||
old "Autoreload"
|
||||
new "オートリロード"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:272
|
||||
old "{b}Missing Images{/b}"
|
||||
new "{b}M画像が見付かりません{/b}"
|
||||
|
||||
# renpy/common/_developer/inspector.rpym:80
|
||||
old "Location"
|
||||
new "ファイル"
|
||||
|
||||
# renpy/common/00preferences.rpy:387
|
||||
old "Clipboard voicing enabled. Press 'shift+C' to disable."
|
||||
new "クリップボードボイシングが有効化しました。 'shift+C'で無効化します。"
|
||||
|
||||
# renpy/common/00preferences.rpy:389
|
||||
old "Self-voicing enabled. Press 'v' to disable."
|
||||
new "セルフボイシングが有効化しました。 'v' で無効化します。"
|
||||
|
||||
##Lancherでのみ必要###########################################
|
||||
# renpy/common/00gltest.rpy:95
|
||||
old "Quit"
|
||||
new "終了"
|
||||
|
||||
# renpy/common/00gltest.rpy:100
|
||||
old "Return"
|
||||
new "戻る"
|
||||
|
||||
# renpy/common/_compat/gamemenu.rpym:198
|
||||
old "Empty Slot."
|
||||
new "空のスロット"
|
||||
|
||||
# renpy/common/_compat/gamemenu.rpym:355
|
||||
old "Previous"
|
||||
new "前へ"
|
||||
|
||||
# renpy/common/_compat/gamemenu.rpym:362
|
||||
old "Next"
|
||||
new "次へ"
|
||||
##templateでのみ必要############################################
|
||||
#
|
||||
# # renpy/common/00updater.rpy:1385
|
||||
# old "An error has occured:"
|
||||
# new "エラーが派生しました。"
|
||||
#
|
||||
# # renpy/common/00updater.rpy:1387
|
||||
# old "Checking for updates."
|
||||
# new "更新をチェックしています。"
|
||||
#
|
||||
# # renpy/common/00updater.rpy:1399
|
||||
# old "Finishing up."
|
||||
# new "更新を完了しました。"
|
||||
#
|
||||
# # renpy/common/00updater.rpy:1419
|
||||
# old "Proceed"
|
||||
# new "処理中"
|
||||
#
|
||||
# # renpy/common/00updater.rpy:1422
|
||||
# old "Cancel"
|
||||
# new "キャンセル"
|
||||
|
||||
@@ -105,3 +105,7 @@ translate japanese strings:
|
||||
old "Recompiling all rpy files into rpyc files..."
|
||||
new "すべての rpy ファイルを rpyc ファイルにコンパイルしています。"
|
||||
|
||||
# game/front_page.rpy:245
|
||||
old "iOS"
|
||||
new "iOS"
|
||||
|
||||
|
||||
Executable
+100
@@ -0,0 +1,100 @@
|
||||
# TODO: Translation updated at 2015-01-25 08:59
|
||||
|
||||
translate japanese strings:
|
||||
|
||||
# game/ios.rpy:28
|
||||
old "To build iOS packages, please download renios, unzip it, and place it into the Ren'Py directory. Then restart the Ren'Py launcher."
|
||||
new "iOS パッケージをビルドするには、 renios をダウンロードして、Ren'Py ディレクトリーに配置、ランチャーを再起動してください。"
|
||||
|
||||
# game/ios.rpy:29
|
||||
old "The directory in where Xcode projects will be placed has not been selected. Choose 'Select Directory' to select it."
|
||||
new "'Select Directory' から、 xcode プロジェクトが配置されるディレクトリーを選択してください。"
|
||||
|
||||
# game/ios.rpy:30
|
||||
old "There is no Xcode project corresponding to the current Ren'Py project. Choose 'Create Xcode Project' to create one."
|
||||
new "現在の Ren'Py プロジェクトに対応する Xcode プロジェクトがありません。'Create Xcode Project' から作成してください。"
|
||||
|
||||
# game/ios.rpy:31
|
||||
old "An Xcode project exists. Choose 'Update Xcode Project' to update it with the latest game files, or use Xcode to build and install it."
|
||||
new "Xcode プロジェクトが存在します。'Update Xcode Project' を選択して最新のゲームファイルに更新するか、 Xcode を使用してそれをビルド、インストールしてください。"
|
||||
|
||||
# game/ios.rpy:33
|
||||
old "Attempts to emulate an iPhone.\n\nTouch input is emulated through the mouse, but only when the button is held down."
|
||||
new "iPhone をエミュレートします。\n\nタッチ入力はマウスを利用してエミュレートされますが、ボタン押下時のみ反応します"
|
||||
|
||||
# game/ios.rpy:34
|
||||
old "Attempts to emulate an iPad.\n\nTouch input is emulated through the mouse, but only when the button is held down."
|
||||
new "iPad をエミュレートします。\n\nタッチ入力はマウスを利用してエミュレートされますが、ボタン押下時のみ反応します"
|
||||
|
||||
# game/ios.rpy:36
|
||||
old "Selects the directory where Xcode projects will be placed."
|
||||
new "Xcode プロジェクトが配置されるディレクトリーを選択します。"
|
||||
|
||||
# game/ios.rpy:37
|
||||
old "Creates an Xcode project corresponding to the current Ren'Py project."
|
||||
new "現在の Ren'PY プロジェクトに対応する Xcode プロジェクトを作成します。"
|
||||
|
||||
# game/ios.rpy:38
|
||||
old "Updates the Xcode project with the latest game files. This must be done each time the Ren'Py project changes."
|
||||
new "最新のゲームファイルに Xcode プロジェクトを更新します。これは Ren'Py プロジェクトが変更される度に行わなければなりません。"
|
||||
|
||||
# game/ios.rpy:39
|
||||
old "Opens the Xcode project in Xcode."
|
||||
new "Xcode から Xcode プロジェクトを開きます。"
|
||||
|
||||
# game/ios.rpy:41
|
||||
old "Opens the directory containing Xcode projects."
|
||||
new "対応する Xcode プロジェクトを開きます。"
|
||||
|
||||
# game/ios.rpy:126
|
||||
old "The Xcode project already exists. Would you like to rename the old project, and replace it with a new one?"
|
||||
new "その Xcode プロジェクトは既に存在します。古いプロジェクトをリネームするか、新しいもので置き換えますか?"
|
||||
|
||||
# game/ios.rpy:202
|
||||
old "iOS: [project.current.name!q]"
|
||||
new "iOS: [project.current.name!q]"
|
||||
|
||||
# game/ios.rpy:231
|
||||
old "iPhone"
|
||||
new "iPhone"
|
||||
|
||||
# game/ios.rpy:235
|
||||
old "iPad"
|
||||
new "iPad"
|
||||
|
||||
# game/ios.rpy:255
|
||||
old "Select Xcode Projects Directory"
|
||||
new "Xcode プロジェクトディレクトリーを選択してください。"
|
||||
|
||||
# game/ios.rpy:259
|
||||
old "Create Xcode Project"
|
||||
new "Xcode プロジェクトを作成してください。"
|
||||
|
||||
# game/ios.rpy:263
|
||||
old "Update Xcode Project"
|
||||
new "Xcode プロジェクトを更新してください。"
|
||||
|
||||
# game/ios.rpy:268
|
||||
old "Launch Xcode"
|
||||
new "Xcode 起動"
|
||||
|
||||
# game/ios.rpy:303
|
||||
old "Open Xcode Projects Directory"
|
||||
new "Xcode プロジェクトディレクトリーを開いてください。"
|
||||
|
||||
# game/ios.rpy:336
|
||||
old "Before packaging iOS apps, you'll need to download renios, Ren'Py's iOS support. Would you like to download renios now?"
|
||||
new "iOS アプリをパッケージする前に、reniosをダウンロードする必要があります。 renios をダウンロードしますか?"
|
||||
|
||||
# game/ios.rpy:345
|
||||
old "XCODE PROJECTS DIRECTORY"
|
||||
new "XCODE PROJECTS DIRECTORY"
|
||||
|
||||
# game/ios.rpy:345
|
||||
old "Please choose the Xcode Projects Directory using the directory chooser.\n{b}The directory chooser may have opened behind this window.{/b}"
|
||||
new "Xcode プロジェクトディレクトリーを選択してください。\n{b}ディレクトリー選択ウィンドウはこのウィンドウの裏に開くかもしれません。{/b}"
|
||||
|
||||
# game/ios.rpy:350
|
||||
old "Ren'Py has set the Xcode Projects Directory to:"
|
||||
new "Ren'Py は Xcode プロジェクトディレクトリーを以下に設定しました。:"
|
||||
|
||||
@@ -371,7 +371,7 @@ translate spanish strings:
|
||||
|
||||
# renpy/common/_developer/developer.rpym:58
|
||||
old "Image Location Picker"
|
||||
new "Image Location Picker"
|
||||
new "Selector de posición en imágenes"
|
||||
|
||||
# renpy/common/_developer/developer.rpym:61
|
||||
old "Filename List"
|
||||
@@ -505,3 +505,43 @@ translate spanish strings:
|
||||
old "Self-voicing enabled. Press 'v' to disable."
|
||||
new "Self-voicing activado. Presiona 'v' para desactivarlo."
|
||||
|
||||
# renpy/common/00preferences.rpy:387
|
||||
old "Clipboard voicing enabled. Press 'shift+C' to disable."
|
||||
new "'Portapapeles a voz' activado. Pulsa 'Mayús.+C' para desactivarlo."
|
||||
|
||||
# renpy/common/00updater.rpy:362
|
||||
old "The Ren'Py Updater is not supported on mobile devices."
|
||||
new "El Actualizador de Ren'Py no es compatible con dispositivos móviles."
|
||||
|
||||
# renpy/common/00updater.rpy:478
|
||||
old "An error is being simulated."
|
||||
new "Se simula un error."
|
||||
|
||||
# renpy/common/00updater.rpy:654
|
||||
old "Either this project does not support updating, or the update status file was deleted."
|
||||
new "O bien este proyecto no es compatible con la actualización o el archivo de estado de la actualización se ha eliminado."
|
||||
|
||||
# renpy/common/00updater.rpy:668
|
||||
old "This account does not have permission to perform an update."
|
||||
new "Esta cuenta no tiene permiso para realizar una actualización."
|
||||
|
||||
# renpy/common/00updater.rpy:671
|
||||
old "This account does not have permission to write the update log."
|
||||
new "Esta cuenta no tiene permiso para escribir en el registro de actualización."
|
||||
|
||||
# renpy/common/00updater.rpy:696
|
||||
old "Could not verify update signature."
|
||||
new "No se pudo verificar la actualización de firmas."
|
||||
|
||||
# renpy/common/00updater.rpy:956
|
||||
old "The update file was not downloaded."
|
||||
new "El archivo de actualización no se ha descargado."
|
||||
|
||||
# renpy/common/00updater.rpy:974
|
||||
old "The update file does not have the correct digest - it may have been corrupted."
|
||||
new "El archivo de actualización no tiene el 'digest' correcto - es posible que esté dañado."
|
||||
|
||||
# renpy/common/00updater.rpy:1030
|
||||
old "While unpacking {}, unknown type {}."
|
||||
new "Tipo desconocido {1} al desempaquetar {0}."
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -24,6 +24,9 @@ init python:
|
||||
if persistent.translate_language is None:
|
||||
persistent.translate_language = "english"
|
||||
|
||||
if persistent.generate_empty_strings is None:
|
||||
persistent.generate_empty_strings = True
|
||||
|
||||
label translate:
|
||||
|
||||
python:
|
||||
@@ -41,7 +44,7 @@ label translate:
|
||||
|
||||
if language == "rot13":
|
||||
args.append("--rot13")
|
||||
else:
|
||||
elif persistent.generate_empty_strings:
|
||||
args.append("--empty")
|
||||
|
||||
interface.processing(_("Ren'Py is generating translations...."))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
+46
-149
@@ -65,23 +65,23 @@ int IMG_SavePNG_RW(SDL_RWops *src, SDL_Surface *surf,int compression){
|
||||
Uint8 *palette_alpha=NULL;
|
||||
png_byte **row_pointers=NULL;
|
||||
png_ptr=NULL;info_ptr=NULL;palette=NULL;ret=-1;
|
||||
funky_format=0;
|
||||
SDL_BlendMode temp_blend;
|
||||
|
||||
Uint32 target_format;
|
||||
|
||||
if( !src || !surf) {
|
||||
goto savedone; /* Nothing to do. */
|
||||
goto savedone2; /* Nothing to do. */
|
||||
}
|
||||
|
||||
row_pointers=(png_byte **)malloc(surf->h * sizeof(png_byte*));
|
||||
if (!row_pointers) {
|
||||
SDL_SetError("Couldn't allocate memory for rowpointers");
|
||||
goto savedone;
|
||||
goto savedone2;
|
||||
}
|
||||
|
||||
png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
|
||||
if (!png_ptr){
|
||||
SDL_SetError("Couldn't allocate memory for PNG file");
|
||||
goto savedone;
|
||||
SDL_SetError("Couldn't allocate memory for PNG file version: " PNG_LIBPNG_VER_STRING);
|
||||
goto savedone2;
|
||||
}
|
||||
info_ptr= png_create_info_struct(png_ptr);
|
||||
if (!info_ptr){
|
||||
@@ -104,172 +104,69 @@ int IMG_SavePNG_RW(SDL_RWops *src, SDL_Surface *surf,int compression){
|
||||
png_set_filter(png_ptr,0,PNG_FILTER_NONE);
|
||||
png_set_compression_level(png_ptr,Z_NO_COMPRESSION);
|
||||
}
|
||||
else if(compression<0) // Default compression
|
||||
else if(compression<0) // Default compression
|
||||
png_set_compression_level(png_ptr,Z_DEFAULT_COMPRESSION);
|
||||
else
|
||||
else
|
||||
png_set_compression_level(png_ptr,compression);
|
||||
|
||||
fmt=surf->format;
|
||||
if(fmt->BitsPerPixel==8){ /* Paletted */
|
||||
|
||||
if (fmt->Amask) {
|
||||
png_set_IHDR(png_ptr,info_ptr,
|
||||
surf->w,surf->h,8,PNG_COLOR_TYPE_PALETTE,
|
||||
surf->w,surf->h,8,PNG_COLOR_TYPE_RGB_ALPHA,
|
||||
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
} else {
|
||||
png_set_IHDR(png_ptr,info_ptr,
|
||||
surf->w,surf->h,8,PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
palette=(png_colorp) malloc(fmt->palette->ncolors * sizeof(png_color));
|
||||
if (!palette) {
|
||||
SDL_SetError("Couldn't create memory for palette");
|
||||
goto savedone;
|
||||
}
|
||||
for (i=0;i<fmt->palette->ncolors;i++) {
|
||||
palette[i].red=fmt->palette->colors[i].r;
|
||||
palette[i].green=fmt->palette->colors[i].g;
|
||||
palette[i].blue=fmt->palette->colors[i].b;
|
||||
}
|
||||
png_set_PLTE(png_ptr,info_ptr,palette,fmt->palette->ncolors);
|
||||
// if (surf->flags&SDL_SRCCOLORKEY) {
|
||||
// palette_alpha=(Uint8 *)malloc((fmt->colorkey+1)*sizeof(Uint8));
|
||||
// if (!palette_alpha) {
|
||||
// SDL_SetError("Couldn't create memory for palette transparency");
|
||||
// goto savedone;
|
||||
// }
|
||||
// /* FIXME: memset? */
|
||||
// for (i=0;i<(fmt->colorkey+1);i++) {
|
||||
// palette_alpha[i]=255;
|
||||
// }
|
||||
// palette_alpha[fmt->colorkey]=0;
|
||||
// png_set_tRNS(png_ptr,info_ptr,palette_alpha,fmt->colorkey+1,NULL);
|
||||
// }
|
||||
}else{ /* Truecolor */
|
||||
if (fmt->Amask) {
|
||||
png_set_IHDR(png_ptr,info_ptr,
|
||||
surf->w,surf->h,8,PNG_COLOR_TYPE_RGB_ALPHA,
|
||||
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
} else {
|
||||
png_set_IHDR(png_ptr,info_ptr,
|
||||
surf->w,surf->h,8,PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
if (fmt->BitsPerPixel==8) { /* Paletted */
|
||||
for(i=0;i<surf->h;i++){
|
||||
row_pointers[i]= ((png_byte*)surf->pixels) + i*surf->pitch;
|
||||
}
|
||||
if(SDL_MUSTLOCK(surf)){
|
||||
SDL_LockSurface(surf);
|
||||
}
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
if(SDL_MUSTLOCK(surf)){
|
||||
SDL_UnlockSurface(surf);
|
||||
}
|
||||
}else{ /* Truecolor */
|
||||
if(fmt->BytesPerPixel==3){
|
||||
if(fmt->Amask){ /* check for 24 bit with alpha */
|
||||
funky_format=1;
|
||||
}else{
|
||||
/* Check for RGB/BGR/GBR/RBG/etc surfaces.*/
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
if(fmt->Rmask!=0xFF0000
|
||||
|| fmt->Gmask!=0x00FF00
|
||||
|| fmt->Bmask!=0x0000FF){
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
if (fmt->Amask) {
|
||||
target_format = SDL_PIXELFORMAT_ABGR8888;
|
||||
} else {
|
||||
target_format = SDL_PIXELFORMAT_BGR888;
|
||||
}
|
||||
#else
|
||||
if(fmt->Rmask!=0x0000FF
|
||||
|| fmt->Gmask!=0x00FF00
|
||||
|| fmt->Bmask!=0xFF0000){
|
||||
if (fmt->Amask) {
|
||||
target_format = SDL_PIXELFORMAT_RGBA8888
|
||||
} else {
|
||||
target_format = SDL_PIXELFORMAT_RGB888;
|
||||
}
|
||||
#endif
|
||||
funky_format=1;
|
||||
}
|
||||
}
|
||||
}else if (fmt->BytesPerPixel==4){
|
||||
if (!fmt->Amask) { /* check for 32bit but no alpha */
|
||||
funky_format=1;
|
||||
}else{
|
||||
/* Check for ARGB/ABGR/GBAR/RABG/etc surfaces.*/
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
if(fmt->Rmask!=0xFF000000
|
||||
|| fmt->Gmask!=0x00FF0000
|
||||
|| fmt->Bmask!=0x0000FF00
|
||||
|| fmt->Amask!=0x000000FF){
|
||||
#else
|
||||
if(fmt->Rmask!=0x000000FF
|
||||
|| fmt->Gmask!=0x0000FF00
|
||||
|| fmt->Bmask!=0x00FF0000
|
||||
|| fmt->Amask!=0xFF000000){
|
||||
#endif
|
||||
funky_format=1;
|
||||
}
|
||||
}
|
||||
}else{ /* 555 or 565 16 bit color */
|
||||
funky_format=1;
|
||||
|
||||
if (surf->format->format != target_format) {
|
||||
tempsurf = SDL_ConvertSurfaceFormat(surf, target_format, 0);
|
||||
surf = tempsurf;
|
||||
|
||||
if (!tempsurf){
|
||||
SDL_SetError("Couldn't allocate temp surface");
|
||||
goto savedone;
|
||||
}
|
||||
if (funky_format) {
|
||||
/* Allocate non-funky format, and copy pixeldata in*/
|
||||
if(fmt->Amask){
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24,
|
||||
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
||||
#else
|
||||
tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24,
|
||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
#endif
|
||||
}else{
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24,
|
||||
0xff0000, 0x00ff00, 0x0000ff, 0x00000000);
|
||||
#else
|
||||
tempsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, surf->w, surf->h, 24,
|
||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000);
|
||||
#endif
|
||||
}
|
||||
if(!tempsurf){
|
||||
SDL_SetError("Couldn't allocate temp surface");
|
||||
goto savedone;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GetSurfaceBlendMode(surf, &temp_blend);
|
||||
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_NONE);
|
||||
for(i=0;i < surf->h;i++){
|
||||
row_pointers[i]= ((png_byte*) surf->pixels) + i * surf->pitch;
|
||||
}
|
||||
|
||||
if(SDL_BlitSurface(surf,NULL,tempsurf,NULL)!=0){
|
||||
SDL_SetError("Couldn't blit surface to temp surface");
|
||||
SDL_FreeSurface(tempsurf);
|
||||
goto savedone;
|
||||
}
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
|
||||
SDL_SetSurfaceBlendMode(surf, temp_blend);
|
||||
|
||||
for(i=0;i<tempsurf->h;i++){
|
||||
row_pointers[i]= ((png_byte*)tempsurf->pixels) + i*tempsurf->pitch;
|
||||
}
|
||||
if(SDL_MUSTLOCK(tempsurf)){
|
||||
SDL_LockSurface(tempsurf);
|
||||
}
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
if(SDL_MUSTLOCK(tempsurf)){
|
||||
SDL_UnlockSurface(tempsurf);
|
||||
}
|
||||
SDL_FreeSurface(tempsurf);
|
||||
} else {
|
||||
for(i=0;i<surf->h;i++){
|
||||
row_pointers[i]= ((png_byte*)surf->pixels) + i*surf->pitch;
|
||||
}
|
||||
if(SDL_MUSTLOCK(surf)){
|
||||
SDL_LockSurface(surf);
|
||||
}
|
||||
png_write_image(png_ptr, row_pointers);
|
||||
if(SDL_MUSTLOCK(surf)){
|
||||
SDL_UnlockSurface(surf);
|
||||
}
|
||||
}
|
||||
if (tempsurf) {
|
||||
SDL_FreeSurface(tempsurf);
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
|
||||
ret=0; /* got here, so nothing went wrong. YAY! */
|
||||
|
||||
savedone: /* clean up and return */
|
||||
png_destroy_write_struct(&png_ptr,&info_ptr);
|
||||
|
||||
savedone2:
|
||||
if (palette) {
|
||||
free(palette);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# -*- python -*-
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -421,6 +421,6 @@ def subpixel(pysrc, pydst, xoffset, yoffset, shift):
|
||||
|
||||
# Be sure to update scale.py when adding something new here!
|
||||
|
||||
import_pygame_sdl2__rwobject()
|
||||
import_pygame_sdl2()
|
||||
core_init()
|
||||
subpixel_init()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -0,0 +1,520 @@
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
cdef extern from "steam/steam_api.h":
|
||||
ctypedef bint bool
|
||||
ctypedef int int32
|
||||
ctypedef unsigned int uint32
|
||||
|
||||
# Init.
|
||||
|
||||
bool SteamAPI_Init()
|
||||
void SteamAPI_RunCallbacks()
|
||||
bool SteamAPI_RestartAppIfNecessary(unsigned int)
|
||||
|
||||
# Stats & Achievements.
|
||||
|
||||
cdef cppclass ISteamUserStats:
|
||||
bool RequestCurrentStats()
|
||||
bool StoreStats()
|
||||
|
||||
bool GetAchievement(const char *pchName, bool *pbAchieved);
|
||||
bool SetAchievement(const char *pchName);
|
||||
bool ClearAchievement(const char *pchName);
|
||||
bool IndicateAchievementProgress(const char *pchName, uint32 nCurProgress, uint32 nMaxProgress)
|
||||
int GetNumAchievements()
|
||||
char *GetAchievementName(int)
|
||||
|
||||
bool GetStat(const char *pchName, int32 *pData)
|
||||
bool GetStat(const char *pchName, float *pData)
|
||||
bool SetStat(const char *pchName, int32 iData)
|
||||
bool SetStat(const char *pchName, float fData)
|
||||
|
||||
ctypedef struct UserStatsReceived_t
|
||||
ISteamUserStats *SteamUserStats()
|
||||
|
||||
# Utils.
|
||||
|
||||
cdef enum ENotificationPosition:
|
||||
k_EPositionTopLeft
|
||||
k_EPositionTopRight
|
||||
k_EPositionBottomLeft
|
||||
k_EPositionBottomRight
|
||||
|
||||
cdef cppclass ISteamUtils:
|
||||
bint IsOverlayEnabled()
|
||||
void SetOverlayNotificationPosition(ENotificationPosition eNotificationPosition)
|
||||
|
||||
ISteamUtils *SteamUtils()
|
||||
|
||||
# Apps.
|
||||
|
||||
ctypedef int AppId_t
|
||||
|
||||
cdef cppclass ISteamApps:
|
||||
bool BIsSubscribedApp(AppId_t appID)
|
||||
const char *GetCurrentGameLanguage()
|
||||
bool GetCurrentBetaName( char *pchName, int cchNameBufferSize );
|
||||
|
||||
bool BIsDlcInstalled(AppId_t nAppID)
|
||||
void InstallDLC(AppId_t nAppID)
|
||||
void UninstallDLC(AppId_t nAppID)
|
||||
|
||||
ctypedef struct DlcInstalled_t:
|
||||
AppId_t m_nAppID
|
||||
|
||||
ISteamApps *SteamApps()
|
||||
|
||||
# Friends.
|
||||
|
||||
cdef enum EOverlayToStoreFlag:
|
||||
k_EOverlayToStoreFlag_None
|
||||
k_EOverlayToStoreFlag_AddToCart
|
||||
k_EOverlayToStoreFlag_AddToCartAndShow
|
||||
|
||||
cdef cppclass ISteamFriends:
|
||||
const char *GetPersonaName()
|
||||
void ActivateGameOverlay(const char *pchDialog)
|
||||
void ActivateGameOverlayToWebPage(const char *pchURL)
|
||||
void ActivateGameOverlayToStore(AppId_t nAppID, EOverlayToStoreFlag eFlag)
|
||||
|
||||
ISteamFriends *SteamFriends()
|
||||
|
||||
# User.
|
||||
|
||||
ctypedef uint32 AccountID_t
|
||||
ctypedef uint32 HAuthTicket
|
||||
|
||||
cdef cppclass CSteamID:
|
||||
AccountID_t GetAccountID()
|
||||
|
||||
cdef cppclass ISteamUser:
|
||||
CSteamID GetSteamID()
|
||||
HAuthTicket GetAuthSessionTicket(void *pTicket, int cbMaxTicket, uint32 *pcbTicket)
|
||||
void CancelAuthTicket(HAuthTicket hAuthTicket)
|
||||
|
||||
ISteamUser *SteamUser()
|
||||
|
||||
|
||||
cdef extern from "steamcallbacks.h":
|
||||
cdef cppclass SteamCallback[T]:
|
||||
SteamCallback(void (*)(T *))
|
||||
|
||||
import renpy
|
||||
|
||||
######################################################### Stats and Achievements
|
||||
|
||||
# A callable that is called when the stats are available.
|
||||
got_stats = None
|
||||
|
||||
cdef void call_got_stats(UserStatsReceived_t *s):
|
||||
if got_stats is not None:
|
||||
got_stats()
|
||||
|
||||
cdef SteamCallback[UserStatsReceived_t] *stats_received_callback = \
|
||||
new SteamCallback[UserStatsReceived_t](call_got_stats)
|
||||
|
||||
def retrieve_stats(callback):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Retrieves achievements and statistics from Steam. `callback` will be
|
||||
called with no parameters if and when the statistics become available.
|
||||
"""
|
||||
|
||||
global got_stats
|
||||
got_stats = callback
|
||||
|
||||
print SteamUserStats().RequestCurrentStats()
|
||||
|
||||
def store_stats():
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Stores statistics and achievements on the Steam server.
|
||||
"""
|
||||
|
||||
SteamUserStats().StoreStats()
|
||||
|
||||
def list_achievements():
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Returns a list of achievement names.
|
||||
"""
|
||||
|
||||
rv = [ ]
|
||||
|
||||
cdef int na = SteamUserStats().GetNumAchievements()
|
||||
cdef char *s
|
||||
cdef int i
|
||||
|
||||
for 0 <= i < na:
|
||||
s = <char *> SteamUserStats().GetAchievementName(i)
|
||||
rv.append(s)
|
||||
|
||||
return rv
|
||||
|
||||
def get_achievement(name):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Gets the state of the achievements with `name`. This returns True if the
|
||||
achievement has been granted, False if it hasn't, and None if the achievement
|
||||
is unknown or an error occurs.
|
||||
"""
|
||||
|
||||
cdef bool rv
|
||||
|
||||
if not SteamUserStats().GetAchievement(name, &rv):
|
||||
return None
|
||||
|
||||
return rv
|
||||
|
||||
def grant_achievement(name):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Grants the achievement with `name`. Call :func:`_renpysteam.store_stats` to
|
||||
push this change to the server.
|
||||
"""
|
||||
|
||||
return SteamUserStats().SetAchievement(name)
|
||||
|
||||
def clear_achievement(name):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Clears the achievement with `name`. Call :func:`_renpysteam.store_stats` to
|
||||
push this change to the server.
|
||||
"""
|
||||
|
||||
return SteamUserStats().ClearAchievement(name)
|
||||
|
||||
def indicate_achievement_progress(name, cur_progress, max_progress):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Indicates achievement progress to the user. This does *not* unlock the
|
||||
achievement.
|
||||
"""
|
||||
|
||||
return SteamUserStats().IndicateAchievementProgress(name, cur_progress, max_progress)
|
||||
|
||||
def get_float_stat(name):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Returns the value of the stat with `name`, or None if no such stat
|
||||
exits.
|
||||
"""
|
||||
|
||||
cdef float rv
|
||||
|
||||
if not SteamUserStats().GetStat(<char *> name, &rv):
|
||||
return None
|
||||
|
||||
return rv
|
||||
|
||||
def set_float_stat(name, value):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Sets the value of the stat with `name`, which must have the type of
|
||||
FLOAT. Call :func:`_renpysteam.store_stats` to push this change to the
|
||||
server.
|
||||
"""
|
||||
|
||||
cdef float v = value
|
||||
|
||||
return SteamUserStats().SetStat(<char *> name, v)
|
||||
|
||||
def get_int_stat(name):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Returns the value of the stat with `name`, or None if no such stat
|
||||
exits.
|
||||
"""
|
||||
|
||||
cdef int32 rv
|
||||
|
||||
if not SteamUserStats().GetStat(<char *> name, &rv):
|
||||
return None
|
||||
|
||||
return rv
|
||||
|
||||
def set_int_stat(name, value):
|
||||
"""
|
||||
:doc: steam_stats
|
||||
|
||||
Sets the value of the stat with `name`, which must have the type of
|
||||
INT. Call :func:`_renpysteam.store_stats` to push this change to the
|
||||
server.
|
||||
"""
|
||||
|
||||
cdef int32 v
|
||||
|
||||
return SteamUserStats().SetStat(<char *> name, v)
|
||||
|
||||
|
||||
########################################################################### Apps
|
||||
|
||||
def is_subscribed_app(appid):
|
||||
"""
|
||||
:doc: steam_apps
|
||||
|
||||
Returns true if the user owns the app with `appid`, and false otherwise.
|
||||
"""
|
||||
|
||||
return SteamApps().BIsSubscribedApp(appid)
|
||||
|
||||
def get_current_game_language():
|
||||
"""
|
||||
:doc: steam_apps
|
||||
|
||||
Return the name of the language the user has selected.
|
||||
"""
|
||||
|
||||
cdef const char *s = SteamApps().GetCurrentGameLanguage()
|
||||
return str(s)
|
||||
|
||||
def get_current_beta_name():
|
||||
"""
|
||||
:doc: steam_apps
|
||||
|
||||
Returns the name of the current beta, or None if it can't.
|
||||
"""
|
||||
|
||||
cdef char rv[256]
|
||||
|
||||
if not SteamApps().GetCurrentBetaName(rv, 256):
|
||||
return None
|
||||
|
||||
return str(rv)
|
||||
|
||||
def dlc_installed(appid):
|
||||
"""
|
||||
:doc: steam_apps
|
||||
|
||||
Returns True if `dlc` is installed, or False otherwise.
|
||||
"""
|
||||
|
||||
return SteamApps().BIsDlcInstalled(appid)
|
||||
|
||||
# A callable that is called when the stats are available.
|
||||
got_dlc = None
|
||||
|
||||
cdef void call_got_dlc(DlcInstalled_t *s):
|
||||
if got_dlc is not None:
|
||||
got_dlc(s.m_nAppID)
|
||||
|
||||
cdef SteamCallback[DlcInstalled_t] *dlc_callback = \
|
||||
new SteamCallback[DlcInstalled_t](call_got_dlc)
|
||||
|
||||
def install_dlc(appid, callback):
|
||||
"""
|
||||
:doc: steam_apps
|
||||
|
||||
Requests the DLC with `appid` be installed. If not None, `callback`
|
||||
will be called with `appid` when the install finishes. Only one
|
||||
callback can be registered at a time.
|
||||
"""
|
||||
|
||||
global got_dlc
|
||||
got_dlc = callback
|
||||
|
||||
SteamApps().InstallDLC(appid)
|
||||
|
||||
def uninstall_dlc(appid):
|
||||
"""
|
||||
:doc: steam_apps
|
||||
|
||||
Requests that the DLC with `appid` be uninstalled.
|
||||
"""
|
||||
|
||||
SteamApps().UninstallDLC(appid)
|
||||
|
||||
######################################################################## Overlay
|
||||
|
||||
def is_overlay_enabled():
|
||||
"""
|
||||
:doc: steam_overlay
|
||||
|
||||
Returns true if the steam overlay is enabled. (This might take a while to
|
||||
return true once the game starts.)
|
||||
"""
|
||||
|
||||
return SteamUtils().IsOverlayEnabled()
|
||||
|
||||
POSITION_TOP_LEFT = k_EPositionTopLeft
|
||||
POSITION_TOP_RIGHT = k_EPositionTopRight
|
||||
POSITION_BOTTOM_LEFT = k_EPositionBottomLeft
|
||||
POSITION_BOTTOM_RIGHT = k_EPositionBottomRight
|
||||
|
||||
def set_overlay_notification_position(position):
|
||||
"""
|
||||
:doc: steam_overlay
|
||||
|
||||
Sets the position of the steam overlay. `Position` should be one of
|
||||
_renpysteam.POSTION_TOP_LEFT, .POSITION_TOP_RIGHT, .POSITION_BOTTOM_LEFT,
|
||||
or .POSITION_BOTTOM_RIGHT.
|
||||
"""
|
||||
|
||||
SteamUtils().SetOverlayNotificationPosition(position)
|
||||
|
||||
def activate_overlay(dialog):
|
||||
"""
|
||||
:doc: steam_overlay
|
||||
|
||||
Activates the Steam overlay.
|
||||
|
||||
`dialog`
|
||||
The dialog to open the overlay to. One of "Friends", "Community",
|
||||
"Players", "Settings", "OfficialGameGroup", "Stats", "Achievements"
|
||||
"""
|
||||
|
||||
SteamFriends().ActivateGameOverlay(dialog)
|
||||
|
||||
def activate_overlay_to_web_page(url):
|
||||
"""
|
||||
:doc: steam_overlay
|
||||
|
||||
Activates the Steam overlay, and opens the web page at `url`.
|
||||
"""
|
||||
|
||||
SteamFriends().ActivateGameOverlayToWebPage(url)
|
||||
|
||||
STORE_NONE = k_EOverlayToStoreFlag_None
|
||||
STORE_ADD_TO_CART = k_EOverlayToStoreFlag_AddToCart
|
||||
STORE_ADD_TO_CART_AND_SHOW = k_EOverlayToStoreFlag_AddToCartAndShow
|
||||
|
||||
def activate_overlay_to_store(appid, flag=STORE_NONE):
|
||||
"""
|
||||
:doc: steam_overlay
|
||||
|
||||
Opens the steam overlay to the store.
|
||||
|
||||
`appid`
|
||||
The appid to open.
|
||||
|
||||
`flag`
|
||||
One of _renpysteam.STORE_NONE, .STORE_ADD_TO_CART, or .STORE_ADD_TO_CART_AND_SHOW.
|
||||
"""
|
||||
|
||||
SteamFriends().ActivateGameOverlayToStore(appid, flag)
|
||||
|
||||
########################################################################### User
|
||||
|
||||
def get_persona_name():
|
||||
"""
|
||||
:doc: steam_user
|
||||
|
||||
Returns the user's publicly-visible name.
|
||||
"""
|
||||
|
||||
return SteamFriends().GetPersonaName().decode("utf-8")
|
||||
|
||||
|
||||
def get_account_id():
|
||||
"""
|
||||
:doc: steam_user
|
||||
|
||||
Returns the user's account ID.
|
||||
"""
|
||||
|
||||
return SteamUser().GetSteamID().GetAccountID()
|
||||
|
||||
cdef HAuthTicket h_ticket = 0
|
||||
ticket = None
|
||||
|
||||
def get_session_ticket():
|
||||
"""
|
||||
:doc: steam_user
|
||||
|
||||
Gets a ticket that can be sent to the server to authenticate this user.
|
||||
"""
|
||||
|
||||
global ticket
|
||||
global h_ticket
|
||||
|
||||
cdef char ticket_buf[2048]
|
||||
cdef uint32 ticket_len
|
||||
|
||||
if ticket is not None:
|
||||
return ticket
|
||||
|
||||
h_ticket = SteamUser().GetAuthSessionTicket(ticket_buf, 2048, &ticket_len)
|
||||
|
||||
if h_ticket:
|
||||
ticket = ticket_buf[0:ticket_len]
|
||||
|
||||
return ticket
|
||||
|
||||
def cancel_ticket():
|
||||
"""
|
||||
:doc: steam_user
|
||||
|
||||
Cancels the ticket returned by :func:`_renpysteam.get_session_ticket`.
|
||||
"""
|
||||
|
||||
|
||||
global h_ticket
|
||||
global tocket
|
||||
|
||||
SteamUser().CancelAuthTicket(h_ticket)
|
||||
|
||||
h_ticket = 0
|
||||
ticket = None
|
||||
|
||||
|
||||
################################################################# Initialization
|
||||
|
||||
# Have we been initialized?
|
||||
initialized = None
|
||||
|
||||
# Called periodically to run callbacks.
|
||||
def periodic():
|
||||
SteamAPI_RunCallbacks()
|
||||
|
||||
# Initialize the Steam API.
|
||||
def init():
|
||||
"""
|
||||
:doc: steam
|
||||
|
||||
Initializes the Steam API. Returns true for success, false for failure.
|
||||
If a failure has occurred, no other steam functions should be called.
|
||||
|
||||
This may be called multiple times, but only attempts initialization the
|
||||
first time it's been called.
|
||||
"""
|
||||
|
||||
global initialized
|
||||
|
||||
if initialized is None:
|
||||
initialized = SteamAPI_Init()
|
||||
|
||||
if initialized:
|
||||
renpy.config.periodic_callbacks.append(periodic)
|
||||
set_overlay_notification_position(POSITION_TOP_RIGHT)
|
||||
|
||||
return initialized
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#include "renpy.h"
|
||||
#include "IMG_savepng.h"
|
||||
#include <SDL.h>
|
||||
#include <pygame_sdl2/pygame_sdl2.surface_api.h>
|
||||
#include <pygame_sdl2/pygame_sdl2.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/* Initializes the stuff found in this file.
|
||||
*/
|
||||
void core_init() {
|
||||
import_pygame_sdl2__surface();
|
||||
import_pygame_sdl2();
|
||||
}
|
||||
|
||||
void save_png_core(PyObject *pysurf, SDL_RWops *rw, int compress) {
|
||||
|
||||
+20
-8
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include "pygame_sdl2/pygame_sdl2.h"
|
||||
#include "EGL/egl.h"
|
||||
#include "GLES2/gl2.h"
|
||||
|
||||
@@ -13,6 +14,7 @@ EGLSurface surface;
|
||||
EGLConfig config;
|
||||
EGLContext context;
|
||||
|
||||
int imported_pygame = 0;
|
||||
int initialized = 0;
|
||||
|
||||
char error_message[100];
|
||||
@@ -45,6 +47,7 @@ char *egl_init(int interval) {
|
||||
SDL_SysWMinfo wminfo;
|
||||
EGLint major, minor;
|
||||
EGLint num_config;
|
||||
HWND new_window;
|
||||
|
||||
const EGLint attrs[] = {
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
@@ -57,12 +60,21 @@ char *egl_init(int interval) {
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
if (!imported_pygame) {
|
||||
import_pygame_sdl2();
|
||||
imported_pygame = 1;
|
||||
}
|
||||
|
||||
SDL_Window *sdl_window = PyWindow_AsWindow(Py_None);
|
||||
|
||||
SDL_VERSION(&wminfo.version);
|
||||
SDL_GetWMInfo(&wminfo);
|
||||
SDL_GetWindowWMInfo(sdl_window, &wminfo);
|
||||
|
||||
new_window = wminfo.info.win.window;
|
||||
|
||||
if (! initialized) {
|
||||
|
||||
display = eglGetDisplay(GetDC(wminfo.window));
|
||||
display = eglGetDisplay(GetDC(new_window));
|
||||
egl_check("getting display");
|
||||
|
||||
eglInitialize(display, &major, &minor);
|
||||
@@ -77,16 +89,16 @@ char *egl_init(int interval) {
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrs);
|
||||
egl_check("creating EGL context");
|
||||
|
||||
surface = eglCreateWindowSurface(display, config, wminfo.window, NULL);
|
||||
surface = eglCreateWindowSurface(display, config, new_window, NULL);
|
||||
egl_check("creating EGL surface");
|
||||
|
||||
|
||||
} else if (window != wminfo.window) {
|
||||
} else if (window != wminfo.info.win.window) {
|
||||
|
||||
eglDestroySurface(display, surface);
|
||||
egl_check("destroying existing EGL surface")
|
||||
|
||||
surface = eglCreateWindowSurface(display, config, wminfo.window, NULL);
|
||||
surface = eglCreateWindowSurface(display, config, new_window, NULL);
|
||||
egl_check("creating EGL surface");
|
||||
|
||||
}
|
||||
@@ -98,7 +110,7 @@ char *egl_init(int interval) {
|
||||
egl_check("setting swap interval")
|
||||
|
||||
initialized = 1;
|
||||
window = wminfo.window;
|
||||
window = new_window;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include "EGL/egl.h"
|
||||
#include "GLES2/gl2.h"
|
||||
|
||||
|
||||
+22
-12
@@ -22,6 +22,7 @@
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <libavutil/avstring.h>
|
||||
#include <libavutil/time.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libswscale/swscale.h>
|
||||
@@ -34,7 +35,7 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL_thread.h>
|
||||
|
||||
#include <pygame_sdl2/pygame_sdl2.surface_api.h>
|
||||
#include <pygame_sdl2/pygame_sdl2.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#undef main /* We don't want SDL to override our main() */
|
||||
@@ -176,6 +177,12 @@ typedef struct VideoState {
|
||||
// The PTS of the first frame.
|
||||
double first_frame_pts;
|
||||
|
||||
// Is the is the first audio?
|
||||
int first_audio;
|
||||
|
||||
// The PTS of the first audio.
|
||||
double first_audio_clock;
|
||||
|
||||
#ifdef HAS_RESAMPLE
|
||||
// The audio frame, and the audio resample context.
|
||||
enum AVSampleFormat sdl_sample_fmt;
|
||||
@@ -489,7 +496,7 @@ static double get_audio_clock(VideoState *is, int adjust)
|
||||
double altpts;
|
||||
double offset;
|
||||
int hw_buf_size, bytes_per_sec;
|
||||
pts = is->audio_clock;
|
||||
pts = is->audio_clock - is->first_audio_clock;
|
||||
hw_buf_size = audio_write_get_buf_size(is);
|
||||
bytes_per_sec = 0;
|
||||
if (is->audio_st) {
|
||||
@@ -519,7 +526,6 @@ static double get_audio_clock(VideoState *is, int adjust)
|
||||
}
|
||||
|
||||
if (adjust) {
|
||||
|
||||
if (offset > 0) {
|
||||
is->start_time += .00025;
|
||||
} else {
|
||||
@@ -559,14 +565,12 @@ static int video_refresh(void *opaque)
|
||||
is->first_frame_pts = vp->pts;
|
||||
}
|
||||
|
||||
delay = get_audio_clock(is, 0) - vp->pts;
|
||||
delay += is->first_frame_pts;
|
||||
delay = get_audio_clock(is, 0) - (vp->pts - is->first_frame_pts);
|
||||
|
||||
/* The video is ahead of the audio. */
|
||||
if (delay < 0 && !is->first_frame) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Adjust the audio clock.
|
||||
get_audio_clock(is, 1);
|
||||
|
||||
@@ -574,11 +578,11 @@ static int video_refresh(void *opaque)
|
||||
video_display(is);
|
||||
}
|
||||
|
||||
is->first_frame = 0;
|
||||
|
||||
av_free(vp->frame);
|
||||
vp->frame = NULL;
|
||||
|
||||
is->first_frame = 0;
|
||||
|
||||
/* update queue size and signal for next picture */
|
||||
if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
|
||||
is->pictq_rindex = 0;
|
||||
@@ -968,6 +972,11 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
|
||||
/* if update the audio clock with the pts */
|
||||
if (pkt->pts != AV_NOPTS_VALUE) {
|
||||
is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
|
||||
|
||||
if (is->first_audio) {
|
||||
is->first_audio_clock = is->audio_clock;
|
||||
is->first_audio = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1481,9 +1490,9 @@ static int decode_thread(void *arg)
|
||||
is->show_audio = 0;
|
||||
}
|
||||
|
||||
if (is->video_stream < 0 && is->audio_stream < 0) {
|
||||
fprintf(stderr, "could not open codecs\n");
|
||||
ret = -1;
|
||||
if (is->audio_stream < 0) {
|
||||
printf("%s audio stream could not be opened.\n", is->filename);
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -1610,6 +1619,7 @@ VideoState *ffpy_stream_open(SDL_RWops *rwops, const char *filename)
|
||||
is->parse_tid = SDL_CreateThread(decode_thread, "decode_thread", is);
|
||||
|
||||
is->first_frame = 1;
|
||||
is->first_audio = 1;
|
||||
|
||||
if (!is->parse_tid) {
|
||||
av_free(is);
|
||||
@@ -1666,7 +1676,7 @@ void ffpy_init(int rate, int status) {
|
||||
|
||||
ffpy_did_init = 1;
|
||||
|
||||
import_pygame_sdl2__surface();
|
||||
import_pygame_sdl2();
|
||||
|
||||
show_status = status;
|
||||
|
||||
|
||||
+21
-21
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -413,6 +413,7 @@ def generate_constants():
|
||||
g.close()
|
||||
|
||||
def generate_property_function(g, prefix, propname, properties):
|
||||
|
||||
name = prefix.name + propname
|
||||
|
||||
g.write("cdef int {name}_property(PyObject **cache, int *cache_priorities, int priority, object value) except -1:", name=name)
|
||||
@@ -457,41 +458,41 @@ def generate_property_functions():
|
||||
This generates code that defines the property functions.
|
||||
"""
|
||||
|
||||
g = CodeGen("module/gen/stylepropertyfunctions.pxi")
|
||||
for prefix in sorted(prefixes.values(), key=lambda p : p.index):
|
||||
g = CodeGen("module/gen/style_{}functions.pyx".format(prefix.name))
|
||||
|
||||
for propname, proplist in all_properties.items():
|
||||
for prefix in sorted(prefixes.values(), key=lambda p : p.index):
|
||||
g.write('include "style_common.pxi"')
|
||||
g.write('')
|
||||
|
||||
for propname, proplist in all_properties.items():
|
||||
generate_property_function(g, prefix, propname, proplist)
|
||||
|
||||
g.close()
|
||||
g.close()
|
||||
|
||||
def generate_property(g, propname, prefix):
|
||||
def generate_property(g, propname):
|
||||
"""
|
||||
This generates the code for a single property on the style object.
|
||||
"""
|
||||
|
||||
name = prefix.name + propname
|
||||
|
||||
g.write("property {}:", name)
|
||||
g.write("property {}:", propname)
|
||||
g.indent()
|
||||
|
||||
if name in style_properties:
|
||||
# __get__
|
||||
g.write("def __get__(self):")
|
||||
g.indent()
|
||||
g.write("return self._get({})", style_property_index[propname])
|
||||
g.dedent()
|
||||
# __get__
|
||||
g.write("def __get__(self):")
|
||||
g.indent()
|
||||
g.write("return self._get({})", style_property_index[propname])
|
||||
g.dedent()
|
||||
|
||||
# __set__
|
||||
g.write("def __set__(self, value):")
|
||||
g.indent()
|
||||
g.write("self.properties.append({{ '{}' : value }})", name)
|
||||
g.write("self.properties.append({{ '{}' : value }})", propname)
|
||||
g.dedent()
|
||||
|
||||
# __del__
|
||||
g.write("def __del__(self):")
|
||||
g.indent()
|
||||
g.write("self.delattr('{}')", name)
|
||||
g.write("self.delattr('{}')", propname)
|
||||
g.dedent()
|
||||
|
||||
g.dedent()
|
||||
@@ -499,16 +500,15 @@ def generate_property(g, propname, prefix):
|
||||
|
||||
def generate_properties():
|
||||
|
||||
g = CodeGen("module/gen/styleproperties.pxi")
|
||||
g = CodeGen("module/gen/styleclass.pxi")
|
||||
|
||||
g.write("cdef class Style(StyleCore):")
|
||||
g.write("")
|
||||
|
||||
g.indent()
|
||||
|
||||
for propname in all_properties:
|
||||
for prefix in sorted(prefixes.values(), key=lambda p : p.index):
|
||||
generate_property(g, propname, prefix)
|
||||
for propname in style_properties:
|
||||
generate_property(g, propname)
|
||||
|
||||
g.dedent()
|
||||
g.close()
|
||||
|
||||
+22
-5
@@ -10,17 +10,28 @@
|
||||
// identifier. So get rid of it here.
|
||||
#undef environ
|
||||
|
||||
#if defined __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE
|
||||
#define IOS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined ANDROID
|
||||
|
||||
#define RENPY_GLES_2
|
||||
#define RENPY_GLES_2
|
||||
|
||||
#elif defined ANGLE
|
||||
|
||||
#define RENPY_GLES_2
|
||||
#define RENPY_GLES_2
|
||||
|
||||
#elif defined IOS
|
||||
|
||||
#define RENPY_GLES_2
|
||||
|
||||
#else
|
||||
|
||||
#define RENPY_OPENGL
|
||||
#define RENPY_OPENGL
|
||||
|
||||
#endif
|
||||
|
||||
@@ -54,11 +65,15 @@
|
||||
|
||||
#if defined RENPY_GLES_2
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef ANGLE
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#else
|
||||
#include <GLES2/gl2.h>
|
||||
#endif
|
||||
|
||||
typedef GLuint GLhandleARB;
|
||||
typedef GLchar GLcharARB;
|
||||
@@ -66,6 +81,7 @@ typedef GLchar GLcharARB;
|
||||
#define GL_MAX_TEXTURE_UNITS GL_MAX_TEXTURE_IMAGE_UNITS
|
||||
|
||||
#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER
|
||||
#define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING
|
||||
#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0
|
||||
#define glBindFramebufferEXT glBindFramebuffer
|
||||
#define glFramebufferTexture2DEXT glFramebufferTexture2D
|
||||
@@ -113,7 +129,7 @@ typedef GLfloat GLdouble;
|
||||
#define glClipPlane glClipPlanef
|
||||
|
||||
// This isn't defined on GL ES, but that's okay, since we'll disable
|
||||
// screenshots on Android.
|
||||
// screenshots on Android/iOS.
|
||||
#define GL_PACK_ROW_LENGTH 0
|
||||
|
||||
#define glClientActiveTextureARB glClientActiveTexture
|
||||
@@ -121,6 +137,7 @@ typedef GLfloat GLdouble;
|
||||
|
||||
#define GL_BGRA GL_RGBA
|
||||
#define GL_UNSIGNED_INT_8_8_8_8_REV GL_UNSIGNED_BYTE
|
||||
#define GL_MAX_TEXTURE_UNITS GL_MAX_TEXTURE_IMAGE_UNITS
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -597,6 +597,7 @@ cdef extern from "pyfreetype.h":
|
||||
FT_Fixed miter_limit )
|
||||
|
||||
void FT_Glyph_StrokeBorder(FT_Glyph *, FT_Stroker, FT_Bool, FT_Bool)
|
||||
void FT_Glyph_Stroke(FT_Glyph *, FT_Stroker, FT_Bool)
|
||||
|
||||
void FT_Stroker_Done(FT_Stroker)
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
from sdl2 cimport SDL_Surface, SDL_RWops
|
||||
from sdl2 cimport SDL_Surface, SDL_RWops, SDL_Window
|
||||
|
||||
cdef extern from "pygame_sdl2/pygame_sdl2.rwobject_api.h":
|
||||
void import_pygame_sdl2__rwobject()
|
||||
cdef extern from "pygame_sdl2/pygame_sdl2.h":
|
||||
int import_pygame_sdl2()
|
||||
SDL_RWops* RWopsFromPython(object obj)
|
||||
|
||||
cdef extern from "pygame_sdl2/pygame_sdl2.surface_api.h":
|
||||
int import_pygame_sdl2__surface()
|
||||
SDL_Surface *PySurface_AsSurface(object)
|
||||
SDL_Window *PyWindow_AsWindow(object)
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import renpy
|
||||
|
||||
from renpy.style cimport register_property_function, assign
|
||||
from cpython.ref cimport PyObject
|
||||
|
||||
from renpy.styledata.styleutil import none_is_null, expand_focus_mask, expand_outlines, expand_anchor
|
||||
|
||||
cdef inline object index_0(object v):
|
||||
return v[0]
|
||||
|
||||
cdef inline object index_1(object v):
|
||||
return v[1]
|
||||
|
||||
cdef inline object index_2(object v):
|
||||
return v[2]
|
||||
|
||||
cdef inline object index_3(object v):
|
||||
return v[3]
|
||||
+174
-26
@@ -26,11 +26,15 @@
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
|
||||
# Modified in 2010 by PyTom to generate Cython code that uses glew.
|
||||
from __future__ import print_function
|
||||
|
||||
# Modified in 2010,2014 by PyTom to generate Cython code that uses glew.
|
||||
|
||||
VERSION = "0.1"
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# Options
|
||||
@@ -2570,6 +2574,88 @@ GLhandleARB = gltype("GLhandleARB")
|
||||
GLstring = gltype("GLchar *")
|
||||
GLcharARB = gltype("GLchar")
|
||||
|
||||
|
||||
def exception_return(t):
|
||||
if "*" in str(t):
|
||||
return "NULL"
|
||||
else:
|
||||
return "0"
|
||||
|
||||
class GLFunction(object):
|
||||
|
||||
def __init__(self, type, name, args):
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.args = args
|
||||
|
||||
def declare_external(self, f):
|
||||
|
||||
print(' %s realGl%s "gl%s\" (%s)' % (
|
||||
self.type,
|
||||
self.name,
|
||||
self.name,
|
||||
", ".join(str(i) for i in self.args)
|
||||
), file=f)
|
||||
|
||||
def declare_wrapper(self, f):
|
||||
t = self.type
|
||||
|
||||
if t == GLvoid:
|
||||
t = "int"
|
||||
|
||||
print('cdef %s gl%s(%s) except? %s' % (
|
||||
t,
|
||||
self.name,
|
||||
", ".join(str(i) for i in self.args),
|
||||
exception_return(self.type),
|
||||
), file=f)
|
||||
|
||||
def define_wrapper(self, f):
|
||||
t = self.type
|
||||
|
||||
if t == GLvoid:
|
||||
t = "int"
|
||||
|
||||
print('cdef %s gl%s(%s) except? %s:' % (
|
||||
t,
|
||||
self.name,
|
||||
", ".join(("%s a%d" % (t, i)) for i, t in enumerate(self.args)),
|
||||
exception_return(self.type),
|
||||
), file=f)
|
||||
|
||||
print(" if check_errors & 4:", file=f)
|
||||
print(" renpy.display.log.write('gl%s')" % self.name, file=f)
|
||||
|
||||
print(" cdef GLenum error", file=f)
|
||||
|
||||
if self.type == GLvoid:
|
||||
print(" realGl%s(%s)" % (
|
||||
self.name,
|
||||
", ".join(("a%d" % i) for i in range(len(self.args)))
|
||||
), file=f)
|
||||
else:
|
||||
print(" cdef %s rv = realGl%s(%s)" % (
|
||||
self.type,
|
||||
self.name,
|
||||
", ".join(("a%d" % i) for i in range(len(self.args)))
|
||||
), file=f)
|
||||
|
||||
print(" if check_errors:", file=f)
|
||||
print(" error = realGlGetError()", file=f)
|
||||
print(" if error:", file=f)
|
||||
print(" message = 'GL error %%x in gl%s' %% error" % self.name, file=f)
|
||||
print(" if check_errors & 1:", file=f)
|
||||
print(" renpy.display.log.write('%s', message)", file=f)
|
||||
print(" if check_errors & 2:", file=f)
|
||||
print(" raise Exception(message)", file=f)
|
||||
|
||||
if self.type == GLvoid:
|
||||
print(" return 1", file=f)
|
||||
else:
|
||||
print(" return rv", file=f)
|
||||
|
||||
declarations = [ ]
|
||||
|
||||
def declare(*args):
|
||||
global is_enum
|
||||
is_enum = False
|
||||
@@ -2579,21 +2665,19 @@ def declare(*args):
|
||||
if isinstance(args[0], gltype):
|
||||
type = args.pop(0) #@ReservedAssignment
|
||||
else:
|
||||
type = "void" #@ReservedAssignment
|
||||
type = GLvoid #@ReservedAssignment
|
||||
|
||||
name = args.pop(0)
|
||||
|
||||
print " %s gl%s(%s)" % (
|
||||
type,
|
||||
name,
|
||||
", ".join(str(i) for i in args))
|
||||
declarations.append(GLFunction(type, name, args))
|
||||
|
||||
|
||||
constants = [ ]
|
||||
|
||||
def constant(name):
|
||||
constants.append("GL_" + name)
|
||||
|
||||
HEADER = """\
|
||||
PXD_HEADER = """\
|
||||
cdef extern from "glcompat.h":
|
||||
ctypedef unsigned int GLenum
|
||||
ctypedef unsigned char GLboolean
|
||||
@@ -2618,34 +2702,98 @@ cdef extern from "glcompat.h":
|
||||
ctypedef char GLcharARB
|
||||
"""
|
||||
|
||||
FOOTER = """\
|
||||
|
||||
cdef inline gl_check(where):
|
||||
cdef GLenum error
|
||||
error = glGetError()
|
||||
if error:
|
||||
import renpy
|
||||
renpy.display.log.write("GL error 0x%X at %s", error, where)
|
||||
PYX_HEADER = """\
|
||||
import os
|
||||
import renpy
|
||||
|
||||
cdef int check_errors
|
||||
check_errors = int(os.environ.get("RENPY_GL_CHECK_ERRORS", 0))
|
||||
"""
|
||||
|
||||
def main():
|
||||
out = sys.stdout
|
||||
out.write(HEADER)
|
||||
def find_gl_names(dirname, gl1):
|
||||
|
||||
names = set()
|
||||
|
||||
for i in os.listdir(dirname):
|
||||
if not i.endswith('.pyx'):
|
||||
continue
|
||||
|
||||
if i in [ "gl.pyx", "gl1.pyx" ]:
|
||||
continue
|
||||
|
||||
GL1_FILES = [ "glenviron_fixed.pyx", "glenviron_limited.pyx" ]
|
||||
|
||||
if gl1:
|
||||
if i not in GL1_FILES:
|
||||
continue
|
||||
else:
|
||||
if i in GL1_FILES:
|
||||
continue
|
||||
|
||||
fn = os.path.join(dirname, i)
|
||||
|
||||
with open(fn, "r") as f:
|
||||
data = f.read()
|
||||
|
||||
for m in re.finditer(r'gl([A-Z]\w+)', data):
|
||||
names.add(m.group(1))
|
||||
|
||||
rv = list(names)
|
||||
rv.sort()
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
def generate(dirname, gl1):
|
||||
|
||||
if gl1:
|
||||
prefix = "gl1"
|
||||
else:
|
||||
prefix = "gl"
|
||||
|
||||
names = find_gl_names(dirname, gl1)
|
||||
|
||||
global constants
|
||||
constants = [ ]
|
||||
|
||||
global declarations
|
||||
declarations = [ ]
|
||||
|
||||
generate_tegl()
|
||||
constant("BGRA")
|
||||
|
||||
constant("BGRA")
|
||||
constants.sort()
|
||||
constants.append("RENPY_THIRD_TEXTURE")
|
||||
|
||||
print
|
||||
print " enum:"
|
||||
for i in constants:
|
||||
print " %s" % i
|
||||
decl_by_name = dict((i.name, i) for i in declarations)
|
||||
|
||||
print
|
||||
print FOOTER
|
||||
with open(os.path.join(dirname, prefix + ".pxd"), "w") as f:
|
||||
print(PXD_HEADER, file=f)
|
||||
|
||||
print(file=f)
|
||||
print(" enum:", file=f)
|
||||
for i in constants:
|
||||
print(" %s" % i, file=f)
|
||||
|
||||
print(file=f)
|
||||
for i in declarations:
|
||||
i.declare_external(f)
|
||||
|
||||
print(file=f)
|
||||
for i in names:
|
||||
decl_by_name[i].declare_wrapper(f)
|
||||
|
||||
with open(os.path.join(dirname, prefix + ".pyx"), "w") as f:
|
||||
print(PYX_HEADER, file=f)
|
||||
|
||||
for i in names:
|
||||
print(file=f)
|
||||
decl_by_name[i].define_wrapper(f)
|
||||
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
generate(os.path.join(root, "renpy", "gl"), False)
|
||||
generate(os.path.join(root, "renpy", "gl"), True)
|
||||
generate(os.path.join(root, "renpy", "angle"), False)
|
||||
|
||||
+3
-1
@@ -26,6 +26,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include <SDL.h>
|
||||
#include <SDL_thread.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* Declarations of ffdecode functions. */
|
||||
struct VideoState;
|
||||
@@ -408,8 +409,9 @@ static void pan_audio(struct Channel *c, Uint8 *stream, int length) {
|
||||
static void callback(void *userdata, Uint8 *stream, int length) {
|
||||
int channel = 0;
|
||||
|
||||
for (channel = 0; channel < num_channels; channel++) {
|
||||
bzero(stream, length);
|
||||
|
||||
for (channel = 0; channel < num_channels; channel++) {
|
||||
|
||||
int mixed = 0;
|
||||
struct Channel *c = &channels[channel];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- python -*-
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -20,14 +20,8 @@
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
cdef extern from "SDL.h":
|
||||
cdef struct SDL_RWops:
|
||||
pass
|
||||
|
||||
cdef extern from "pygame_sdl2/pygame_sdl2.rwobject_api.h":
|
||||
|
||||
void import_pygame_sdl2__rwobject()
|
||||
SDL_RWops* RWopsFromPythonThreaded(object obj)
|
||||
from pygame_sdl2 cimport *
|
||||
import_pygame_sdl2()
|
||||
|
||||
cdef extern from "pss.h":
|
||||
|
||||
@@ -68,7 +62,7 @@ def check_error():
|
||||
def play(channel, file, name, paused=False, fadein=0, tight=False):
|
||||
cdef SDL_RWops *rw
|
||||
|
||||
rw = RWopsFromPythonThreaded(file)
|
||||
rw = RWopsFromPython(file)
|
||||
|
||||
if rw == NULL:
|
||||
raise Exception, "Could not create RWops."
|
||||
@@ -90,7 +84,7 @@ def play(channel, file, name, paused=False, fadein=0, tight=False):
|
||||
def queue(channel, file, name, fadein=0, tight=False):
|
||||
cdef SDL_RWops *rw
|
||||
|
||||
rw = RWopsFromPythonThreaded(file)
|
||||
rw = RWopsFromPython(file)
|
||||
|
||||
if tight:
|
||||
tight = 1
|
||||
@@ -188,5 +182,3 @@ def movie_size():
|
||||
def check_version(version):
|
||||
if version < 2 or version > 4:
|
||||
raise Exception("pysdlsound version mismatch.")
|
||||
|
||||
import_pygame_sdl2__rwobject()
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#include <Python.h>
|
||||
#include <fribidi/fribidi.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef alloca
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
/* This is easier than trying to figure out the header that alloca is */
|
||||
/* defined in. */
|
||||
void *alloca(size_t size);
|
||||
// void *alloca(size_t size);
|
||||
|
||||
PyObject *renpybidi_log2vis(PyObject *s, int *direction) {
|
||||
char *src;
|
||||
@@ -12,7 +17,7 @@ PyObject *renpybidi_log2vis(PyObject *s, int *direction) {
|
||||
int unisize;
|
||||
FriBidiChar *dstuni;
|
||||
char *dst;
|
||||
|
||||
|
||||
src = PyString_AsString(s);
|
||||
|
||||
if (src == NULL) {
|
||||
@@ -24,7 +29,7 @@ PyObject *renpybidi_log2vis(PyObject *s, int *direction) {
|
||||
srcuni = (FriBidiChar *) alloca(size * 4);
|
||||
dstuni = (FriBidiChar *) alloca(size * 4);
|
||||
dst = (char *) alloca(size * 4);
|
||||
|
||||
|
||||
unisize = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, src, size, srcuni);
|
||||
|
||||
fribidi_log2vis(
|
||||
|
||||
+47
-25
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -48,9 +48,10 @@ def setup_env(name):
|
||||
|
||||
setup_env("CC")
|
||||
setup_env("LD")
|
||||
setup_env("CXX")
|
||||
|
||||
import setuplib
|
||||
from setuplib import android, include, library, cython, pymodule, copyfile, find_unnecessary_gen
|
||||
from setuplib import android, ios, include, library, cython, pymodule, copyfile, find_unnecessary_gen
|
||||
|
||||
# These control the level of optimization versus debugging.
|
||||
setuplib.extra_compile_args = [ "-Wno-unused-function" ]
|
||||
@@ -86,14 +87,18 @@ has_fribidi = library("fribidi", optional=True)
|
||||
library("z")
|
||||
has_libglew = library("GLEW", optional=True)
|
||||
has_libglew32 = library("glew32", optional=True)
|
||||
|
||||
has_angle = windows and library("EGL", optional=True) and library("GLESv2", optional=True)
|
||||
|
||||
if android:
|
||||
sdl = [ 'sdl', 'GLESv2', 'log' ]
|
||||
sdl = [ 'SDL2', 'GLESv2', 'log' ]
|
||||
png = 'png16'
|
||||
else:
|
||||
sdl = [ 'SDL2' ]
|
||||
png = 'png'
|
||||
|
||||
if has_fribidi:
|
||||
|
||||
if has_fribidi and (not android) and (not ios):
|
||||
try:
|
||||
# Some versions of fribidi require glib, and it doesn't hurt to include it in
|
||||
# our path.
|
||||
@@ -102,49 +107,63 @@ if has_fribidi:
|
||||
except:
|
||||
pass
|
||||
|
||||
steam_sdk = os.environ.get("RENPY_STEAM_SDK", None)
|
||||
steam_platform = os.environ.get("RENPY_STEAM_PLATFORM", "")
|
||||
|
||||
if steam_sdk:
|
||||
setuplib.library_dirs.append("{}/redistributable_bin/{}".format(steam_sdk, steam_platform))
|
||||
setuplib.include_dirs.append("{}/public".format(steam_sdk))
|
||||
|
||||
# Modules directory.
|
||||
cython(
|
||||
"_renpy",
|
||||
[ "IMG_savepng.c", "core.c", "subpixel.c"],
|
||||
sdl + [ 'png', 'z', 'm' ])
|
||||
sdl + [ png, 'z', 'm' ])
|
||||
|
||||
if has_fribidi and not android:
|
||||
if has_fribidi:
|
||||
cython(
|
||||
"_renpybidi",
|
||||
[ "renpybidicore.c" ],
|
||||
['fribidi'], define_macros=[ ("FRIBIDI_ENTRY", "") ])
|
||||
|
||||
cython("_renpysteam", language="c++", compile_if=steam_sdk, libs=["steam_api"])
|
||||
|
||||
# Sound.
|
||||
pymodule("pysdlsound.__init__")
|
||||
|
||||
if not android:
|
||||
sound = [ "avformat", "avcodec", "avutil", "z" ]
|
||||
macros = [ ]
|
||||
|
||||
sound = [ "avformat", "avcodec", "avutil", "z" ]
|
||||
macros = [ ]
|
||||
if has_avresample:
|
||||
sound.insert(0, "avresample")
|
||||
macros.append(("HAS_RESAMPLE", 1))
|
||||
|
||||
if has_avresample:
|
||||
sound.insert(0, "avresample")
|
||||
macros.append(("HAS_RESAMPLE", 1))
|
||||
if has_swscale:
|
||||
sound.insert(0, "swscale")
|
||||
|
||||
if has_swscale:
|
||||
sound.insert(0, "swscale")
|
||||
|
||||
cython(
|
||||
"pysdlsound.sound",
|
||||
[ "pss.c", "ffdecode.c" ],
|
||||
libs = sdl + sound,
|
||||
define_macros=macros)
|
||||
cython(
|
||||
"pysdlsound.sound",
|
||||
[ "pss.c", "ffdecode.c" ],
|
||||
libs = sdl + sound,
|
||||
define_macros=macros)
|
||||
|
||||
# renpy
|
||||
cython("renpy.style")
|
||||
cython("renpy.styleclass")
|
||||
# cython("renpy.styleclass")
|
||||
|
||||
# renpy.styledata
|
||||
cython("renpy.styledata.styleclass")
|
||||
cython("renpy.styledata.stylesets")
|
||||
|
||||
for p in generate_styles.prefixes:
|
||||
cython("renpy.styledata.style_{}functions".format(p), pyx="gen/style_{}functions.pyx".format(p))
|
||||
|
||||
# renpy.display
|
||||
cython("renpy.display.render", libs=[ 'z', 'm' ])
|
||||
cython("renpy.display.accelerator", libs=sdl + [ 'z', 'm' ])
|
||||
|
||||
# renpy.gl
|
||||
if android:
|
||||
if (android or ios):
|
||||
glew_libs = [ 'GLESv2', 'z', 'm' ]
|
||||
gl2_only = True
|
||||
egl = "egl_none.c"
|
||||
@@ -157,6 +176,8 @@ else:
|
||||
gl2_only = False
|
||||
egl = "egl_none.c"
|
||||
|
||||
cython("renpy.gl.gl", libs=glew_libs)
|
||||
cython("renpy.gl.gl1", libs=glew_libs, compile_if=not gl2_only)
|
||||
cython("renpy.gl.gldraw", libs=glew_libs, source=[ egl ])
|
||||
cython("renpy.gl.gltexture", libs=glew_libs)
|
||||
cython("renpy.gl.glenviron_shader", libs=glew_libs)
|
||||
@@ -167,7 +188,7 @@ cython("renpy.gl.glrtt_fbo", libs=glew_libs)
|
||||
|
||||
# renpy.angle
|
||||
def anglecopy(fn):
|
||||
if android:
|
||||
if (android or ios):
|
||||
return
|
||||
|
||||
copyfile("renpy/gl/" + fn, "renpy/angle/" + fn, "DEF ANGLE = False", "DEF ANGLE = True")
|
||||
@@ -176,17 +197,17 @@ anglecopy("glblacklist.py")
|
||||
anglecopy("gldraw.pxd")
|
||||
anglecopy("gldraw.pyx")
|
||||
anglecopy("glenviron_shader.pyx")
|
||||
anglecopy("gl.pxd")
|
||||
anglecopy("glrtt_fbo.pyx")
|
||||
anglecopy("glrtt_copy.pyx")
|
||||
anglecopy("gltexture.pxd")
|
||||
anglecopy("gltexture.pyx")
|
||||
|
||||
angle_libs = [ "SDL", "EGL", "GLESv2" ]
|
||||
angle_libs = [ "SDL2", "EGL", "GLESv2" ]
|
||||
|
||||
def anglecython(name, source=[]):
|
||||
cython(name, libs=angle_libs, compile_if=has_angle, define_macros=[ ( "ANGLE", None ) ], source=source)
|
||||
|
||||
anglecython("renpy.angle.gl")
|
||||
anglecython("renpy.angle.gldraw", source=[ "egl_angle.c" ])
|
||||
anglecython("renpy.angle.gltexture")
|
||||
anglecython("renpy.angle.glenviron_shader")
|
||||
@@ -206,6 +227,7 @@ find_unnecessary_gen()
|
||||
|
||||
# Figure out the version, and call setup.
|
||||
sys.path.insert(0, '..')
|
||||
|
||||
import renpy
|
||||
|
||||
setuplib.setup("Ren'Py", renpy.version[7:])
|
||||
|
||||
+34
-11
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -31,6 +31,9 @@ import distutils.core
|
||||
# This flag determines if we are compiling for Android or not.
|
||||
android = "RENPY_ANDROID" in os.environ
|
||||
|
||||
# True if we're building on ios.
|
||||
ios = "RENPY_IOS" in os.environ
|
||||
|
||||
# The cython command.
|
||||
cython_command = os.environ.get("RENPY_CYTHON", "cython")
|
||||
|
||||
@@ -40,7 +43,7 @@ cython_command = os.environ.get("RENPY_CYTHON", "cython")
|
||||
|
||||
# The install variable is a list of directories that have Ren'Py
|
||||
# dependencies installed in them.
|
||||
if not android:
|
||||
if not android or ios:
|
||||
install = os.environ.get("RENPY_DEPS_INSTALL", "/usr")
|
||||
install = install.split("::")
|
||||
install = [ os.path.abspath(i) for i in install ]
|
||||
@@ -66,7 +69,7 @@ def include(header, directory=None, optional=True):
|
||||
If given, returns False rather than abandoning the process.
|
||||
"""
|
||||
|
||||
if android:
|
||||
if android or ios:
|
||||
return True
|
||||
|
||||
for i in install:
|
||||
@@ -105,7 +108,7 @@ def library(name, optional=False):
|
||||
rather than reporting an error.
|
||||
"""
|
||||
|
||||
if android:
|
||||
if android or ios:
|
||||
return True
|
||||
|
||||
for i in install:
|
||||
@@ -135,7 +138,7 @@ extensions = [ ]
|
||||
# A list of macros that are defined for all modules.
|
||||
global_macros = [ ]
|
||||
|
||||
def cmodule(name, source, libs=[], define_macros=[]):
|
||||
def cmodule(name, source, libs=[], define_macros=[], language="c"):
|
||||
"""
|
||||
Compiles the python module `name` from the files given in
|
||||
`source`, and the libraries in `libs`.
|
||||
@@ -150,12 +153,13 @@ def cmodule(name, source, libs=[], define_macros=[]):
|
||||
extra_link_args=extra_link_args,
|
||||
libraries=libs,
|
||||
define_macros=define_macros + global_macros,
|
||||
language=language,
|
||||
))
|
||||
|
||||
|
||||
necessary_gen = [ ]
|
||||
|
||||
def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
|
||||
def cython(name, source=[], libs=[], compile_if=True, define_macros=[], pyx=None, language="c"):
|
||||
"""
|
||||
Compiles a cython module. This takes care of regenerating it as necessary
|
||||
when it, or any of the files it depends on, changes.
|
||||
@@ -164,7 +168,10 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
|
||||
# Find the pyx file.
|
||||
split_name = name.split(".")
|
||||
|
||||
fn = "/".join(split_name) + ".pyx"
|
||||
if pyx is not None:
|
||||
fn = pyx
|
||||
else:
|
||||
fn = "/".join(split_name) + ".pyx"
|
||||
|
||||
if os.path.exists(os.path.join("..", fn)):
|
||||
fn = os.path.join("..", fn)
|
||||
@@ -202,8 +209,13 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
|
||||
deps = [ i for i in deps if (not i.startswith("cpython/")) and (not i.startswith("libc/")) ]
|
||||
|
||||
# Determine if any of the dependencies are newer than the c file.
|
||||
c_fn = os.path.join("gen", name + ".c")
|
||||
necessary_gen.append(name + ".c")
|
||||
|
||||
if language == "c++":
|
||||
c_fn = os.path.join("gen", name + ".cc")
|
||||
necessary_gen.append(name + ".cc")
|
||||
else:
|
||||
c_fn = os.path.join("gen", name + ".c")
|
||||
necessary_gen.append(name + ".c")
|
||||
|
||||
if os.path.exists(c_fn):
|
||||
c_mtime = os.path.getmtime(c_fn)
|
||||
@@ -243,11 +255,18 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
|
||||
|
||||
try:
|
||||
import subprocess
|
||||
|
||||
if language == "c++":
|
||||
lang_args = [ "--cplus" ]
|
||||
else:
|
||||
lang_args = [ ]
|
||||
|
||||
subprocess.check_call([
|
||||
cython_command,
|
||||
"-Iinclude",
|
||||
"-Igen",
|
||||
"-a",
|
||||
"-I..",
|
||||
] + lang_args + [
|
||||
fn,
|
||||
"-o",
|
||||
c_fn])
|
||||
@@ -260,7 +279,7 @@ def cython(name, source=[], libs=[], compile_if=True, define_macros=[]):
|
||||
|
||||
# Build the module normally once we have the c file.
|
||||
if compile_if:
|
||||
cmodule(name, [ c_fn ] + source, libs=libs, define_macros=define_macros)
|
||||
cmodule(name, [ c_fn ] + source, libs=libs, define_macros=define_macros, language=language)
|
||||
|
||||
def find_unnecessary_gen():
|
||||
|
||||
@@ -294,6 +313,10 @@ def copyfile(source, dest, replace=None, replace_with=None):
|
||||
sfn = os.path.join("..", source)
|
||||
dfn = os.path.join("..", dest)
|
||||
|
||||
if os.path.exists(dfn):
|
||||
if os.path.getmtime(sfn) <= os.path.getmtime(dfn):
|
||||
return
|
||||
|
||||
sf = file(sfn, "rb")
|
||||
data = sf.read()
|
||||
sf.close()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef STEAMCALLBACKS_H
|
||||
#define STEAMCALLBACKS_H
|
||||
#include "steam/steam_api.h"
|
||||
|
||||
template <class P>
|
||||
class SteamCallback : CCallbackBase {
|
||||
void (*callback)(P*);
|
||||
|
||||
public:
|
||||
|
||||
SteamCallback(void (*func)(P *)) : callback(func) {
|
||||
m_iCallback = P::k_iCallback;
|
||||
SteamAPI_RegisterCallback(this, P::k_iCallback);
|
||||
}
|
||||
|
||||
~SteamCallback() {
|
||||
SteamAPI_UnregisterCallback(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void Run(void *param) {
|
||||
callback((P *) param);
|
||||
}
|
||||
|
||||
virtual void Run( void *param, bool, SteamAPICall_t ) {
|
||||
callback((P *) param);
|
||||
}
|
||||
|
||||
int GetCallbackSizeBytes() {
|
||||
return sizeof(P);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -8,12 +8,12 @@
|
||||
|
||||
#include "renpy.h"
|
||||
#include <SDL.h>
|
||||
#include <pygame_sdl2/pygame_sdl2.surface_api.h>
|
||||
#include <pygame_sdl2/pygame_sdl2.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
void subpixel_init() {
|
||||
import_pygame_sdl2__surface();
|
||||
import_pygame_sdl2();
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# This file is part of Ren'Py. The license below applies to Ren'Py only.
|
||||
# Games and other projects that use Ren'Py may use a different license.
|
||||
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -65,12 +65,34 @@ def path_to_saves(gamedir):
|
||||
if os.path.isdir(rv) and test_writable(rv):
|
||||
break
|
||||
|
||||
print "Using savedir", rv
|
||||
print "Saving to", rv
|
||||
|
||||
# We return the last path as the default.
|
||||
|
||||
return rv
|
||||
|
||||
if renpy.ios:
|
||||
from pyobjus import autoclass
|
||||
from pyobjus.objc_py_types import enum
|
||||
|
||||
NSSearchPathDirectory = enum("NSSearchPathDirectory", NSDocumentDirectory=9)
|
||||
NSSearchPathDomainMask = enum("NSSearchPathDomainMask", NSUserDomainMask=1)
|
||||
|
||||
NSFileManager = autoclass('NSFileManager')
|
||||
manager = NSFileManager.defaultManager()
|
||||
url = manager.URLsForDirectory_inDomains_(
|
||||
NSSearchPathDirectory.NSDocumentDirectory,
|
||||
NSSearchPathDomainMask.NSUserDomainMask,
|
||||
).lastObject()
|
||||
|
||||
# url.path seems to change type based on iOS version, for some reason.
|
||||
try:
|
||||
rv = url.path().UTF8String().decode("utf-8")
|
||||
except:
|
||||
rv = url.path.UTF8String().decode("utf-8")
|
||||
|
||||
print "Saving to", rv
|
||||
return rv
|
||||
|
||||
# No save directory given.
|
||||
if not renpy.config.save_directory:
|
||||
@@ -165,10 +187,6 @@ def main():
|
||||
print >>sys.stderr, "correctly, preserving the directory structure."
|
||||
raise
|
||||
|
||||
if android:
|
||||
renpy.linux = False
|
||||
renpy.android = True
|
||||
|
||||
renpy.bootstrap.bootstrap(renpy_base)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+61
-33
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -40,10 +40,10 @@ except ImportError:
|
||||
vc_version = 0
|
||||
|
||||
# The tuple giving the version number.
|
||||
version_tuple = (6, 18, 3, vc_version)
|
||||
version_tuple = (6, 99, 0, vc_version)
|
||||
|
||||
# The name of this version.
|
||||
version_name = "... through shared popular culture."
|
||||
version_name = "Here's to the crazy ones."
|
||||
|
||||
# A verbose string giving the version.
|
||||
version = "Ren'Py " + ".".join(str(i) for i in version_tuple)
|
||||
@@ -53,6 +53,41 @@ script_version = 5003000
|
||||
savegame_suffix = "-LT1.save"
|
||||
bytecode_version = 1
|
||||
|
||||
|
||||
################################################################################
|
||||
# Platform Information
|
||||
################################################################################
|
||||
|
||||
# Information about the platform we're running on. We break the platforms
|
||||
# up into 5 groups - windows-like, mac-like, linux-like, android-like,
|
||||
# and ios-like.
|
||||
windows = False
|
||||
macintosh = False
|
||||
linux = False
|
||||
android = False
|
||||
ios = False
|
||||
|
||||
import platform
|
||||
|
||||
if platform.win32_ver()[0]:
|
||||
windows = True
|
||||
elif "RENPY_IOS" in os.environ:
|
||||
ios = True
|
||||
elif platform.mac_ver()[0]:
|
||||
macintosh = True
|
||||
elif "ANDROID_PRIVATE" in os.environ:
|
||||
android = True
|
||||
else:
|
||||
linux = True
|
||||
|
||||
# A flag that's true if we're on a smartphone or tablet-like platform.
|
||||
mobile = android or ios
|
||||
|
||||
|
||||
################################################################################
|
||||
# Backup Data for Reload
|
||||
################################################################################
|
||||
|
||||
# True if this is the first time we've started - even including
|
||||
# utter restarts.
|
||||
first_utter_start = True
|
||||
@@ -117,11 +152,8 @@ class Backup():
|
||||
# A map from module to the set of names in that module.
|
||||
self.names = { }
|
||||
|
||||
try:
|
||||
import android # @UnresolvedImport
|
||||
if mobile:
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
for m in sys.modules.values():
|
||||
if m is None:
|
||||
@@ -147,6 +179,9 @@ class Backup():
|
||||
if name in backup_blacklist:
|
||||
return
|
||||
|
||||
if name.startswith("renpy.styledata"):
|
||||
return
|
||||
|
||||
self.names[mod] = set(vars(mod).keys())
|
||||
|
||||
for k, v in vars(mod).iteritems():
|
||||
@@ -197,6 +232,9 @@ class Backup():
|
||||
# A backup of the Ren'Py modules after initial import.
|
||||
backup = None
|
||||
|
||||
################################################################################
|
||||
# Import
|
||||
################################################################################
|
||||
|
||||
def update_path(package):
|
||||
"""
|
||||
@@ -215,7 +253,6 @@ def update_path(package):
|
||||
libexec = os.path.dirname(encodings.__path__[0])
|
||||
package.__path__.append(os.path.join(libexec, *name))
|
||||
|
||||
|
||||
def import_all():
|
||||
|
||||
# Note: If we add a new update_path, we have to add an equivalent
|
||||
@@ -254,7 +291,15 @@ def import_all():
|
||||
import renpy.python
|
||||
import renpy.script
|
||||
import renpy.statements
|
||||
|
||||
import renpy.styledata # @UnresolvedImport
|
||||
update_path(renpy.styledata)
|
||||
|
||||
import renpy.style
|
||||
renpy.styledata.import_style_functions()
|
||||
|
||||
sys.modules['renpy.styleclass'] = renpy.style
|
||||
|
||||
import renpy.substitutions
|
||||
import renpy.translation
|
||||
|
||||
@@ -306,8 +351,9 @@ def import_all():
|
||||
import renpy.display.dragdrop
|
||||
import renpy.display.imagemap
|
||||
import renpy.display.predict
|
||||
import renpy.display.emulator # @UnresolvedImport
|
||||
import renpy.display.tts # @UnresolvedImport
|
||||
import renpy.display.emulator
|
||||
import renpy.display.tts
|
||||
import renpy.display.gesture
|
||||
|
||||
import renpy.display.error
|
||||
|
||||
@@ -337,6 +383,7 @@ def import_all():
|
||||
import renpy.exports
|
||||
import renpy.character # depends on exports. @UnresolvedImport
|
||||
|
||||
import renpy.add_from
|
||||
import renpy.dump
|
||||
|
||||
import renpy.config # depends on lots. @UnresolvedImport
|
||||
@@ -448,7 +495,7 @@ def setup_modulefinder(modulefinder):
|
||||
|
||||
libexec = os.path.dirname(_renpy.__file__)
|
||||
|
||||
for i in [ "display", "gl", "angle", "text" ]:
|
||||
for i in [ "display", "gl", "angle", "text", "styledata" ]:
|
||||
|
||||
displaypath = os.path.join(libexec, "renpy", i)
|
||||
|
||||
@@ -467,6 +514,8 @@ def import_cython():
|
||||
import renpy.display.accelerator
|
||||
import renpy.display.render
|
||||
|
||||
import renpy.gl.gl
|
||||
import renpy.gl.gl1
|
||||
import renpy.gl.gldraw
|
||||
import renpy.gl.glenviron_fixed
|
||||
import renpy.gl.glenviron_limited
|
||||
@@ -475,37 +524,16 @@ def import_cython():
|
||||
import renpy.gl.glrtt_fbo
|
||||
import renpy.gl.gltexture
|
||||
|
||||
import renpy.angle.gl
|
||||
import renpy.angle.gldraw
|
||||
import renpy.angle.glenviron_shader
|
||||
import renpy.angle.glrtt_copy
|
||||
import renpy.angle.glrtt_fbo
|
||||
import renpy.angle.gltexture
|
||||
|
||||
import renpy.styleclass # @UnresolvedImport
|
||||
|
||||
|
||||
if False:
|
||||
import renpy.defaultstore as store
|
||||
|
||||
|
||||
################################################################################
|
||||
# Platform Information
|
||||
################################################################################
|
||||
|
||||
# Information about the platform we're running on. We break the platforms
|
||||
# up into 4 groups - windows-like, mac-like, linux-like, and android-like.
|
||||
windows = False
|
||||
macintosh = False
|
||||
linux = False
|
||||
android = False
|
||||
|
||||
import platform
|
||||
|
||||
if platform.win32_ver()[0]:
|
||||
windows = True
|
||||
elif platform.mac_ver()[0]:
|
||||
macintosh = True
|
||||
else:
|
||||
linux = True
|
||||
|
||||
# The android init code in renpy.py will set linux=False and android=True.
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import collections
|
||||
import renpy
|
||||
import os
|
||||
import codecs
|
||||
|
||||
# A map from filename to position, target label pairs.
|
||||
missing = collections.defaultdict(list)
|
||||
|
||||
def report_missing(target, filename, position):
|
||||
"""
|
||||
Reports that the call statement ending at `position` in `filename`
|
||||
is missing a from clause.
|
||||
|
||||
`target`
|
||||
The string
|
||||
"""
|
||||
|
||||
missing[filename].append((position, target))
|
||||
|
||||
|
||||
# Labels that we've created while running add_from.
|
||||
new_labels = set()
|
||||
|
||||
def generate_label(target):
|
||||
"""
|
||||
Generate a reasonable and unique new label for a call to `target`.
|
||||
"""
|
||||
|
||||
n = 0
|
||||
|
||||
while True:
|
||||
if n:
|
||||
label = "_call_{}_{}".format(target, n)
|
||||
else:
|
||||
label = "_call_{}".format(target)
|
||||
|
||||
if not renpy.exports.has_label(label) and not (label in new_labels):
|
||||
break
|
||||
|
||||
n += 1
|
||||
|
||||
new_labels.add(label)
|
||||
return label
|
||||
|
||||
|
||||
def process_file(fn):
|
||||
"""
|
||||
Adds missing from clauses to `fn`.
|
||||
"""
|
||||
|
||||
if not os.path.exists(fn):
|
||||
return
|
||||
|
||||
edits = missing[fn]
|
||||
edits.sort()
|
||||
|
||||
with codecs.open(fn, "r", "utf-8") as f:
|
||||
data = f.read()
|
||||
|
||||
# How much of the input has been consumed.
|
||||
consumed = 0
|
||||
|
||||
# The output.
|
||||
output = u""
|
||||
|
||||
for position, target in edits:
|
||||
output += data[consumed:position]
|
||||
consumed = position
|
||||
|
||||
output += " from {}".format(generate_label(target))
|
||||
|
||||
output += data[consumed:]
|
||||
|
||||
with codecs.open(fn + ".new", "w", "utf-8") as f:
|
||||
f.write(output)
|
||||
|
||||
try:
|
||||
os.unlink(fn + ".bak")
|
||||
except:
|
||||
pass
|
||||
|
||||
os.rename(fn, fn + ".bak")
|
||||
os.rename(fn + ".new", fn)
|
||||
|
||||
def add_from():
|
||||
|
||||
renpy.arguments.takes_no_arguments("Adds from clauses to call statements that are missing them.")
|
||||
|
||||
for fn in missing:
|
||||
if fn.startswith(renpy.config.gamedir):
|
||||
process_file(fn)
|
||||
|
||||
return False
|
||||
|
||||
renpy.arguments.register_command("add_from", add_from)
|
||||
|
||||
+1572
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,711 @@
|
||||
import os
|
||||
import renpy
|
||||
|
||||
cdef int check_errors
|
||||
check_errors = int(os.environ.get("RENPY_GL_CHECK_ERRORS", 0))
|
||||
|
||||
|
||||
cdef int glActiveTextureARB(GLenum a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glActiveTextureARB')
|
||||
cdef GLenum error
|
||||
realGlActiveTextureARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glActiveTextureARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glAttachObjectARB(GLhandleARB a0, GLhandleARB a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glAttachObjectARB')
|
||||
cdef GLenum error
|
||||
realGlAttachObjectARB(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glAttachObjectARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glBindFramebufferEXT(GLenum a0, GLuint a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glBindFramebufferEXT')
|
||||
cdef GLenum error
|
||||
realGlBindFramebufferEXT(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glBindFramebufferEXT' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glBindTexture(GLenum a0, GLuint a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glBindTexture')
|
||||
cdef GLenum error
|
||||
realGlBindTexture(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glBindTexture' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glBlendFunc(GLenum a0, GLenum a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glBlendFunc')
|
||||
cdef GLenum error
|
||||
realGlBlendFunc(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glBlendFunc' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glClear(GLbitfield a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glClear')
|
||||
cdef GLenum error
|
||||
realGlClear(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glClear' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glClearColor(GLclampf a0, GLclampf a1, GLclampf a2, GLclampf a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glClearColor')
|
||||
cdef GLenum error
|
||||
realGlClearColor(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glClearColor' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glCompileShaderARB(GLhandleARB a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glCompileShaderARB')
|
||||
cdef GLenum error
|
||||
realGlCompileShaderARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glCompileShaderARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glCopyTexSubImage2D(GLenum a0, GLint a1, GLint a2, GLint a3, GLint a4, GLint a5, GLsizei a6, GLsizei a7) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glCopyTexSubImage2D')
|
||||
cdef GLenum error
|
||||
realGlCopyTexSubImage2D(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glCopyTexSubImage2D' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef GLhandleARB glCreateProgramObjectARB() except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glCreateProgramObjectARB')
|
||||
cdef GLenum error
|
||||
cdef GLhandleARB rv = realGlCreateProgramObjectARB()
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glCreateProgramObjectARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return rv
|
||||
|
||||
cdef GLhandleARB glCreateShaderObjectARB(GLenum a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glCreateShaderObjectARB')
|
||||
cdef GLenum error
|
||||
cdef GLhandleARB rv = realGlCreateShaderObjectARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glCreateShaderObjectARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return rv
|
||||
|
||||
cdef int glDeleteFramebuffersEXT(GLsizei a0, GLuint * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDeleteFramebuffersEXT')
|
||||
cdef GLenum error
|
||||
realGlDeleteFramebuffersEXT(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDeleteFramebuffersEXT' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glDeleteProgram(GLuint a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDeleteProgram')
|
||||
cdef GLenum error
|
||||
realGlDeleteProgram(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDeleteProgram' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glDeleteShader(GLuint a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDeleteShader')
|
||||
cdef GLenum error
|
||||
realGlDeleteShader(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDeleteShader' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glDeleteTextures(GLsizei a0, GLuint * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDeleteTextures')
|
||||
cdef GLenum error
|
||||
realGlDeleteTextures(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDeleteTextures' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glDisable(GLenum a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDisable')
|
||||
cdef GLenum error
|
||||
realGlDisable(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDisable' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glDisableVertexAttribArrayARB(GLuint a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDisableVertexAttribArrayARB')
|
||||
cdef GLenum error
|
||||
realGlDisableVertexAttribArrayARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDisableVertexAttribArrayARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glDrawArrays(GLenum a0, GLint a1, GLsizei a2) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glDrawArrays')
|
||||
cdef GLenum error
|
||||
realGlDrawArrays(a0, a1, a2)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glDrawArrays' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glEnable(GLenum a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glEnable')
|
||||
cdef GLenum error
|
||||
realGlEnable(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glEnable' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glEnableVertexAttribArrayARB(GLuint a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glEnableVertexAttribArrayARB')
|
||||
cdef GLenum error
|
||||
realGlEnableVertexAttribArrayARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glEnableVertexAttribArrayARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glFinish() except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glFinish')
|
||||
cdef GLenum error
|
||||
realGlFinish()
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glFinish' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glFramebufferTexture2DEXT(GLenum a0, GLenum a1, GLenum a2, GLuint a3, GLint a4) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glFramebufferTexture2DEXT')
|
||||
cdef GLenum error
|
||||
realGlFramebufferTexture2DEXT(a0, a1, a2, a3, a4)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glFramebufferTexture2DEXT' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glGenFramebuffersEXT(GLsizei a0, GLuint * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGenFramebuffersEXT')
|
||||
cdef GLenum error
|
||||
realGlGenFramebuffersEXT(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGenFramebuffersEXT' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glGenTextures(GLsizei a0, GLuint * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGenTextures')
|
||||
cdef GLenum error
|
||||
realGlGenTextures(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGenTextures' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef GLint glGetAttribLocationARB(GLhandleARB a0, GLchar * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetAttribLocationARB')
|
||||
cdef GLenum error
|
||||
cdef GLint rv = realGlGetAttribLocationARB(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetAttribLocationARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return rv
|
||||
|
||||
cdef int glGetIntegerv(GLenum a0, GLint * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetIntegerv')
|
||||
cdef GLenum error
|
||||
realGlGetIntegerv(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetIntegerv' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glGetProgramInfoLog(GLhandleARB a0, GLsizei a1, GLsizei * a2, GLchar * a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetProgramInfoLog')
|
||||
cdef GLenum error
|
||||
realGlGetProgramInfoLog(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetProgramInfoLog' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glGetProgramiv(GLuint a0, GLenum a1, GLint * a2) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetProgramiv')
|
||||
cdef GLenum error
|
||||
realGlGetProgramiv(a0, a1, a2)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetProgramiv' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glGetShaderInfoLog(GLhandleARB a0, GLsizei a1, GLsizei * a2, GLchar * a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetShaderInfoLog')
|
||||
cdef GLenum error
|
||||
realGlGetShaderInfoLog(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetShaderInfoLog' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glGetShaderiv(GLuint a0, GLenum a1, GLint * a2) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetShaderiv')
|
||||
cdef GLenum error
|
||||
realGlGetShaderiv(a0, a1, a2)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetShaderiv' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef GLchar * glGetString(GLenum a0) except? NULL:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetString')
|
||||
cdef GLenum error
|
||||
cdef GLchar * rv = realGlGetString(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetString' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return rv
|
||||
|
||||
cdef GLint glGetUniformLocationARB(GLhandleARB a0, GLchar * a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glGetUniformLocationARB')
|
||||
cdef GLenum error
|
||||
cdef GLint rv = realGlGetUniformLocationARB(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glGetUniformLocationARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return rv
|
||||
|
||||
cdef int glLinkProgramARB(GLhandleARB a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glLinkProgramARB')
|
||||
cdef GLenum error
|
||||
realGlLinkProgramARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glLinkProgramARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glReadPixels(GLint a0, GLint a1, GLsizei a2, GLsizei a3, GLenum a4, GLenum a5, GLubyte * a6) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glReadPixels')
|
||||
cdef GLenum error
|
||||
realGlReadPixels(a0, a1, a2, a3, a4, a5, a6)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glReadPixels' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glScissor(GLint a0, GLint a1, GLsizei a2, GLsizei a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glScissor')
|
||||
cdef GLenum error
|
||||
realGlScissor(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glScissor' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glShaderSourceARB(GLhandleARB a0, GLsizei a1, GLchar * * a2, GLint * a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glShaderSourceARB')
|
||||
cdef GLenum error
|
||||
realGlShaderSourceARB(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glShaderSourceARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glTexImage2D(GLenum a0, GLint a1, GLint a2, GLsizei a3, GLsizei a4, GLint a5, GLenum a6, GLenum a7, GLubyte * a8) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glTexImage2D')
|
||||
cdef GLenum error
|
||||
realGlTexImage2D(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glTexImage2D' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glTexParameteri(GLenum a0, GLenum a1, GLint a2) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glTexParameteri')
|
||||
cdef GLenum error
|
||||
realGlTexParameteri(a0, a1, a2)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glTexParameteri' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glTexSubImage2D(GLenum a0, GLint a1, GLint a2, GLint a3, GLsizei a4, GLsizei a5, GLenum a6, GLenum a7, GLubyte * a8) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glTexSubImage2D')
|
||||
cdef GLenum error
|
||||
realGlTexSubImage2D(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glTexSubImage2D' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glUniform1fARB(GLint a0, GLfloat a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glUniform1fARB')
|
||||
cdef GLenum error
|
||||
realGlUniform1fARB(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glUniform1fARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glUniform1iARB(GLint a0, GLint a1) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glUniform1iARB')
|
||||
cdef GLenum error
|
||||
realGlUniform1iARB(a0, a1)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glUniform1iARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glUniform2fARB(GLint a0, GLfloat a1, GLfloat a2) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glUniform2fARB')
|
||||
cdef GLenum error
|
||||
realGlUniform2fARB(a0, a1, a2)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glUniform2fARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glUniform4fARB(GLint a0, GLfloat a1, GLfloat a2, GLfloat a3, GLfloat a4) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glUniform4fARB')
|
||||
cdef GLenum error
|
||||
realGlUniform4fARB(a0, a1, a2, a3, a4)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glUniform4fARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glUniformMatrix4fvARB(GLint a0, GLsizei a1, GLboolean a2, GLfloat * a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glUniformMatrix4fvARB')
|
||||
cdef GLenum error
|
||||
realGlUniformMatrix4fvARB(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glUniformMatrix4fvARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glUseProgramObjectARB(GLhandleARB a0) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glUseProgramObjectARB')
|
||||
cdef GLenum error
|
||||
realGlUseProgramObjectARB(a0)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glUseProgramObjectARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glVertexAttribPointerARB(GLuint a0, GLint a1, GLenum a2, GLboolean a3, GLsizei a4, GLubyte * a5) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glVertexAttribPointerARB')
|
||||
cdef GLenum error
|
||||
realGlVertexAttribPointerARB(a0, a1, a2, a3, a4, a5)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glVertexAttribPointerARB' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
|
||||
cdef int glViewport(GLint a0, GLint a1, GLsizei a2, GLsizei a3) except? 0:
|
||||
if check_errors & 4:
|
||||
renpy.display.log.write('glViewport')
|
||||
cdef GLenum error
|
||||
realGlViewport(a0, a1, a2, a3)
|
||||
if check_errors:
|
||||
error = realGlGetError()
|
||||
if error:
|
||||
message = 'GL error %x in glViewport' % error
|
||||
if check_errors & 1:
|
||||
renpy.display.log.write('%s', message)
|
||||
if check_errors & 2:
|
||||
raise Exception(message)
|
||||
return 1
|
||||
@@ -1,7 +1,7 @@
|
||||
# This file was automatically generated from renpy/gl/glblacklist.py
|
||||
# Modifications will be automatically overwritten.
|
||||
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
+10
-4
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -878,6 +878,9 @@ class Image(Node):
|
||||
|
||||
renpy.exports.image(self.imgname, img)
|
||||
|
||||
def analyze(self):
|
||||
if getattr(self, 'atl', None) is not None:
|
||||
self.atl.mark_constant()
|
||||
|
||||
|
||||
class Transform(Node):
|
||||
@@ -1040,6 +1043,10 @@ class Show(Node):
|
||||
predict_imspec(self.imspec, atl=getattr(self, "atl", None))
|
||||
return [ self.next ]
|
||||
|
||||
def analyze(self):
|
||||
if getattr(self, 'atl', None) is not None:
|
||||
self.atl.mark_constant()
|
||||
|
||||
|
||||
class ShowLayer(Node):
|
||||
|
||||
@@ -1127,7 +1134,7 @@ class Scene(Node):
|
||||
return [ self.next ]
|
||||
|
||||
def analyze(self):
|
||||
if self.atl is not None:
|
||||
if getattr(self, 'atl', None) is not None:
|
||||
self.atl.mark_constant()
|
||||
|
||||
|
||||
@@ -1326,9 +1333,8 @@ class Return(Node):
|
||||
else:
|
||||
renpy.store._return = None
|
||||
|
||||
renpy.game.context().pop_dynamic()
|
||||
|
||||
next_node(renpy.game.context().lookup_return(pop=True))
|
||||
renpy.game.context().pop_dynamic()
|
||||
|
||||
def predict(self):
|
||||
|
||||
|
||||
+64
-23
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -227,6 +227,9 @@ class ATLTransformBase(renpy.object.Object):
|
||||
parent_transform = None
|
||||
atl_st_offset = 0
|
||||
|
||||
# The block, as first compiled for prediction.
|
||||
predict_block = None
|
||||
|
||||
nosave = [ 'parent_transform' ]
|
||||
|
||||
def __init__(self, atl, context, parameters):
|
||||
@@ -248,6 +251,10 @@ class ATLTransformBase(renpy.object.Object):
|
||||
# The code after it has been compiled into a block.
|
||||
self.block = None
|
||||
|
||||
# The same thing, but only if the code was compiled into a block
|
||||
# for prediction purposes only.
|
||||
self.predict_block = None
|
||||
|
||||
# The properties of the block, if it contains only an
|
||||
# Interpolation.
|
||||
self.properties = None
|
||||
@@ -281,6 +288,18 @@ class ATLTransformBase(renpy.object.Object):
|
||||
if renpy.game.context().init_phase:
|
||||
compile_queue.append(self)
|
||||
|
||||
def get_block(self):
|
||||
"""
|
||||
Returns the compiled block to use.
|
||||
"""
|
||||
|
||||
if self.block:
|
||||
return self.block
|
||||
elif self.predict_block and renpy.display.predict.predicting:
|
||||
return self.predict_block
|
||||
else:
|
||||
return None
|
||||
|
||||
def take_execution_state(self, t):
|
||||
"""
|
||||
Updates self to begin executing from the same point as t. This
|
||||
@@ -322,7 +341,6 @@ class ATLTransformBase(renpy.object.Object):
|
||||
self.child = t.child
|
||||
self.raw_child = t.raw_child
|
||||
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
|
||||
context = self.context.context.copy()
|
||||
@@ -409,20 +427,25 @@ class ATLTransformBase(renpy.object.Object):
|
||||
self.block = self.parent_transform.block
|
||||
self.properties = self.parent_transform.properties
|
||||
self.parent_transform = None
|
||||
return
|
||||
return self.block
|
||||
|
||||
old_exception_info = renpy.game.exception_info
|
||||
|
||||
self.block = self.atl.compile(self.context)
|
||||
block = self.atl.compile(self.context)
|
||||
|
||||
if len(self.block.statements) == 1 \
|
||||
and isinstance(self.block.statements[0], Interpolation):
|
||||
if len(block.statements) == 1 and isinstance(block.statements[0], Interpolation):
|
||||
|
||||
interp = self.block.statements[0]
|
||||
interp = block.statements[0]
|
||||
|
||||
if interp.duration == 0 and interp.properties:
|
||||
self.properties = interp.properties[:]
|
||||
|
||||
if not constant and renpy.display.predict.predicting:
|
||||
self.predict_block = block
|
||||
else:
|
||||
self.block = block
|
||||
self.predict_block = None
|
||||
|
||||
renpy.game.exception_info = old_exception_info
|
||||
|
||||
if constant and self.parent_transform:
|
||||
@@ -430,14 +453,17 @@ class ATLTransformBase(renpy.object.Object):
|
||||
self.parent_transform.properties = self.properties
|
||||
self.parent_transform = None
|
||||
|
||||
return block
|
||||
|
||||
|
||||
def execute(self, trans, st, at):
|
||||
|
||||
if self.done:
|
||||
return None
|
||||
|
||||
if not self.block:
|
||||
self.compile()
|
||||
block = self.get_block()
|
||||
if block is None:
|
||||
block = self.compile()
|
||||
|
||||
# Propagate transform_events from children.
|
||||
if self.child:
|
||||
@@ -469,11 +495,11 @@ class ATLTransformBase(renpy.object.Object):
|
||||
else:
|
||||
timebase = st - self.atl_st_offset
|
||||
|
||||
action, arg, pause = self.block.execute(trans, timebase, self.atl_state, event)
|
||||
action, arg, pause = block.execute(trans, timebase, self.atl_state, event)
|
||||
|
||||
renpy.game.exception_info = old_exception_info
|
||||
|
||||
if action == "continue":
|
||||
if action == "continue" and not renpy.display.predict.predicting:
|
||||
self.atl_state = arg
|
||||
else:
|
||||
self.done = True
|
||||
@@ -484,10 +510,12 @@ class ATLTransformBase(renpy.object.Object):
|
||||
self.atl.predict(self.context)
|
||||
|
||||
def visit(self):
|
||||
if not self.block:
|
||||
self.compile()
|
||||
block = self.get_block()
|
||||
|
||||
return self.children + self.block.visit()
|
||||
if block is None:
|
||||
block = self.compile()
|
||||
|
||||
return self.children + block.visit()
|
||||
|
||||
# This is used in mark_constant to analyze expressions for constness.
|
||||
is_constant_expr = renpy.pyanalysis.Analysis().is_constant_expr
|
||||
@@ -788,10 +816,11 @@ class RawMultipurpose(RawStatement):
|
||||
if isinstance(child, (int, float)):
|
||||
return Interpolation(self.loc, "pause", child, [ ], None, 0, [ ])
|
||||
|
||||
child = renpy.easy.displayable(child)
|
||||
|
||||
if isinstance(child, ATLTransformBase):
|
||||
child.compile()
|
||||
return child.block
|
||||
|
||||
return child.get_block()
|
||||
else:
|
||||
return Child(self.loc, child, transition)
|
||||
|
||||
@@ -905,7 +934,7 @@ class RawContainsExpr(RawStatement):
|
||||
self.constant = is_constant_expr(self.expression)
|
||||
|
||||
|
||||
# This allows us to have multiple children, inside a Fixed.
|
||||
# This allows us to have multiple ATL transforms as children.
|
||||
class RawChild(RawStatement):
|
||||
|
||||
def __init__(self, loc, child):
|
||||
@@ -915,12 +944,23 @@ class RawChild(RawStatement):
|
||||
self.children = [ child ]
|
||||
|
||||
def compile(self, ctx): #@ReservedAssignment
|
||||
box = renpy.display.layout.MultiBox(layout='fixed')
|
||||
|
||||
children = [ ]
|
||||
|
||||
for i in self.children:
|
||||
box.add(renpy.display.motion.ATLTransform(i, context=ctx.context))
|
||||
children.append(renpy.display.motion.ATLTransform(i, context=ctx.context))
|
||||
|
||||
return Child(self.loc, box, None)
|
||||
if len(children) != 1:
|
||||
|
||||
box = renpy.display.layout.MultiBox(layout='fixed')
|
||||
|
||||
for i in children:
|
||||
box.add(i)
|
||||
|
||||
return Child(self.loc, box, None)
|
||||
|
||||
else:
|
||||
return Child(self.loc, children[0], None)
|
||||
|
||||
def mark_constant(self):
|
||||
|
||||
@@ -940,7 +980,7 @@ class Child(Statement):
|
||||
|
||||
super(Child, self).__init__(loc)
|
||||
|
||||
self.child = renpy.easy.displayable(child)
|
||||
self.child = child
|
||||
self.transition = transition
|
||||
|
||||
def execute(self, trans, st, state, event):
|
||||
@@ -948,12 +988,13 @@ class Child(Statement):
|
||||
executing(self.loc)
|
||||
|
||||
old_child = trans.raw_child
|
||||
child = self.child.parameterize('displayable', [ ])
|
||||
|
||||
if (old_child is not None) and (old_child is not renpy.display.motion.null) and (self.transition is not None):
|
||||
child = self.transition(old_widget=old_child,
|
||||
new_widget=self.child)
|
||||
new_widget=child)
|
||||
else:
|
||||
child = self.child
|
||||
child = child
|
||||
|
||||
trans.set_child(child)
|
||||
trans.raw_child = self.child
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
import renpy
|
||||
import jnius # @UnresolvedImport
|
||||
|
||||
from renpy.audio.audio import MusicContext
|
||||
|
||||
VideoPlayer = jnius.autoclass("org.renpy.android.VideoPlayer")
|
||||
|
||||
class AndroidVideoChannel(object):
|
||||
|
||||
def __init__(self, name, file_prefix="", file_suffix="", default_loop=None):
|
||||
|
||||
# A list of queued filenames.
|
||||
self.queue = [ ]
|
||||
|
||||
# The filename that's currently playing.
|
||||
self.filename = None
|
||||
|
||||
# The videoplayer that's currently playing.
|
||||
self.player = None
|
||||
|
||||
# The name assigned to this channel. This is used to look up
|
||||
# information about the channel in the MusicContext object.
|
||||
self.name = name
|
||||
|
||||
# The name of the mixer this channel uses. Set below, as there's
|
||||
# no good default.
|
||||
self.mixer = None
|
||||
|
||||
# The time the music in this channel was last changed.
|
||||
self.last_changed = 0
|
||||
|
||||
# The callback that is called if the queue becomes empty.
|
||||
self.callback = None
|
||||
|
||||
# Ignored.
|
||||
self.synchro_start = False
|
||||
self.wait_stop = False
|
||||
self.loop = [ ]
|
||||
|
||||
# A prefix and suffix that are used to create the full filenames.
|
||||
self.file_prefix = file_prefix
|
||||
self.file_suffix = file_suffix
|
||||
|
||||
if default_loop is None:
|
||||
# By default, should we loop the music?
|
||||
self.default_loop = True
|
||||
# Was this set explicitly?
|
||||
self.default_loop_set = False
|
||||
|
||||
else:
|
||||
self.default_loop = default_loop
|
||||
self.default_loop_set = True
|
||||
|
||||
|
||||
def get_context(self):
|
||||
"""
|
||||
Returns the MusicContext corresponding to this channel, taken from
|
||||
the context object. Allocates a MusicContext if none exists.
|
||||
"""
|
||||
|
||||
mcd = renpy.game.context().music
|
||||
|
||||
rv = mcd.get(self.name)
|
||||
if rv is None:
|
||||
rv = mcd[self.name] = MusicContext()
|
||||
|
||||
return rv
|
||||
|
||||
context = property(get_context)
|
||||
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Starts playing the first video in the queue.
|
||||
"""
|
||||
|
||||
if not self.queue:
|
||||
return
|
||||
|
||||
filename = self.queue.pop(0)
|
||||
|
||||
print "Playing", filename
|
||||
|
||||
f = renpy.loader.load(filename)
|
||||
|
||||
real_fn = f.name
|
||||
base = getattr(f, "base", -1)
|
||||
length = getattr(f, "length", -1)
|
||||
|
||||
self.filename = filename
|
||||
self.player = VideoPlayer(real_fn, base, length)
|
||||
|
||||
def stop(self):
|
||||
|
||||
if self.player is not None:
|
||||
self.player.stop()
|
||||
self.player = None
|
||||
|
||||
self.filename = None
|
||||
|
||||
def get_playing(self):
|
||||
|
||||
if self.player is None:
|
||||
return None
|
||||
|
||||
if self.player.isPlaying():
|
||||
return self.filename
|
||||
|
||||
def periodic(self):
|
||||
|
||||
# This should be set from something that checks to see if our
|
||||
# mixer is muted.
|
||||
force_stop = self.context.force_stop
|
||||
|
||||
if force_stop:
|
||||
self.dequeue()
|
||||
self.stop()
|
||||
return
|
||||
|
||||
if self.get_playing():
|
||||
return
|
||||
|
||||
if self.queue:
|
||||
self.start()
|
||||
|
||||
|
||||
def dequeue(self, even_tight=False):
|
||||
"""
|
||||
Clears the queued music, except for a first item that has
|
||||
not been started.
|
||||
"""
|
||||
|
||||
if self.get_playing():
|
||||
self.queue = [ ]
|
||||
else:
|
||||
self.queue = self.queue[:1]
|
||||
|
||||
|
||||
def interact(self):
|
||||
"""
|
||||
Called (mostly) once per interaction.
|
||||
"""
|
||||
|
||||
self.periodic()
|
||||
|
||||
|
||||
def fadeout(self, secs):
|
||||
"""
|
||||
Causes the playing music to be faded out for the given number
|
||||
of seconds. Also clears any queued music.
|
||||
"""
|
||||
|
||||
self.stop()
|
||||
self.queue = [ ]
|
||||
|
||||
def enqueue(self, filenames, loop=True, synchro_start=False, fadein=0, tight=None):
|
||||
self.queue.extend(filenames)
|
||||
|
||||
def set_volume(self, volume):
|
||||
pass
|
||||
|
||||
def get_pos(self):
|
||||
pass
|
||||
|
||||
def set_pan(self, pan, delay):
|
||||
pass
|
||||
|
||||
def set_secondary_volume(self, volume, delay):
|
||||
pass
|
||||
|
||||
def pause(self):
|
||||
if self.player is not None:
|
||||
self.player.pause()
|
||||
|
||||
def unpause(self):
|
||||
if self.player is not None:
|
||||
self.player.unpause()
|
||||
+41
-179
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -28,7 +28,7 @@ import renpy.audio # @UnusedImport
|
||||
import renpy.display # @UnusedImport
|
||||
|
||||
import time
|
||||
import pygame # @UnusedImport
|
||||
import pygame_sdl2 # @UnusedImport
|
||||
import os
|
||||
import atexit
|
||||
|
||||
@@ -36,23 +36,16 @@ import atexit
|
||||
|
||||
disable = os.environ.get("RENPY_DISABLE_SOUND", "")
|
||||
|
||||
pss = None
|
||||
|
||||
if 'pss' not in disable:
|
||||
|
||||
try:
|
||||
import pysdlsound as pss
|
||||
pss.check_version(4) # @UndefinedVariable
|
||||
atexit.register(pss.quit) # @UndefinedVariable
|
||||
except:
|
||||
pass
|
||||
|
||||
if pss is None:
|
||||
try:
|
||||
import android.sound as pss #@UnresolvedImport @Reimport
|
||||
print "Imported android.sound."
|
||||
except:
|
||||
pass
|
||||
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
pss = None
|
||||
|
||||
# Save the mixer, and restore it at exit.
|
||||
|
||||
@@ -511,178 +504,29 @@ class Channel(object):
|
||||
self.secondary_volume_time = self.context.secondary_volume_time
|
||||
pss.set_secondary_volume(self.number, self.context.secondary_volume, delay)
|
||||
|
||||
def pause(self):
|
||||
pss.pause(self.number)
|
||||
|
||||
def unpause(self):
|
||||
pss.unpause(self.number)
|
||||
|
||||
|
||||
################################################################################
|
||||
# Android VideoPlayer Channel
|
||||
################################################################################
|
||||
|
||||
if renpy.android:
|
||||
# Use unconditional imports so these files get compiled during the build
|
||||
# process.
|
||||
|
||||
import jnius # @UnresolvedImport
|
||||
|
||||
VideoPlayer = jnius.autoclass("org.renpy.android.VideoPlayer")
|
||||
|
||||
class AndroidVideoChannel(object):
|
||||
|
||||
def __init__(self, name, file_prefix="", file_suffix="", default_loop=None):
|
||||
|
||||
# A list of queued filenames.
|
||||
self.queue = [ ]
|
||||
|
||||
# The filename that's currently playing.
|
||||
self.filename = None
|
||||
|
||||
# The videoplayer that's currently playing.
|
||||
self.player = None
|
||||
|
||||
# The name assigned to this channel. This is used to look up
|
||||
# information about the channel in the MusicContext object.
|
||||
self.name = name
|
||||
|
||||
# The name of the mixer this channel uses. Set below, as there's
|
||||
# no good default.
|
||||
self.mixer = None
|
||||
|
||||
# The time the music in this channel was last changed.
|
||||
self.last_changed = 0
|
||||
|
||||
# The callback that is called if the queue becomes empty.
|
||||
self.callback = None
|
||||
|
||||
# Ignored.
|
||||
self.synchro_start = False
|
||||
self.wait_stop = False
|
||||
self.loop = [ ]
|
||||
|
||||
# A prefix and suffix that are used to create the full filenames.
|
||||
self.file_prefix = file_prefix
|
||||
self.file_suffix = file_suffix
|
||||
|
||||
if default_loop is None:
|
||||
# By default, should we loop the music?
|
||||
self.default_loop = True
|
||||
# Was this set explicitly?
|
||||
self.default_loop_set = False
|
||||
|
||||
else:
|
||||
self.default_loop = default_loop
|
||||
self.default_loop_set = True
|
||||
|
||||
|
||||
def get_context(self):
|
||||
"""
|
||||
Returns the MusicContext corresponding to this channel, taken from
|
||||
the context object. Allocates a MusicContext if none exists.
|
||||
"""
|
||||
|
||||
mcd = renpy.game.context().music
|
||||
|
||||
rv = mcd.get(self.name)
|
||||
if rv is None:
|
||||
rv = mcd[self.name] = MusicContext()
|
||||
|
||||
return rv
|
||||
|
||||
context = property(get_context)
|
||||
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Starts playing the first video in the queue.
|
||||
"""
|
||||
|
||||
if not self.queue:
|
||||
return
|
||||
|
||||
filename = self.queue.pop(0)
|
||||
|
||||
f = renpy.loader.load(filename)
|
||||
|
||||
real_fn = f.name
|
||||
base = getattr(f, "base", -1)
|
||||
length = getattr(f, "length", -1)
|
||||
|
||||
self.filename = filename
|
||||
self.player = VideoPlayer(real_fn, base, length)
|
||||
|
||||
def stop(self):
|
||||
|
||||
if self.player is not None:
|
||||
self.player.stop()
|
||||
self.player = None
|
||||
|
||||
self.filename = None
|
||||
|
||||
def get_playing(self):
|
||||
|
||||
if self.player is None:
|
||||
return None
|
||||
|
||||
if self.player.isPlaying():
|
||||
return self.filename
|
||||
|
||||
def periodic(self):
|
||||
|
||||
# This should be set from something that checks to see if our
|
||||
# mixer is muted.
|
||||
force_stop = self.context.force_stop
|
||||
|
||||
if force_stop:
|
||||
self.dequeue()
|
||||
self.stop()
|
||||
return
|
||||
|
||||
if self.get_playing():
|
||||
return
|
||||
|
||||
if self.queue:
|
||||
self.start()
|
||||
|
||||
|
||||
def dequeue(self, even_tight=False):
|
||||
"""
|
||||
Clears the queued music, except for a first item that has
|
||||
not been started.
|
||||
"""
|
||||
|
||||
if self.get_playing():
|
||||
self.queue = [ ]
|
||||
else:
|
||||
self.queue = self.queue[:1]
|
||||
|
||||
|
||||
def interact(self):
|
||||
"""
|
||||
Called (mostly) once per interaction.
|
||||
"""
|
||||
|
||||
self.periodic()
|
||||
|
||||
|
||||
def fadeout(self, secs):
|
||||
"""
|
||||
Causes the playing music to be faded out for the given number
|
||||
of seconds. Also clears any queued music.
|
||||
"""
|
||||
|
||||
self.stop()
|
||||
self.queue = [ ]
|
||||
|
||||
def enqueue(self, filenames, loop=True, synchro_start=False, fadein=0, tight=None):
|
||||
self.queue.extend(filenames)
|
||||
|
||||
def set_volume(self, volume):
|
||||
pass
|
||||
|
||||
def get_pos(self):
|
||||
pass
|
||||
|
||||
def set_pan(self, pan, delay):
|
||||
pass
|
||||
|
||||
def set_secondary_volume(self, volume, delay):
|
||||
pass
|
||||
try:
|
||||
from renpy.audio.androidhw import AndroidVideoChannel
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
from renpy.audio.ioshw import IOSVideoChannel
|
||||
except:
|
||||
pass
|
||||
|
||||
# A list of channels we know about.
|
||||
all_channels = [ ]
|
||||
@@ -732,8 +576,10 @@ def register_channel(name, mixer=None, loop=None, stop_on_mute=True, tight=False
|
||||
if not renpy.game.context().init_phase:
|
||||
raise Exception("Can't register channel outside of init phase.")
|
||||
|
||||
if renpy.android and name == "movie":
|
||||
if renpy.android and renpy.config.hw_video and name == "movie":
|
||||
c = AndroidVideoChannel(name, default_loop=loop, file_prefix=file_prefix, file_suffix=file_suffix)
|
||||
elif renpy.ios and renpy.config.hw_video and name == "movie":
|
||||
c = IOSVideoChannel(name, default_loop=loop, file_prefix=file_prefix, file_suffix=file_suffix)
|
||||
else:
|
||||
c = Channel(name, loop, stop_on_mute, tight, file_prefix, file_suffix, buffer_queue)
|
||||
|
||||
@@ -953,3 +799,19 @@ def rollback():
|
||||
for c in all_channels:
|
||||
if not c.loop:
|
||||
c.fadeout(0)
|
||||
|
||||
def pause_all():
|
||||
"""
|
||||
Pause all playback channels.
|
||||
"""
|
||||
|
||||
for c in channels.values():
|
||||
c.pause()
|
||||
|
||||
def unpause_all():
|
||||
"""
|
||||
Unpause all playback channels.
|
||||
"""
|
||||
|
||||
for c in channels.values():
|
||||
c.unpause()
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
import renpy
|
||||
import pyobjus # @UnresolvedImport
|
||||
|
||||
from renpy.audio.audio import MusicContext
|
||||
|
||||
VideoPlayer = pyobjus.autoclass("VideoPlayer")
|
||||
|
||||
class IOSVideoChannel(object):
|
||||
|
||||
def __init__(self, name, file_prefix="", file_suffix="", default_loop=None):
|
||||
|
||||
# A list of queued filenames.
|
||||
self.queue = [ ]
|
||||
|
||||
# The filename that's currently playing.
|
||||
self.filename = None
|
||||
|
||||
# The videoplayer that's currently playing.
|
||||
self.player = None
|
||||
|
||||
# The name assigned to this channel. This is used to look up
|
||||
# information about the channel in the MusicContext object.
|
||||
self.name = name
|
||||
|
||||
# The name of the mixer this channel uses. Set below, as there's
|
||||
# no good default.
|
||||
self.mixer = None
|
||||
|
||||
# The time the music in this channel was last changed.
|
||||
self.last_changed = 0
|
||||
|
||||
# The callback that is called if the queue becomes empty.
|
||||
self.callback = None
|
||||
|
||||
# Ignored.
|
||||
self.synchro_start = False
|
||||
self.wait_stop = False
|
||||
self.loop = [ ]
|
||||
|
||||
# A prefix and suffix that are used to create the full filenames.
|
||||
self.file_prefix = file_prefix
|
||||
self.file_suffix = file_suffix
|
||||
|
||||
if default_loop is None:
|
||||
# By default, should we loop the music?
|
||||
self.default_loop = True
|
||||
# Was this set explicitly?
|
||||
self.default_loop_set = False
|
||||
|
||||
else:
|
||||
self.default_loop = default_loop
|
||||
self.default_loop_set = True
|
||||
|
||||
|
||||
def get_context(self):
|
||||
"""
|
||||
Returns the MusicContext corresponding to this channel, taken from
|
||||
the context object. Allocates a MusicContext if none exists.
|
||||
"""
|
||||
|
||||
mcd = renpy.game.context().music
|
||||
|
||||
rv = mcd.get(self.name)
|
||||
if rv is None:
|
||||
rv = mcd[self.name] = MusicContext()
|
||||
|
||||
return rv
|
||||
|
||||
context = property(get_context)
|
||||
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Starts playing the first video in the queue.
|
||||
"""
|
||||
|
||||
if not self.queue:
|
||||
return
|
||||
|
||||
filename = self.queue.pop(0)
|
||||
f = renpy.loader.load(filename)
|
||||
|
||||
real_fn = f.name
|
||||
|
||||
self.filename = filename
|
||||
self.player = VideoPlayer.alloc().initWithFile_(real_fn)
|
||||
|
||||
def stop(self):
|
||||
|
||||
if self.player is not None:
|
||||
self.player.stop()
|
||||
self.player = None
|
||||
|
||||
self.filename = None
|
||||
|
||||
def get_playing(self):
|
||||
|
||||
if self.player is None:
|
||||
return None
|
||||
|
||||
if self.player.isPlaying():
|
||||
return self.filename
|
||||
|
||||
def periodic(self):
|
||||
|
||||
# This should be set from something that checks to see if our
|
||||
# mixer is muted.
|
||||
force_stop = self.context.force_stop
|
||||
|
||||
if force_stop:
|
||||
self.dequeue()
|
||||
self.stop()
|
||||
return
|
||||
|
||||
if self.get_playing():
|
||||
return
|
||||
|
||||
if self.queue:
|
||||
self.start()
|
||||
|
||||
|
||||
def dequeue(self, even_tight=False):
|
||||
"""
|
||||
Clears the queued music, except for a first item that has
|
||||
not been started.
|
||||
"""
|
||||
|
||||
if self.get_playing():
|
||||
self.queue = [ ]
|
||||
else:
|
||||
self.queue = self.queue[:1]
|
||||
|
||||
|
||||
def interact(self):
|
||||
"""
|
||||
Called (mostly) once per interaction.
|
||||
"""
|
||||
|
||||
self.periodic()
|
||||
|
||||
|
||||
def fadeout(self, secs):
|
||||
"""
|
||||
Causes the playing music to be faded out for the given number
|
||||
of seconds. Also clears any queued music.
|
||||
"""
|
||||
|
||||
self.stop()
|
||||
self.queue = [ ]
|
||||
|
||||
def enqueue(self, filenames, loop=True, synchro_start=False, fadein=0, tight=None):
|
||||
self.queue.extend(filenames)
|
||||
|
||||
def pause(self):
|
||||
if self.player is not None:
|
||||
self.player.pause()
|
||||
pass
|
||||
|
||||
def unpause(self):
|
||||
if self.player is not None:
|
||||
self.player.unpause()
|
||||
pass
|
||||
|
||||
def set_volume(self, volume):
|
||||
pass
|
||||
|
||||
def get_pos(self):
|
||||
pass
|
||||
|
||||
def set_pan(self, pan, delay):
|
||||
pass
|
||||
|
||||
def set_secondary_volume(self, volume, delay):
|
||||
pass
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
+13
-14
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -57,9 +57,6 @@ def extra_imports():
|
||||
import tarfile; tarfile
|
||||
import bz2; bz2 # @UnresolvedImport
|
||||
import webbrowser; webbrowser
|
||||
import pygame.locals; pygame.locals
|
||||
import pygame.color; pygame.color
|
||||
import pygame.colordict; pygame.colordict
|
||||
import posixpath; posixpath
|
||||
import ctypes; ctypes
|
||||
import ctypes.wintypes; ctypes.wintypes
|
||||
@@ -74,6 +71,7 @@ def extra_imports():
|
||||
import rsa; rsa
|
||||
import decimal; decimal
|
||||
import plistlib; plistlib
|
||||
import _renpysteam; _renpysteam
|
||||
|
||||
class NullFile(io.IOBase):
|
||||
"""
|
||||
@@ -135,6 +133,10 @@ def bootstrap(renpy_base):
|
||||
|
||||
os.environ["RENPY_BASE"] = os.path.abspath(renpy_base)
|
||||
|
||||
# Remove a legacy environment setting.
|
||||
if os.environ.get("SDL_VIDEODRIVER", "") == "windib":
|
||||
del os.environ["SDL_VIDEODRIVER"]
|
||||
|
||||
renpy_base = unicode(renpy_base, FSENCODING, "replace")
|
||||
|
||||
# If environment.txt exists, load it into the os.environ dictionary.
|
||||
@@ -212,10 +214,6 @@ def bootstrap(renpy_base):
|
||||
|
||||
sys.path.insert(0, basedir)
|
||||
|
||||
# Force windib on windows, unless the user explicitly overrides.
|
||||
if renpy.windows and not 'SDL_VIDEODRIVER' in os.environ:
|
||||
os.environ['SDL_VIDEODRIVER'] = 'windib'
|
||||
|
||||
# If we're not given a command, show the presplash.
|
||||
if args.command == "run":
|
||||
import renpy.display.presplash #@Reimport
|
||||
@@ -225,19 +223,17 @@ def bootstrap(renpy_base):
|
||||
if renpy.macintosh:
|
||||
os.startfile = mac_start
|
||||
|
||||
import pygame_sdl2
|
||||
pygame_sdl2.import_as_pygame()
|
||||
|
||||
# Check that we have installed pygame properly. This also deals with
|
||||
# weird cases on Windows and Linux where we can't import modules. (On
|
||||
# windows ";" is a directory separator in PATH, so if it's in a parent
|
||||
# directory, we won't get the libraries in the PATH, and hence pygame
|
||||
# won't import.)
|
||||
try:
|
||||
import pygame; pygame
|
||||
import pygame_sdl2
|
||||
pygame_sdl2.import_as_pygame()
|
||||
except:
|
||||
print >>sys.stderr, """\
|
||||
Could not import pygame. Please ensure that this program has been built
|
||||
Could not import pygame_sdl2. Please ensure that this program has been built
|
||||
and unpacked properly. Also, make sure that the directories containing
|
||||
this program do not contain : or ; in their names.
|
||||
|
||||
@@ -306,7 +302,10 @@ You may be using a system install of python. Please run {0}.sh,
|
||||
exit_status = e.status
|
||||
|
||||
if e.relaunch:
|
||||
subprocess.Popen([sys.executable, "-EO"] + sys.argv)
|
||||
if hasattr(sys, "renpy_executable"):
|
||||
subprocess.Popen([sys.renpy_executable] + sys.argv[1:])
|
||||
else:
|
||||
subprocess.Popen([sys.executable, "-EO"] + sys.argv)
|
||||
|
||||
except renpy.game.ParseErrorException:
|
||||
pass
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -45,11 +45,7 @@ init -1200 python:
|
||||
if _preferences.show_empty_window:
|
||||
renpy.with_statement(None)
|
||||
store._window = True
|
||||
try:
|
||||
_voice.ignore_interaction = True
|
||||
renpy.with_statement(trans)
|
||||
finally:
|
||||
_voice.ignore_interaction = False
|
||||
renpy.with_statement(trans)
|
||||
else:
|
||||
store._window = True
|
||||
|
||||
@@ -63,11 +59,7 @@ init -1200 python:
|
||||
if _preferences.show_empty_window:
|
||||
renpy.with_statement(None)
|
||||
store._window = False
|
||||
try:
|
||||
_voice.ignore_interaction = True
|
||||
renpy.with_statement(trans)
|
||||
finally:
|
||||
_voice.ignore_interaction = False
|
||||
renpy.with_statement(trans)
|
||||
else:
|
||||
store._window = False
|
||||
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
init -1500 python in achievement:
|
||||
from store import persistent, renpy
|
||||
|
||||
|
||||
# A list of backends that have been registered.
|
||||
backends = [ ]
|
||||
|
||||
|
||||
class Backend(object):
|
||||
"""
|
||||
Achievement backends should inherit from this class, so new methods
|
||||
will be ignored.
|
||||
"""
|
||||
|
||||
|
||||
def register(self, name, **kwargs):
|
||||
"""
|
||||
Called to register a new achievement.
|
||||
"""
|
||||
|
||||
def grant(self, name):
|
||||
"""
|
||||
Grants the achievement with `name`, if it has not already been
|
||||
granted.
|
||||
"""
|
||||
|
||||
def clear(self, name):
|
||||
"""
|
||||
Clears the achievement with `name`, if it has been granted.
|
||||
"""
|
||||
|
||||
def clear_all(self):
|
||||
"""
|
||||
Clears all achievements.
|
||||
"""
|
||||
|
||||
def progress(self, name, complete, total):
|
||||
"""
|
||||
Reports progress towards the achievement with `name`.
|
||||
"""
|
||||
|
||||
def has(self, name):
|
||||
"""
|
||||
Returns true if the achievement with `name` is unlocked.
|
||||
"""
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class PersistentBackend(Backend):
|
||||
"""
|
||||
A backend that stores achievements in persistent._achievements.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
if persistent._achievements is None:
|
||||
persistent._achievements = _set()
|
||||
|
||||
|
||||
def grant(self, name):
|
||||
persistent._achievements.add(name)
|
||||
|
||||
def clear(self, name):
|
||||
persistent._achievements.discard(name)
|
||||
|
||||
def clear_all(self):
|
||||
persistent._achievements.clear()
|
||||
|
||||
def has(self, name):
|
||||
return name in persistent._achievements
|
||||
|
||||
def merge(old, new, current):
|
||||
return old | new
|
||||
|
||||
renpy.register_persistent("_achievements", merge)
|
||||
|
||||
backends.append(PersistentBackend())
|
||||
|
||||
|
||||
class SteamBackend(Backend):
|
||||
"""
|
||||
A backend that sends achievements to Steam. This is only used if steam
|
||||
has loaded and initialized successfully.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# A map from achievement name to steam name.
|
||||
self.names = { }
|
||||
|
||||
steam.retrieve_stats(self.got_stats)
|
||||
|
||||
def got_stats(self):
|
||||
renpy.restart_interaction()
|
||||
|
||||
def register(self, name, steam=None, **kwargs):
|
||||
if steam is not None:
|
||||
self.names[name] = steam
|
||||
|
||||
def grant(self, name):
|
||||
name = self.names.get(name, name)
|
||||
|
||||
steam.grant_achievement(name)
|
||||
steam.store_stats()
|
||||
|
||||
def clear(self, name):
|
||||
name = self.names.get(name, name)
|
||||
|
||||
steam.clear_achievement(name)
|
||||
steam.store_stats()
|
||||
|
||||
def clear_all(self):
|
||||
for i in steam.list_achievements():
|
||||
steam.clear_achievement(i)
|
||||
|
||||
steam.store_stats()
|
||||
|
||||
def progress(self, name, completed, total):
|
||||
name = self.names.get(name, name)
|
||||
|
||||
steam.indicate_achievement_progress(name, completed, total)
|
||||
steam.store_stats()
|
||||
|
||||
def has(self, name):
|
||||
name = self.names.get(name, name)
|
||||
|
||||
return steam.get_achievement(name)
|
||||
|
||||
try:
|
||||
import _renpysteam as steam
|
||||
|
||||
if steam.init():
|
||||
backends.append(SteamBackend())
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def register(name, **kwargs):
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
Registers an achievement. Achievements are not required to be
|
||||
registered, but doing so allows one to pass information to the
|
||||
backends.
|
||||
|
||||
`name`
|
||||
The name of the achievement to register.
|
||||
|
||||
The following keyword parameters are optional.
|
||||
|
||||
`steam`
|
||||
The name to use on steam. If not given, defaults to `name`.
|
||||
"""
|
||||
|
||||
for i in backends:
|
||||
i.register(name, **kwargs)
|
||||
|
||||
def grant(name):
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
Grants the achievement with `name`, if it has not already been
|
||||
granted.
|
||||
"""
|
||||
|
||||
if not has(name):
|
||||
for i in backends:
|
||||
i.grant(name)
|
||||
|
||||
def clear(name):
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
Clears the achievement with `name`.
|
||||
"""
|
||||
|
||||
if has(name):
|
||||
for i in backends:
|
||||
i.clear(name)
|
||||
|
||||
def clear_all():
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
Clears all achievements.
|
||||
"""
|
||||
|
||||
for i in backends:
|
||||
i.clear_all()
|
||||
|
||||
def progress(name, complete, total):
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
Reports progress towards the achievement with `name`, if that
|
||||
achievement has not been granted.
|
||||
|
||||
`complete`
|
||||
An integer giving the number of units completed towards the
|
||||
achievement.
|
||||
|
||||
`total`
|
||||
An integer giving the total number of units required to consider
|
||||
the achievement complete.
|
||||
"""
|
||||
|
||||
if has(name):
|
||||
return
|
||||
|
||||
for i in backends:
|
||||
i.progress(name, complete, total)
|
||||
|
||||
def grant_progress(name, complete, total):
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
If `complete` is less than `total`, reports progress towards the
|
||||
achievement with `name`, if that achievement has not been
|
||||
granted.
|
||||
|
||||
Otherwise, grants the achievement with `name`, if that achievement
|
||||
has not been granted.
|
||||
"""
|
||||
|
||||
if complete < total:
|
||||
progress(name, complete, total)
|
||||
else:
|
||||
grant(name)
|
||||
|
||||
def has(name):
|
||||
"""
|
||||
:doc: achievement
|
||||
|
||||
Returne true if the plater has been grnted the achievement with
|
||||
`name`.
|
||||
"""
|
||||
|
||||
for i in backends:
|
||||
if i.has(name):
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -121,7 +121,7 @@ init -1500 python:
|
||||
the current interaction completes.
|
||||
"""
|
||||
|
||||
return Show(screen, _transient=True, *args, **kwargs)
|
||||
return Show(screen, None, _transient=True, *args, **kwargs)
|
||||
|
||||
@renpy.pure
|
||||
class Hide(Action, DictEquality):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -94,7 +94,8 @@ init -1600 python:
|
||||
be set to `value`.
|
||||
"""
|
||||
|
||||
identity_fields = [ "name", "value" ]
|
||||
identity_fields = [ "value" ]
|
||||
equality_fields = [ "name" ]
|
||||
|
||||
def __init__(self, name, value):
|
||||
self.name = name
|
||||
@@ -253,7 +254,8 @@ init -1600 python:
|
||||
If not None, then this is the false value we use.
|
||||
"""
|
||||
|
||||
identity_fields = [ "name", "true_value", "false_value" ]
|
||||
identity_fields = [ "true_value", "false_value" ]
|
||||
equality_fields = [ "name" ]
|
||||
|
||||
def __init__(self, name, true_value=None, false_value=None):
|
||||
self.name = name
|
||||
@@ -298,3 +300,100 @@ init -1600 python:
|
||||
|
||||
|
||||
return rv
|
||||
|
||||
@renpy.pure
|
||||
class AddToSet(Action, FieldEquality):
|
||||
"""
|
||||
:data: data_action
|
||||
|
||||
Adds `value` to `set`.
|
||||
|
||||
`set`
|
||||
The set to add to. This may be a python set or list, in which
|
||||
case the value is appended to the list.
|
||||
`value`
|
||||
The value to add or append.
|
||||
"""
|
||||
|
||||
identity_fields = [ 'set', 'value' ]
|
||||
|
||||
def __init__(self, set, value):
|
||||
self.set = set
|
||||
self.value = value
|
||||
|
||||
def get_sensitive(self):
|
||||
return self.value not in self.set
|
||||
|
||||
def __call__(self):
|
||||
if isinstance(self.set, list):
|
||||
self.set.append(self.value)
|
||||
else:
|
||||
self.set.add(self.value)
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
@renpy.pure
|
||||
class RemoveFromSet(Action, FieldEquality):
|
||||
"""
|
||||
:data: data_action
|
||||
|
||||
Removes `value` from `set`.
|
||||
|
||||
`set`
|
||||
The set to remove from. This may be a set or list.
|
||||
`value`
|
||||
The value to add or append.
|
||||
"""
|
||||
|
||||
identity_fields = [ 'set', 'value' ]
|
||||
|
||||
def __init__(self, set, value):
|
||||
self.set = set
|
||||
self.value = value
|
||||
|
||||
def get_sensitive(self):
|
||||
return self.value in self.set
|
||||
|
||||
def __call__(self):
|
||||
if self.value in self.set:
|
||||
self.set.remove(self.value)
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
@renpy.pure
|
||||
class ToggleSetMembership(Action, FieldEquality):
|
||||
"""
|
||||
:data: data_action
|
||||
|
||||
Toggles the membership of `value` in `set`. If the value is not
|
||||
in the set, it's added. Otherwise, it is removed.
|
||||
|
||||
Buttons with this action are marked as selected if and only if the
|
||||
value is in the set.
|
||||
|
||||
`set`
|
||||
The set to add to or remove from. This may be a set or list. In the
|
||||
case of a list, new items are appended.
|
||||
`value`
|
||||
The value to add or append.
|
||||
"""
|
||||
|
||||
identity_fields = [ 'set', 'value' ]
|
||||
|
||||
def __init__(self, set, value):
|
||||
self.set = set
|
||||
self.value = value
|
||||
|
||||
def get_selected(self):
|
||||
return self.value in self.set
|
||||
|
||||
def __call__(self):
|
||||
if self.value in self.set:
|
||||
self.set.remove(self.value)
|
||||
else:
|
||||
if isinstance(self.set, list):
|
||||
self.set.append(self.value)
|
||||
else:
|
||||
self.set.add(self.value)
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -342,7 +342,7 @@ init -1500 python:
|
||||
|
||||
def get_sensitive(self):
|
||||
if self.locked is not None:
|
||||
return self.locked
|
||||
return not self.locked
|
||||
|
||||
return renpy.seen_label(self.label)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -96,7 +96,6 @@ init -1500 python in build:
|
||||
( "renpy.sh", "linux mac"),
|
||||
])
|
||||
|
||||
|
||||
def classify_renpy(pattern, groups):
|
||||
"""
|
||||
Classifies files in the Ren'Py base directory according to pattern.
|
||||
@@ -141,11 +140,12 @@ init -1500 python in build:
|
||||
|
||||
(".android.json", "android"),
|
||||
("android-icon.png", "android"),
|
||||
("android-presplash.jpg", "android"),
|
||||
("android-presplash.*", "android"),
|
||||
("android-*-icon.png", "android"),
|
||||
("android-*-presplash.jpg", "android"),
|
||||
("ouya-icon.png", "android"),
|
||||
("android-*-presplash.*", "android"),
|
||||
("ouya_icon.png", "android"),
|
||||
|
||||
("ios-presplash.*", "ios"),
|
||||
])
|
||||
|
||||
base_patterns = [ ]
|
||||
@@ -308,6 +308,7 @@ init -1500 python in build:
|
||||
package("mac", "app-zip", "mac renpy all", "Macintosh x86")
|
||||
package("win", "zip", "windows renpy all", "Windows x86")
|
||||
package("android", "directory", "android renpy all", hidden=True, update=False, dlc=True)
|
||||
package("ios", "directory", "ios renpy all", hidden=True, update=False, dlc=True)
|
||||
|
||||
# Data that we expect the user to set.
|
||||
|
||||
@@ -341,9 +342,14 @@ init -1500 python in build:
|
||||
# The destination things are built in.
|
||||
destination = "{directory_name}-dists"
|
||||
|
||||
# Should we allow the use of an integrated GPU on platforms that support
|
||||
# both discrete and integrated GPUs?
|
||||
allow_integrated_gpu = True
|
||||
|
||||
# This function is called by the json_dump command to dump the build data
|
||||
# into the json file.
|
||||
def dump():
|
||||
|
||||
rv = { }
|
||||
|
||||
rv["directory_name"] = directory_name
|
||||
@@ -361,8 +367,11 @@ init -1500 python in build:
|
||||
|
||||
rv["exclude_empty_directories"] = exclude_empty_directories
|
||||
|
||||
rv["allow_integrated_gpu"] = allow_integrated_gpu
|
||||
|
||||
rv["renpy"] = renpy
|
||||
|
||||
|
||||
rv["destination"] = destination.format(
|
||||
directory_name=directory_name,
|
||||
executable_name=executable_name,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -290,8 +290,8 @@ init -1500 python:
|
||||
if not _preferences.performance_test and "RENPY_PERFORMANCE_TEST" not in os.environ:
|
||||
return
|
||||
|
||||
# Don't bother on androuid - there's nothing the user can do.
|
||||
if renpy.renpy.android:
|
||||
# Don't bother on android or ios - there's nothing the user can do.
|
||||
if renpy.mobile:
|
||||
return
|
||||
|
||||
renpy.renpy.display.log.write("Performance test:")
|
||||
|
||||
+208
-33
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -31,11 +31,16 @@ init -1500 python in iap:
|
||||
A data object representing a product.
|
||||
"""
|
||||
|
||||
def __init__(self, product, identifier, google, amazon):
|
||||
def __init__(self, product, identifier, google, amazon, ios):
|
||||
self.product = product
|
||||
self.identifier = identifier
|
||||
self.google = google
|
||||
self.amazon = amazon
|
||||
self.ios = ios
|
||||
|
||||
# None if the item is not purchasable. Otherwise, a string that
|
||||
# gives the price in the local language.
|
||||
self.price = None
|
||||
|
||||
class NoneBackend(object):
|
||||
"""
|
||||
@@ -74,15 +79,35 @@ init -1500 python in iap:
|
||||
|
||||
return False
|
||||
|
||||
def is_deferred(self, p):
|
||||
"""
|
||||
Returns True if the purchase of `p` has been deferred, and False otherwise.
|
||||
"""
|
||||
|
||||
return False
|
||||
|
||||
def get_price(self, p):
|
||||
"""
|
||||
Returns the price of the item, or None if the item is not
|
||||
purchasable.
|
||||
"""
|
||||
|
||||
return None
|
||||
|
||||
class AndroidBackend(object):
|
||||
"""
|
||||
The IAP backend that is used when IAP is supported.
|
||||
"""
|
||||
|
||||
def __init__(self, devicePurchase, store_name):
|
||||
self.devicePurchase = devicePurchase
|
||||
def __init__(self, store, store_name):
|
||||
self.store = store
|
||||
self.store_name = store_name
|
||||
|
||||
self.store.clearSKUs()
|
||||
|
||||
for p in products.values():
|
||||
self.store.addSKU(self.identifier(p))
|
||||
|
||||
def get_store_name(self):
|
||||
return self.store_name
|
||||
|
||||
@@ -105,35 +130,110 @@ init -1500 python in iap:
|
||||
renpy.pause.
|
||||
"""
|
||||
|
||||
while True:
|
||||
rv = self.devicePurchase.checkPurchaseResult()
|
||||
|
||||
if rv:
|
||||
break
|
||||
|
||||
while not self.store.getFinished():
|
||||
if interact:
|
||||
renpy.pause(.1)
|
||||
else:
|
||||
time.sleep(.1)
|
||||
|
||||
if rv == 1:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def purchase(self, p, interact=True):
|
||||
identifier = self.identifier(p)
|
||||
self.devicePurchase.beginPurchase(identifier)
|
||||
return self.wait_for_result(interact=interact)
|
||||
self.store.beginPurchase(identifier)
|
||||
self.wait_for_result(interact=interact)
|
||||
|
||||
def restore_purchases(self, interact=True):
|
||||
self.devicePurchase.restorePurchases()
|
||||
self.store.updatePrices();
|
||||
self.wait_for_result(interact)
|
||||
|
||||
self.store.restorePurchases();
|
||||
self.wait_for_result(interact)
|
||||
|
||||
def has_purchased(self, p):
|
||||
identifier = self.identifier(p)
|
||||
return self.devicePurchase.isPurchaseOwned(identifier)
|
||||
return self.store.hasPurchased(identifier)
|
||||
|
||||
def is_deferred(self, p):
|
||||
return False
|
||||
|
||||
def get_price(self, p):
|
||||
identifier = self.identifier(p)
|
||||
return self.store.getPrice(identifier)
|
||||
|
||||
if renpy.ios:
|
||||
import pyobjus
|
||||
IAPHelper = pyobjus.autoclass("IAPHelper")
|
||||
NSMutableArray = pyobjus.autoclass("NSMutableArray")
|
||||
|
||||
from pyobjus import objc_str, objc_arr
|
||||
|
||||
class IOSBackend(object):
|
||||
|
||||
def __init__(self):
|
||||
self.helper = IAPHelper.alloc().init()
|
||||
|
||||
identifiers = NSMutableArray.alloc().init()
|
||||
|
||||
for p in products.values():
|
||||
identifiers.addObject_(objc_str(p.ios))
|
||||
|
||||
self.helper.productIdentifiers = identifiers
|
||||
|
||||
def get_store_name(self):
|
||||
if self.helper.canMakePayments():
|
||||
return "ios"
|
||||
else:
|
||||
return None
|
||||
|
||||
def identifier(self, p):
|
||||
"""
|
||||
Returns the identifier for a store purchase.
|
||||
"""
|
||||
|
||||
return p.ios
|
||||
|
||||
def wait_for_result(self, interact=True):
|
||||
"""
|
||||
Waits for a result.
|
||||
|
||||
`interact`
|
||||
If true, waits interactively. If false, waits using
|
||||
renpy.pause.
|
||||
"""
|
||||
|
||||
while not self.helper.finished:
|
||||
if interact:
|
||||
renpy.pause(.1)
|
||||
else:
|
||||
import pygame
|
||||
pygame.event.pump()
|
||||
time.sleep(.1)
|
||||
|
||||
def purchase(self, p, interact=True):
|
||||
identifier = objc_str(self.identifier(p))
|
||||
self.helper.beginPurchase_(identifier)
|
||||
self.wait_for_result(interact=interact)
|
||||
|
||||
def restore_purchases(self, interact=True):
|
||||
self.helper.validateProductIdentifiers()
|
||||
self.helper.restorePurchases()
|
||||
self.wait_for_result(interact)
|
||||
|
||||
def has_purchased(self, p):
|
||||
identifier = objc_str(self.identifier(p))
|
||||
return self.helper.hasPurchased_(identifier)
|
||||
|
||||
def is_deferred(self, p):
|
||||
identifier = objc_str(self.identifier(p))
|
||||
return self.helper.isDeferred_(identifier)
|
||||
|
||||
def get_price(self, p):
|
||||
identifier = objc_str(self.identifier(p))
|
||||
rv = self.helper.formatPrice_(identifier)
|
||||
|
||||
if rv is not None:
|
||||
rv = rv.UTF8String().decode("utf-8")
|
||||
|
||||
return rv
|
||||
|
||||
# The backend we're using.
|
||||
backend = NoneBackend()
|
||||
@@ -141,7 +241,7 @@ init -1500 python in iap:
|
||||
# A map from product identifier to the product object.
|
||||
products = { }
|
||||
|
||||
def register(product, identifier=None, amazon=None, google=None):
|
||||
def register(product, identifier=None, amazon=None, google=None, ios=None):
|
||||
"""
|
||||
:doc: iap
|
||||
|
||||
@@ -166,6 +266,10 @@ init -1500 python in iap:
|
||||
`google`
|
||||
A string that identifies the product in the Google Play store.
|
||||
If not given, defaults to `identifier`.
|
||||
|
||||
`ios`
|
||||
A string that identifies the product in the Apple App store for
|
||||
iOS. If not given, defaults to `identifier`.
|
||||
"""
|
||||
|
||||
if product in products:
|
||||
@@ -174,8 +278,9 @@ init -1500 python in iap:
|
||||
identifier = identifier or product
|
||||
amazon = amazon or identifier
|
||||
google = google or identifier
|
||||
ios = ios or identifier
|
||||
|
||||
p = Product(product, identifier, google, amazon)
|
||||
p = Product(product, identifier, google, amazon, ios)
|
||||
products[product] = p
|
||||
|
||||
def with_background(f, *args, **kwargs):
|
||||
@@ -185,6 +290,8 @@ init -1500 python in iap:
|
||||
|
||||
renpy.scene()
|
||||
renpy.show(background)
|
||||
renpy.pause(0)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
def restore(interact=True):
|
||||
@@ -238,12 +345,13 @@ init -1500 python in iap:
|
||||
if persistent._iap_purchases[p.identifier]:
|
||||
return True
|
||||
|
||||
rv = backend.purchase(p, interact)
|
||||
backend.purchase(p, interact)
|
||||
|
||||
if rv:
|
||||
if backend.has_purchased(p):
|
||||
persistent._iap_purchases[p.identifier] = True
|
||||
|
||||
return rv
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
class Purchase(Action):
|
||||
"""
|
||||
@@ -256,13 +364,34 @@ init -1500 python in iap:
|
||||
|
||||
def __init__(self, product):
|
||||
self.product = product
|
||||
self.sensitive = True
|
||||
|
||||
def __call__(self):
|
||||
renpy.invoke_in_new_context(with_background, purchase, self.product)
|
||||
renpy.restart_interaction()
|
||||
|
||||
def should_be_sensitive(self):
|
||||
|
||||
if not get_store_name():
|
||||
return False
|
||||
|
||||
if has_purchased(self.product):
|
||||
return False
|
||||
|
||||
if is_deferred(self.product):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_sensitive(self):
|
||||
return get_store_name() and not has_purchased(self.product)
|
||||
self.sensitive = self.should_be_sensitive()
|
||||
return self.sensitive
|
||||
|
||||
def periodic(self, st):
|
||||
if self.should_be_sensitive() != self.sensitive:
|
||||
renpy.restart_interaction()
|
||||
|
||||
return 5.0
|
||||
|
||||
def has_purchased(product):
|
||||
"""
|
||||
@@ -274,15 +403,53 @@ init -1500 python in iap:
|
||||
|
||||
p = get_product(product)
|
||||
|
||||
return persistent._iap_purchases[p.identifier]
|
||||
# Check the cache first, since we might be off line.
|
||||
if persistent._iap_purchases.get(p.identifier, False):
|
||||
return True
|
||||
|
||||
# Then ask the backend, in case we bought the product
|
||||
# recently.
|
||||
return backend.has_purchased(p)
|
||||
|
||||
|
||||
def is_deferred(product):
|
||||
"""
|
||||
:doc: iap
|
||||
|
||||
Returns True if the user has asked to purchase `product`, but that
|
||||
request has to be approved by a third party, such as a parent or
|
||||
guardian.
|
||||
"""
|
||||
|
||||
p = get_product(product)
|
||||
|
||||
# Then ask the backend, in case we bought the product
|
||||
# recently.
|
||||
return backend.is_deferred(p)
|
||||
|
||||
def get_price(product):
|
||||
"""
|
||||
:doc: iap
|
||||
|
||||
Returns a string giving the price of the `product` in the user's
|
||||
local currency. Returns None if the price of the product is unknown -
|
||||
which indicates the product cannot be purchased.
|
||||
"""
|
||||
|
||||
p = get_product(product)
|
||||
|
||||
if p.price is None:
|
||||
p.price = backend.get_price(p)
|
||||
|
||||
return p.price
|
||||
|
||||
def get_store_name():
|
||||
"""
|
||||
:doc: iap
|
||||
|
||||
Returns the name of the enabled store for in-app purchase. This
|
||||
currently returns one of "amazon", "google", or None if no store
|
||||
is configured.
|
||||
currently returns one of "amazon", "google", "ios" or None if no store
|
||||
is available.
|
||||
"""
|
||||
|
||||
return backend.get_store_name()
|
||||
@@ -304,13 +471,15 @@ init -1500 python in iap:
|
||||
"""
|
||||
|
||||
from jnius import autoclass
|
||||
devicePurchase = autoclass('com.puzzlebrothers.renpurchase.devicePurchase')
|
||||
Store = autoclass('org.renpy.iap.Store')
|
||||
store = Store.getStore()
|
||||
|
||||
store_name = store.getStoreName()
|
||||
|
||||
store_name = devicePurchase.getStoreName()
|
||||
if store_name == "none":
|
||||
return NoneBackend()
|
||||
|
||||
return AndroidBackend(devicePurchase, store_name)
|
||||
return AndroidBackend(store, store_name)
|
||||
|
||||
def init():
|
||||
"""
|
||||
@@ -329,6 +498,12 @@ init -1500 python in iap:
|
||||
# Set up the back end.
|
||||
if renpy.android:
|
||||
backend = init_android()
|
||||
elif renpy.ios:
|
||||
backend = IOSBackend()
|
||||
|
||||
if backend.get_store_name() is None:
|
||||
backend = NoneBackend()
|
||||
|
||||
else:
|
||||
backend = NoneBackend()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
@@ -25,21 +25,26 @@ init -1600 python:
|
||||
|
||||
# Bindings present almost everywhere, unless explicitly
|
||||
# disabled.
|
||||
rollback = [ 'K_PAGEUP', 'mousedown_4', 'joy_rollback' ],
|
||||
rollback = [ 'K_PAGEUP', 'K_AC_BACK', 'mousedown_4', 'joy_rollback' ],
|
||||
screenshot = [ 's' ],
|
||||
toggle_fullscreen = [ 'f', 'alt_K_RETURN', 'alt_K_KP_ENTER', 'K_F11' ],
|
||||
game_menu = [ 'K_ESCAPE', 'mouseup_3', 'joy_menu' ],
|
||||
game_menu = [ 'K_ESCAPE', 'K_MENU', 'mouseup_3', 'joy_menu' ],
|
||||
hide_windows = [ 'mouseup_2', 'h', 'joy_hide' ],
|
||||
launch_editor = [ 'E' ],
|
||||
dump_styles = [ ],
|
||||
reload_game = [ 'R' ],
|
||||
inspector = [ 'I' ],
|
||||
full_inspector = [ 'alt_I' ],
|
||||
developer = [ 'D' ],
|
||||
quit = [ 'meta_q', 'alt_K_F4', 'alt_q' ],
|
||||
iconify = [ 'meta_m', 'alt_m' ],
|
||||
quit = [ ],
|
||||
iconify = [ ],
|
||||
help = [ 'K_F1', 'meta_shift_/' ],
|
||||
choose_renderer = [ 'G' ],
|
||||
progress_screen = [ 'alt_P' ],
|
||||
|
||||
# Accessibility.
|
||||
self_voicing = [ 'v', 'V' ],
|
||||
clipboard_voicing = [ 'C' ],
|
||||
|
||||
# Say.
|
||||
rollforward = [ 'mousedown_5', 'K_PAGEDOWN' ],
|
||||
@@ -101,9 +106,9 @@ init -1600 python:
|
||||
# Ignored (kept for backwards compatibility).
|
||||
toggle_music = [ 'm' ],
|
||||
|
||||
# Profile one frame
|
||||
# Profile commands.
|
||||
profile_once = [ 'K_F8' ],
|
||||
|
||||
memory_profile = [ 'K_F7' ],
|
||||
|
||||
)
|
||||
|
||||
@@ -240,6 +245,35 @@ init -1600 python:
|
||||
renpy.display.interface.profile_once = True
|
||||
renpy.restart_interaction()
|
||||
|
||||
def _memory_profile():
|
||||
renpy.memory.diff_memory()
|
||||
|
||||
def _progress_screen():
|
||||
if renpy.context_nesting_level():
|
||||
return
|
||||
|
||||
if renpy.get_screen("_progress"):
|
||||
renpy.hide_screen("_progress")
|
||||
else:
|
||||
renpy.show_screen("_progress")
|
||||
|
||||
renpy.restart_interaction()
|
||||
|
||||
screen _progress:
|
||||
$ seen = renpy.count_seen_dialogue_blocks()
|
||||
$ total = renpy.count_dialogue_blocks()
|
||||
|
||||
drag:
|
||||
draggable True
|
||||
focus_mask None
|
||||
xpos 0
|
||||
ypos 0
|
||||
|
||||
text "[seen]/[total]":
|
||||
size 14
|
||||
color "#fff"
|
||||
outlines [ (1, "#000", 0, 0) ]
|
||||
|
||||
init -1100 python:
|
||||
|
||||
# The default keymap. We might also want to put some of this into
|
||||
@@ -261,7 +295,10 @@ init -1100 python:
|
||||
choose_renderer = renpy.curried_call_in_new_context("_choose_renderer"),
|
||||
console = _console.enter,
|
||||
profile_once = _profile_once,
|
||||
memory_profile = _memory_profile,
|
||||
self_voicing = Preference("self voicing", "toggle"),
|
||||
clipboard_voicing = Preference("clipboard voicing", "toggle"),
|
||||
progress_screen = _progress_screen,
|
||||
)
|
||||
|
||||
config.underlay = [ km ]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
# Copyright 2004-2015 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user