Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 693cf9f8c9 | |||
| 35c2ec5a83 | |||
| 3b60efd744 | |||
| daac5d8ebf | |||
| 1fab6d8707 | |||
| aaff11668a | |||
| 536341a819 | |||
| b9c468e446 | |||
| 03edec9785 | |||
| da70a85d75 | |||
| 4ba170b8d8 | |||
| 72ae15c635 | |||
| 1179066dda | |||
| 62d0093bee | |||
| 55c0d3b4a7 | |||
| 92014eafdd | |||
| b1be4c8ed4 | |||
| 06f36dd8d1 | |||
| 3a15f5c717 | |||
| 031f3338b1 | |||
| 66125b2e10 | |||
| e6becffc4c | |||
| d281e57879 | |||
| 5196a970a0 | |||
| efcbc92e7a | |||
| 142fa33548 | |||
| 4b6e871ac6 | |||
| 1fbbad053a | |||
| 61aa933d97 | |||
| 70c3ea773e | |||
| a16de04682 | |||
| 0280a12589 | |||
| 4dc8fef9c1 | |||
| 2c02645ec7 | |||
| 40bad327fe | |||
| f5653d3c4d | |||
| 4026d7818b | |||
| a0fda2f058 | |||
| 93546e2d5c | |||
| 85a562713a | |||
| 4e9beb1a5d | |||
| 522333e0f5 | |||
| b4c4d0264c | |||
| 21c3187fa3 | |||
| b377cfcdef |
@@ -1,3 +1,43 @@
|
||||
New in Ren'Py 6.9.2
|
||||
-------------------
|
||||
|
||||
The semantics for play and queue have changed slightly. Now, when a
|
||||
play statement is followed by one or more queue statements, the first
|
||||
file in each play or queue statement will be played. For example:
|
||||
|
||||
play music "a.ogg"
|
||||
queue music "b.ogg"
|
||||
queue music "c.ogg"
|
||||
|
||||
will play "a.ogg", "b.ogg", and then loop "c.ogg". This change also
|
||||
applies to renpy.music.play and renpy.music.queue.
|
||||
|
||||
|
||||
Rollback was changed so that doing anything other than a roll-forward
|
||||
while in rollback mode exits rollback immediately.
|
||||
|
||||
|
||||
The library alias for config has been removed.
|
||||
|
||||
|
||||
Fixed a regression that caused dissolves to be terribly slow.
|
||||
|
||||
Fixed a bug that caused Ren'Py to crash when playing music on Windows
|
||||
when Data Execution Prevention was enabled. DEP is enabled by default
|
||||
on 64-bit Windows Vista.
|
||||
|
||||
Fixed a bug that caused Ren'Py to crash when a window icon was used on
|
||||
a computer with a 16-bit or 8-bit screen depth.
|
||||
|
||||
Fixed a bug that caused ui.sizer to malfunction.
|
||||
|
||||
Fixed a repeated word in "The Question".
|
||||
|
||||
Fixed a bug that could cause it to take two tries to define a joystick
|
||||
button.
|
||||
|
||||
|
||||
|
||||
New in Ren'Py 6.9.1
|
||||
-------------------
|
||||
|
||||
@@ -62,6 +102,10 @@ There is a new config.windows_icon variable, that lets one set the
|
||||
window icon for Windows separately from Mac OS X and Linux.
|
||||
|
||||
|
||||
Ren'Py now automatically scales itself down when it detects that the
|
||||
game window is too large for the screen.
|
||||
|
||||
|
||||
The define.move_transitions function can now pass keyword arguments to
|
||||
the moves it creates. The most useful thing with this is to pass
|
||||
subpixel=True, in order to create subpixel move transitions.
|
||||
@@ -93,6 +137,14 @@ Added more verbose diagnostics when illegal statements are run in the
|
||||
init phase.
|
||||
|
||||
|
||||
Added _rollback, which controls if rollback is enabled.
|
||||
|
||||
|
||||
Added a target parameter to renpy.full_restart, which allows the main
|
||||
menu screen to be selected after a restart.
|
||||
|
||||
|
||||
|
||||
Fixed a bug that caused layout.imagemap_main_menu to call a label even
|
||||
though there was a button with the same name.
|
||||
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ launchers may contain code taken from the following projects:
|
||||
* SDL_ttf (LGPL)
|
||||
* SDL_mixer (LGPL)
|
||||
* Freetype (LGPL)
|
||||
* ffmpeg (LGPL)
|
||||
* FFmpeg (LGPL)
|
||||
* jpeg (JPEG License)
|
||||
* libpng (PNG license)
|
||||
* zlib (Zlib License)
|
||||
|
||||
@@ -13,6 +13,9 @@ init -1210 python:
|
||||
if version <= (6, 5, 0):
|
||||
layout.compat()
|
||||
|
||||
if version <= (6, 9, 1):
|
||||
store.library = store.config
|
||||
|
||||
init 1210 python hide::
|
||||
|
||||
# This returns true if the script_version is <= the
|
||||
|
||||
+11
-11
@@ -607,7 +607,7 @@ label _return:
|
||||
|
||||
if renpy.context().main_menu:
|
||||
$ renpy.transition(config.game_main_transition)
|
||||
jump _main_menu
|
||||
jump _main_menu_screen
|
||||
|
||||
$ renpy.transition(config.exit_transition)
|
||||
|
||||
@@ -682,12 +682,6 @@ label _start:
|
||||
|
||||
$ renpy.block_rollback()
|
||||
|
||||
python hide:
|
||||
for i in range(0, 7):
|
||||
# renpy.music.stop(channel=i)
|
||||
# renpy.sound.stop(channel=i)
|
||||
pass
|
||||
|
||||
if config.main_menu_music:
|
||||
$ renpy.music.play(config.main_menu_music, if_changed=True)
|
||||
else:
|
||||
@@ -703,15 +697,19 @@ label _start:
|
||||
jump expression _restart[1]
|
||||
|
||||
label _invoke_main_menu:
|
||||
|
||||
$ renpy.call_in_new_context("_enter_main_menu")
|
||||
|
||||
if _restart:
|
||||
$ renpy.call_in_new_context(_restart[2])
|
||||
else:
|
||||
$ renpy.call_in_new_context("_main_menu")
|
||||
|
||||
|
||||
# If the main menu returns, then start the game.
|
||||
jump start
|
||||
|
||||
# At this point, we've been switched into a new context. So we
|
||||
# initialize it.
|
||||
label _enter_main_menu:
|
||||
label _main_menu(_main_menu_screen="_main_menu_screen"):
|
||||
|
||||
call _enter_menu from _call__enter_menu_1
|
||||
|
||||
@@ -721,9 +719,11 @@ label _enter_main_menu:
|
||||
|
||||
renpy.context().main_menu = True
|
||||
store.main_menu = True
|
||||
|
||||
jump expression _main_menu_screen
|
||||
|
||||
# This is called to show the main menu to the user.
|
||||
label _main_menu:
|
||||
label _main_menu_screen:
|
||||
|
||||
# Let the user completely override the main menu. (But please note
|
||||
# it still lives in the menu context, rather than the game context.)
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ init -1130 python hide:
|
||||
for i in xrange(0, 8):
|
||||
renpy.music.register_channel(i)
|
||||
|
||||
renpy.music.register_channel("movie", "music", False)
|
||||
renpy.music.register_channel("movie", "music", False, stop_on_mute=False)
|
||||
|
||||
# Set up default names for some of the channels.
|
||||
renpy.music.alias_channel(0, "sound")
|
||||
|
||||
@@ -28,8 +28,6 @@ init python:
|
||||
style.js_prefs_button.xminimum = 0.5
|
||||
style.js_prefs_box.box_first_spacing = 10
|
||||
|
||||
|
||||
|
||||
config.joystick_keys = [
|
||||
(u'Left', 'joy_left'),
|
||||
(u'Right', 'joy_right'),
|
||||
@@ -42,8 +40,6 @@ init python:
|
||||
(u'Hide Text', 'joy_hide'),
|
||||
(u'Menu', 'joy_menu'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
def _joystick_select_binding():
|
||||
|
||||
@@ -55,8 +51,8 @@ init python:
|
||||
layout.button(_(label) + " - " + _(_preferences.joymap.get(key, u"Not Assigned")), "prefs_js", clicked=my_clicked, index=label)
|
||||
|
||||
def _joystick_get_binding():
|
||||
ui.add(renpy.display.joystick.JoyBehavior())
|
||||
ui.saybehavior()
|
||||
ui.add(renpy.display.joystick.JoyBehavior())
|
||||
|
||||
def _joystick_take_binding(binding, key):
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ label main_menu_screen:
|
||||
else:
|
||||
ui.jumpsoutofcontext(rv)()
|
||||
|
||||
|
||||
jump main_menu_screen
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ label start:
|
||||
|
||||
e "We look forward to seeing what you can make with this! Good luck!"
|
||||
|
||||
window hide
|
||||
|
||||
# Returning from the top level quits the game.
|
||||
return
|
||||
|
||||
|
||||
@@ -228,6 +228,7 @@ def main():
|
||||
print "Did you remember to rebuild the exe after the last change?"
|
||||
print "Did you run me with renpython -OO?"
|
||||
print "Was ming using the right crt?"
|
||||
print "Did you update renpy.py and launcher/script_version.rpy?"
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -29,9 +29,10 @@ margin-left: -2.5em;
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="renpy_help"></div>
|
||||
<p><a name="Basic_Help" id="Basic_Help"></a></p>
|
||||
<h3><span class="mw-headline">Basic Help</span></h3>
|
||||
<h2><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="mw-headline">Game Menu</span></h3>
|
||||
@@ -105,5 +106,8 @@ margin-left: -2.5em;
|
||||
<dt>Alt-F4, Command-Q</dt>
|
||||
<dd>Quits the game.</dd>
|
||||
</dl>
|
||||
<p><a name="Legal_Notice" id="Legal_Notice"></a></p>
|
||||
<h2><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 <a href="./renpy/LICENSE.txt">LICENSE.txt</a> file in the renpy directory.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+10
-7
@@ -10,14 +10,17 @@ init:
|
||||
if not config.editor:
|
||||
|
||||
editor = os.path.normpath(config.renpy_base + "/jedit/jedit.jar")
|
||||
editor = renpy.shell_escape(editor)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
config.editor = 'javaw.exe -jar "' + editor + '" -reuseview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
config.editor_transient = 'javaw.exe -jar "' + editor + '" -newplainview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
else:
|
||||
config.editor = 'java -jar "' + editor + '" -reuseview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
config.editor_transient = 'java -jar "' + editor + '" -newplainview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
if os.path.exists(editor):
|
||||
|
||||
editor = renpy.shell_escape(editor)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
config.editor = 'javaw.exe -jar "' + editor + '" -reuseview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
config.editor_transient = 'javaw.exe -jar "' + editor + '" -newplainview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
else:
|
||||
config.editor = 'java -jar "' + editor + '" -reuseview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
config.editor_transient = 'java -jar "' + editor + '" -newplainview "%(filename)s" +line:%(line)d "%(otherfiles)s"'
|
||||
|
||||
if config.editor:
|
||||
os.environ['RENPY_EDITOR'] = config.editor
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
init -999:
|
||||
$ config.script_version = (6, 9, 0)
|
||||
$ config.script_version = (6, 9, 2)
|
||||
|
||||
|
||||
+25
-25
@@ -1000,18 +1000,18 @@ void transform32_std(PyObject *pysrc, PyObject *pydst,
|
||||
|
||||
unsigned int amul = (int) (a * 256);
|
||||
|
||||
lsx = corner_x * 256;
|
||||
lsy = corner_y * 256;
|
||||
lsx = corner_x * 65536;
|
||||
lsy = corner_y * 65536;
|
||||
|
||||
xdx *= 256;
|
||||
ydx *= 256;
|
||||
xdy *= 256;
|
||||
ydy *= 256;
|
||||
xdx *= 65536;
|
||||
ydx *= 65536;
|
||||
xdy *= 65536;
|
||||
ydy *= 65536;
|
||||
|
||||
|
||||
// Scaled subtracted srcw and srch.
|
||||
float fsw = (srcw - 2) * 256;
|
||||
float fsh = (srch - 2) * 256;
|
||||
float fsw = (srcw - 1) * 65536 - 1;
|
||||
float fsh = (srch - 1) * 65536 - 1;
|
||||
|
||||
for (y = 0; y < dsth; y++, lsx += xdy, lsy += ydy) {
|
||||
|
||||
@@ -1058,7 +1058,7 @@ void transform32_std(PyObject *pysrc, PyObject *pydst,
|
||||
|
||||
sx = lsx + minx * xdx;
|
||||
sy = lsy + minx * ydx;
|
||||
|
||||
|
||||
int sxi = (int) sx;
|
||||
int syi = (int) sy;
|
||||
int xdxi = (int) xdx;
|
||||
@@ -1066,13 +1066,13 @@ void transform32_std(PyObject *pysrc, PyObject *pydst,
|
||||
|
||||
while (d <= dend) {
|
||||
int px, py;
|
||||
px = sxi >> 8;
|
||||
py = syi >> 8;
|
||||
px = sxi >> 16;
|
||||
py = syi >> 16;
|
||||
|
||||
unsigned char *sp = srcpixels + py * srcpitch + px * 4;
|
||||
|
||||
int yfrac = syi & 0xff; // ((short) sy) & 0xff;
|
||||
int xfrac = sxi & 0xff; // ((short) sx) & 0xff;
|
||||
int yfrac = (syi >> 8) & 0xff; // ((short) sy) & 0xff;
|
||||
int xfrac = (sxi >> 8) & 0xff; // ((short) sx) & 0xff;
|
||||
|
||||
unsigned int pal = *(unsigned int *) sp;
|
||||
unsigned int pbl = *(unsigned int *) (sp + 4);
|
||||
@@ -1164,17 +1164,17 @@ int transform32_mmx(PyObject *pysrc, PyObject *pydst,
|
||||
// Compute the coloring multiplier.
|
||||
unsigned int amul = (unsigned int) (a * 256);
|
||||
|
||||
lsx = corner_x * 256;
|
||||
lsy = corner_y * 256;
|
||||
lsx = corner_x * 65536;
|
||||
lsy = corner_y * 65536;
|
||||
|
||||
xdx *= 256;
|
||||
ydx *= 256;
|
||||
xdy *= 256;
|
||||
ydy *= 256;
|
||||
xdx *= 65536;
|
||||
ydx *= 65536;
|
||||
xdy *= 65536;
|
||||
ydy *= 65536;
|
||||
|
||||
// Scaled subtracted srcw and srch.
|
||||
float fsw = (srcw - 2) * 256;
|
||||
float fsh = (srch - 2) * 256;
|
||||
float fsw = (srcw - 1) * 65536 - 1;
|
||||
float fsh = (srch - 1) * 65536 - 1;
|
||||
|
||||
for (y = 0; y < dsth; y++, lsx += xdy, lsy += ydy) {
|
||||
|
||||
@@ -1235,13 +1235,13 @@ int transform32_mmx(PyObject *pysrc, PyObject *pydst,
|
||||
|
||||
while (d <= dend) {
|
||||
|
||||
px = sxi >> 8;
|
||||
py = syi >> 8;
|
||||
px = sxi >> 16;
|
||||
py = syi >> 16;
|
||||
|
||||
unsigned char *sp = srcpixels + py * srcpitch + px * 4;
|
||||
|
||||
unsigned int yfrac = syi & 0xff; // ((short) sy) & 0xff;
|
||||
unsigned int xfrac = sxi & 0xff; // ((short) sx) & 0xff;
|
||||
unsigned int yfrac = (syi >> 8) & 0xff; // ((short) sy) & 0xff;
|
||||
unsigned int xfrac = (sxi >> 8) & 0xff; // ((short) sx) & 0xff;
|
||||
|
||||
// Put xfrac in mm5, yfrac in m6
|
||||
pxor_r2r(mm5, mm5);
|
||||
|
||||
+5
-4
@@ -22,11 +22,12 @@
|
||||
#include <pygame/pygame.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include <libavutil/avstring.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
// #include "libavdevice/avdevice.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libavcodec/audioconvert.h"
|
||||
#include <libswscale/swscale.h>
|
||||
// #include "libavcodec/audioconvert.h"
|
||||
// #include "libavcodec/opt.h"
|
||||
|
||||
// #include "cmdutils.h"
|
||||
|
||||
+42
-19
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
Copyright 2005-2009 PyTom <pytom@bishoujo.us>
|
||||
|
||||
@@ -112,9 +111,6 @@ struct Channel {
|
||||
/* The queued up sample. */
|
||||
struct VideoState *queued;
|
||||
|
||||
/* A sample that's dying, and needs to be deallocated. */
|
||||
struct VideoState *dying;
|
||||
|
||||
/* The name of the queued up sample. */
|
||||
PyObject *queued_name;
|
||||
|
||||
@@ -173,6 +169,13 @@ struct Channel {
|
||||
unsigned int vol2_done;
|
||||
};
|
||||
|
||||
struct Dying {
|
||||
struct VideoState *stream;
|
||||
struct Dying *next;
|
||||
};
|
||||
|
||||
static struct Dying *dying = NULL;
|
||||
|
||||
/*
|
||||
* The number of channels the system knows about.
|
||||
*/
|
||||
@@ -247,8 +250,12 @@ static void start_sample(struct Channel* c, int reset_fade) {
|
||||
c->fade_off = 0;
|
||||
c->fade_vol = 0;
|
||||
|
||||
c->fade_step_len = ms_to_bytes(c->playing_fadein) / fade_steps;
|
||||
c->fade_step_len &= ~0x7; // Even sample.
|
||||
if (fade_steps) {
|
||||
c->fade_step_len = ms_to_bytes(c->playing_fadein) / fade_steps;
|
||||
c->fade_step_len &= ~0x7; // Even sample.
|
||||
} else {
|
||||
c->fade_step_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
c->stop_bytes = -1;
|
||||
@@ -440,10 +447,15 @@ static void callback(void *userdata, Uint8 *stream, int length) {
|
||||
if (c->stop_bytes == 0 || bytes == 0) {
|
||||
|
||||
int old_tight = c->playing_tight;
|
||||
|
||||
struct Dying *d;
|
||||
|
||||
post_event(c);
|
||||
|
||||
c->dying = c->playing;
|
||||
d = malloc(sizeof(struct Dying));
|
||||
d->next = dying;
|
||||
d->stream = c->playing;
|
||||
dying = d;
|
||||
|
||||
decref(c->playing_name);
|
||||
|
||||
c->playing = c->queued;
|
||||
@@ -488,7 +500,6 @@ static int check_channel(int c) {
|
||||
channels[i].queued = NULL;
|
||||
channels[i].playing_name = NULL;
|
||||
channels[i].queued_name = NULL;
|
||||
channels[i].dying = NULL;
|
||||
channels[i].volume = SDL_MIX_MAXVOLUME;
|
||||
channels[i].paused = 1;
|
||||
channels[i].event = 0;
|
||||
@@ -786,14 +797,20 @@ void PSS_fadeout(int channel, int ms) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
fade_steps = c->volume;
|
||||
c->fade_delta = -1;
|
||||
c->fade_off = 0;
|
||||
c->fade_vol = c->volume;
|
||||
|
||||
c->fade_step_len = ms_to_bytes(ms) / fade_steps;
|
||||
c->fade_step_len &= ~0x7; // Even sample.
|
||||
|
||||
if (fade_steps) {
|
||||
c->fade_step_len = ms_to_bytes(ms) / fade_steps;
|
||||
c->fade_step_len &= ~0x7; // Even sample.
|
||||
} else {
|
||||
c->fade_step_len = 0;
|
||||
}
|
||||
|
||||
c->stop_bytes = ms_to_bytes(ms);
|
||||
c->queued_tight = 0;
|
||||
|
||||
@@ -1080,14 +1097,20 @@ void PSS_periodic() {
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_channels; i++) {
|
||||
if (channels[i].dying) {
|
||||
ENTER();
|
||||
ffpy_stream_close(channels[i].dying);
|
||||
channels[i].dying = NULL;
|
||||
EXIT();
|
||||
}
|
||||
if (!dying) {
|
||||
return;
|
||||
}
|
||||
|
||||
ENTER();
|
||||
|
||||
while (dying) {
|
||||
struct Dying *d = dying;
|
||||
ffpy_stream_close(d->stream);
|
||||
dying = d->next;
|
||||
free(d);
|
||||
}
|
||||
|
||||
EXIT();
|
||||
}
|
||||
|
||||
/* This should be called in response to an FF_ALLOC_EVENT, with a pygame
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
#include <Python.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "pygame.h"
|
||||
#include <pygame/pygame.h>
|
||||
#include "structmember.h"
|
||||
#include "renpy_ttf.h"
|
||||
|
||||
|
||||
Regular → Executable
+103
-35
@@ -1,6 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import distutils.core
|
||||
import os
|
||||
import os.path
|
||||
@@ -12,45 +10,119 @@ try:
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# These control the level of optimization versus debugging.
|
||||
extra_compile_args = [ "-O3", "-funroll-loops" ]
|
||||
# extra_compile_args = [ "-O0", "-ggdb" ]
|
||||
# extra_compile_args = [ "-O0", "-gstabs" ]
|
||||
|
||||
|
||||
# This environment variable should have the full path to the installed
|
||||
# Ren'Py dependencies.
|
||||
install = os.environ.get("RENPY_DEPS_INSTALL", "/does/not/exist")
|
||||
install = os.environ.get("RENPY_DEPS_INSTALL", None)
|
||||
|
||||
# Check to see if that's the case.
|
||||
if not os.path.isdir(install):
|
||||
print "The Ren'Py dependencies install directory:"
|
||||
print
|
||||
print install
|
||||
print
|
||||
print "does not exist. Please set RENPY_DEPS_INSTALL to the correct"
|
||||
print "location of the Ren'Py dependencies install directory, and "
|
||||
print "re-run this script."
|
||||
if install is None:
|
||||
print """
|
||||
The RENPY_DEPS_INSTALL environment variable has not been set. This
|
||||
should be set to a double-colon-delimited list of places where the
|
||||
Ren'Py dependencies can be found. (To use system libraries, this can
|
||||
be set to a system directory, like /usr.)
|
||||
"""
|
||||
sys.exit(-1)
|
||||
|
||||
ffmpeg = os.environ.get("FFMPEG_BUILD_PATH", "/does/not/exist")
|
||||
install = install.split("::")
|
||||
|
||||
if not os.path.isdir(install):
|
||||
print "The FFMPEG build path:"
|
||||
print
|
||||
print ffmpeg
|
||||
print
|
||||
print "does not exist. Please set FFMPEG_BUILD_PATH to the correct"
|
||||
print "location and re-run this script."
|
||||
sys.exit(-1)
|
||||
include_dirs = [ ]
|
||||
library_dirs = [ ]
|
||||
|
||||
def add_include(prefix, file):
|
||||
"""
|
||||
Search for prefix/file underneath <i> and <i>/include, for each of the
|
||||
directories <i> in install. When found, puts the directory it was found
|
||||
in into include_dirs.
|
||||
"""
|
||||
|
||||
checked = [ ]
|
||||
for i in install:
|
||||
|
||||
dir = os.path.join(i, prefix)
|
||||
fn = os.path.join(dir, file)
|
||||
fn = os.path.normpath(fn)
|
||||
checked.append(fn)
|
||||
if os.path.exists(fn):
|
||||
break
|
||||
|
||||
dir = os.path.join(i, "include", prefix)
|
||||
fn = os.path.join(dir, file)
|
||||
fn = os.path.normpath(fn)
|
||||
checked.append(fn)
|
||||
|
||||
if os.path.exists(fn):
|
||||
break
|
||||
|
||||
else:
|
||||
|
||||
print "Could not find include %s." % file
|
||||
print "The paths searched were:"
|
||||
for i in checked:
|
||||
print "-", i
|
||||
sys.exit(-1)
|
||||
|
||||
dir = os.path.normpath(dir)
|
||||
|
||||
print "Found %s in %s." % (file, dir)
|
||||
|
||||
if dir not in include_dirs:
|
||||
include_dirs.append(dir)
|
||||
|
||||
def add_library(name):
|
||||
"""
|
||||
This looks for a library named name in the <i> and <i>/lib, for all
|
||||
<i> in install. When found, it adds it to library_dirs.
|
||||
"""
|
||||
|
||||
checked = [ ]
|
||||
|
||||
# Default compile arguements for everybody.
|
||||
include_dirs = [ install + "/include",
|
||||
install + "/include/SDL",
|
||||
install + "/include/freetype2",
|
||||
install + "/include/pygame",
|
||||
ffmpeg]
|
||||
for i in install:
|
||||
for d in ('', 'lib'):
|
||||
for suffix in (".so", ".dylib", ".a"):
|
||||
|
||||
library_dirs = [ install + "/lib" ]
|
||||
dir = os.path.join(i, d)
|
||||
fn = os.path.join(dir, name + suffix)
|
||||
checked.append(fn)
|
||||
|
||||
if os.path.exists(fn):
|
||||
print "Found %s." % fn
|
||||
|
||||
if dir not in library_dirs:
|
||||
library_dirs.append(dir)
|
||||
return
|
||||
|
||||
print "Couldn't find library %s." % name
|
||||
print "The paths searched were:"
|
||||
for i in checked:
|
||||
print "-", i
|
||||
sys.exit(-1)
|
||||
|
||||
add_include("", "zlib.h")
|
||||
add_include("", "png.h")
|
||||
add_include("SDL", "SDL.h")
|
||||
add_include("", "ft2build.h")
|
||||
add_include("freetype2", "freetype/freetype.h")
|
||||
add_include("", "libavutil/avstring.h")
|
||||
add_include("", "libavformat/avformat.h")
|
||||
add_include("", "libavcodec/avcodec.h")
|
||||
add_include("", "libswscale/swscale.h")
|
||||
|
||||
add_library("libSDL")
|
||||
add_library("libz")
|
||||
add_library("libpng")
|
||||
add_library("libavformat")
|
||||
add_library("libavcodec")
|
||||
add_library("libavutil")
|
||||
add_library("libfreetype")
|
||||
|
||||
|
||||
# Fast math breaks on windows. :-(
|
||||
extra_compile_args = [ "-O3", "-funroll-loops" ] # , "-ffast-math" ]
|
||||
# extra_compile_args = [ "-O0", "-ggdb" ]
|
||||
|
||||
extra_link_args = [ ]
|
||||
|
||||
@@ -67,10 +139,6 @@ if platform.win32_ver()[0]:
|
||||
extra_compile_args.append("-fno-strict-aliasing")
|
||||
winmixer = True
|
||||
|
||||
# Detect mac.
|
||||
if platform.mac_ver()[0]:
|
||||
nativemidi_libs = [ 'SDL' ]
|
||||
|
||||
# Detect OSS.
|
||||
try:
|
||||
import ossaudiodev
|
||||
|
||||
+5
-1
@@ -124,7 +124,11 @@ def get_pos(channel):
|
||||
return PSS_get_pos(channel)
|
||||
|
||||
def set_volume(channel, volume):
|
||||
PSS_set_volume(channel, 10 ** volume / 10 )
|
||||
if volume == 0:
|
||||
PSS_set_volume(channel, 0)
|
||||
else:
|
||||
PSS_set_volume(channel, 10 ** volume / 10 )
|
||||
|
||||
check_error()
|
||||
|
||||
def set_pan(channel, pan, delay):
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
dist/MSVCR71.dll
|
||||
dist/msvcr71.dll
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
# ***** ***** ***** ***** ***** ***** **** ***** ***** ***** *****
|
||||
# Be sure to change script_version in launcher/script_version.rpy, too!
|
||||
# Also check to see if we have to update renpy.py.
|
||||
version = "Ren'Py 6.9.1b"
|
||||
version = "Ren'Py 6.9.2a"
|
||||
script_version = 5003000
|
||||
savegame_suffix = "-LT1.save"
|
||||
|
||||
|
||||
+54
-34
@@ -181,7 +181,7 @@ class Channel(object):
|
||||
This stores information about the currently-playing music.
|
||||
"""
|
||||
|
||||
def __init__(self, name, default_loop):
|
||||
def __init__(self, name, default_loop, stop_on_mute, tight):
|
||||
|
||||
# The name assigned to this channel. This is used to look up
|
||||
# information about the channel in the MusicContext object.
|
||||
@@ -235,6 +235,17 @@ class Channel(object):
|
||||
# The time the secondary volume of this channel was last set.
|
||||
self.secondary_volume_time = None
|
||||
|
||||
# Should we stop playing on mute?
|
||||
self.stop_on_mute = stop_on_mute
|
||||
|
||||
# Is this channel tight?
|
||||
self.tight = tight
|
||||
|
||||
# The number of items in the queue that should be kept
|
||||
# on queue clear.
|
||||
self.keep_queue = 0
|
||||
|
||||
|
||||
if default_loop is None:
|
||||
# By default, should we loop the music?
|
||||
self.default_loop = True
|
||||
@@ -287,10 +298,9 @@ class Channel(object):
|
||||
|
||||
# This should be set from something that checks to see if our
|
||||
# mixer is muted.
|
||||
force_stop = self.context.force_stop or renpy.game.preferences.mute[self.mixer]
|
||||
force_stop = self.context.force_stop or (renpy.game.preferences.mute[self.mixer] and self.stop_on_mute)
|
||||
|
||||
if self.playing and force_stop:
|
||||
|
||||
pss.stop(self.number)
|
||||
self.playing = False
|
||||
self.wait_stop = False
|
||||
@@ -335,14 +345,18 @@ class Channel(object):
|
||||
break
|
||||
|
||||
# Otherwise, we might be able to enqueue something.
|
||||
topq = self.queue[0]
|
||||
topq = self.queue.pop(0)
|
||||
|
||||
# At this point, we've decided to try to play
|
||||
# top. So let's see how far we can get.
|
||||
|
||||
# Update the queue
|
||||
self.queue = self.queue[1:]
|
||||
# Blacklist of old file formats we used to support, but we now
|
||||
# ignore.
|
||||
lfn = topq.filename.lower()
|
||||
for i in (".mod", ".xm", ".mid", ".midi"):
|
||||
if lfn.endswith(i):
|
||||
topq = None
|
||||
|
||||
if not topq:
|
||||
continue
|
||||
|
||||
try:
|
||||
topf = load(topq.filename)
|
||||
|
||||
@@ -374,22 +388,27 @@ class Channel(object):
|
||||
|
||||
def dequeue(self, even_tight=False):
|
||||
"""
|
||||
Clears any queued music. Doesn't stop the playing music, if
|
||||
any, but will prevent looping from occuring.
|
||||
Clears the queued music.
|
||||
|
||||
If the first item in the queue has not been started, then it is
|
||||
left in the queue unless all is given.
|
||||
"""
|
||||
|
||||
self.queue = [ ]
|
||||
self.queue = self.queue[:self.keep_queue]
|
||||
self.loop = [ ]
|
||||
|
||||
|
||||
if not pcm_ok:
|
||||
return
|
||||
|
||||
pss.dequeue(self.number, even_tight)
|
||||
|
||||
if self.keep_queue == 0:
|
||||
pss.dequeue(self.number, even_tight)
|
||||
|
||||
def interact(self):
|
||||
"""
|
||||
Called (mostly) once per interaction.
|
||||
"""
|
||||
|
||||
self.keep_queue = 0
|
||||
|
||||
if pcm_ok:
|
||||
|
||||
@@ -418,6 +437,7 @@ class Channel(object):
|
||||
of seconds. Also clears any queued music.
|
||||
"""
|
||||
|
||||
self.keep_queue = 0
|
||||
self.dequeue()
|
||||
|
||||
if not pcm_ok:
|
||||
@@ -429,7 +449,7 @@ class Channel(object):
|
||||
pss.fadeout(self.number, int(secs * 1000))
|
||||
|
||||
|
||||
def enqueue(self, filenames, loop=True, synchro_start=False, fadein=0, tight=False):
|
||||
def enqueue(self, filenames, loop=True, synchro_start=False, fadein=0, tight=None):
|
||||
|
||||
for filename in filenames:
|
||||
renpy.game.persistent._seen_audio[filename] = True
|
||||
@@ -437,6 +457,11 @@ class Channel(object):
|
||||
if not pcm_ok:
|
||||
return
|
||||
|
||||
if tight is None:
|
||||
tight = self.tight
|
||||
|
||||
self.keep_queue += 1
|
||||
|
||||
for filename in filenames:
|
||||
qe = QueueEntry(filename, int(fadein * 1000), tight)
|
||||
self.queue.append(qe)
|
||||
@@ -494,11 +519,11 @@ all_channels = [ ]
|
||||
channels = { }
|
||||
|
||||
|
||||
def register_channel(name, mixer=None, loop=None):
|
||||
def register_channel(name, mixer=None, loop=None, stop_on_mute=True, tight=False):
|
||||
if not renpy.game.init_phase:
|
||||
raise Exception("Can't register channel outside of init phase.")
|
||||
|
||||
c = Channel(name, loop)
|
||||
c = Channel(name, loop, stop_on_mute, tight)
|
||||
c.mixer = mixer
|
||||
all_channels.append(c)
|
||||
channels[name] = c
|
||||
@@ -634,7 +659,7 @@ def periodic():
|
||||
|
||||
max_volume = -1.0
|
||||
volumes = renpy.game.preferences.volumes
|
||||
|
||||
|
||||
if mix_ok:
|
||||
|
||||
anything_playing = False
|
||||
@@ -646,28 +671,26 @@ def periodic():
|
||||
if vol != 0:
|
||||
anything_playing = True
|
||||
|
||||
if not anything_playing:
|
||||
disable_mixer()
|
||||
return
|
||||
|
||||
enable_mixer()
|
||||
|
||||
if max_volume == -1.0:
|
||||
return
|
||||
|
||||
if max_volume == 0.0:
|
||||
return
|
||||
if not anything_playing:
|
||||
disable_mixer()
|
||||
pcm_volume = -1.0
|
||||
else:
|
||||
enable_mixer()
|
||||
|
||||
if max_volume != pcm_volume:
|
||||
mix.set_wave(max_volume)
|
||||
pcm_volume = max_volume
|
||||
|
||||
if max_volume != pcm_volume:
|
||||
mix.set_wave(max_volume)
|
||||
pcm_volume = max_volume
|
||||
|
||||
for c in all_channels:
|
||||
|
||||
vol = c.chan_volume * volumes[c.mixer]
|
||||
|
||||
vol /= max_volume
|
||||
|
||||
|
||||
if c.actual_volume != vol:
|
||||
pss.set_volume(c.number, vol)
|
||||
c.actual_volume = vol
|
||||
@@ -676,9 +699,6 @@ def periodic():
|
||||
|
||||
for c in all_channels:
|
||||
|
||||
if not c.playing:
|
||||
continue
|
||||
|
||||
vol = c.chan_volume * volumes[c.mixer]
|
||||
|
||||
if vol != c.actual_volume:
|
||||
|
||||
@@ -35,7 +35,7 @@ from renpy.audio.audio import get_channel, get_serial
|
||||
# Part of the public api:
|
||||
from renpy.audio.audio import register_channel, alias_channel
|
||||
|
||||
def play(filenames, channel="music", loop=None, fadeout=None, synchro_start=False, fadein=0, tight=False, if_changed=False):
|
||||
def play(filenames, channel="music", loop=None, fadeout=None, synchro_start=False, fadein=0, tight=None, if_changed=False):
|
||||
"""
|
||||
This stops the music currently playing on the numbered channel, dequeues
|
||||
any queued music, and begins playing the specified file or files. If loop
|
||||
@@ -108,7 +108,7 @@ def play(filenames, channel="music", loop=None, fadeout=None, synchro_start=Fals
|
||||
raise
|
||||
|
||||
|
||||
def queue(filenames, channel="music", loop=None, clear_queue=True, fadein=0, tight=False):
|
||||
def queue(filenames, channel="music", loop=None, clear_queue=True, fadein=0, tight=None):
|
||||
"""
|
||||
This queues the given filenames on the specified channel. If
|
||||
clear_queue is True, then the queue is cleared, making these files
|
||||
@@ -185,8 +185,6 @@ def stop(channel="music", fadeout=None):
|
||||
try:
|
||||
c = get_channel(channel)
|
||||
ctx = c.context
|
||||
|
||||
c.dequeue()
|
||||
|
||||
if fadeout is None:
|
||||
fadeout = renpy.config.fade_music
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ def display_say(show_function,
|
||||
|
||||
# If we're in fast skipping mode, don't bother with say
|
||||
# statements at all.
|
||||
if renpy.config.skipping == "fast":
|
||||
if interact and renpy.config.skipping == "fast":
|
||||
|
||||
# Clears out transients.
|
||||
renpy.exports.with_statement(None)
|
||||
|
||||
+23
-22
@@ -187,9 +187,7 @@ class Keymap(renpy.display.layout.Null):
|
||||
|
||||
class RollForward(renpy.display.layout.Null):
|
||||
"""
|
||||
This is a behavior that maps keys to functions that are called when
|
||||
the key is pressed. The keys are specified by giving the appropriate
|
||||
k_constant from pygame.constants, or the unicode for the key.
|
||||
This behavior implements rollforward.
|
||||
"""
|
||||
|
||||
def __init__(self, value):
|
||||
@@ -202,6 +200,7 @@ class RollForward(renpy.display.layout.Null):
|
||||
if map_event(ev, "rollforward"):
|
||||
renpy.game.interface.suppress_transition = True
|
||||
renpy.game.after_rollback = True
|
||||
renpy.game.log.rolled_forward = True
|
||||
return self.value
|
||||
|
||||
class PauseBehavior(renpy.display.layout.Null):
|
||||
@@ -276,22 +275,6 @@ class SayBehavior(renpy.display.layout.Null):
|
||||
|
||||
def event(self, ev, x, y, st):
|
||||
|
||||
skip_delay = renpy.config.skip_delay / 1000.0
|
||||
|
||||
if renpy.config.allow_skipping and renpy.config.skipping and \
|
||||
st >= skip_delay:
|
||||
|
||||
if renpy.game.preferences.skip_unseen:
|
||||
return True
|
||||
elif renpy.config.skipping == "fast":
|
||||
return True
|
||||
elif renpy.game.context().seen_current(True):
|
||||
return True
|
||||
|
||||
if renpy.config.allow_skipping and renpy.config.skipping and \
|
||||
st < skip_delay:
|
||||
renpy.game.interface.timeout(skip_delay - st)
|
||||
|
||||
if self.afm_length and renpy.game.preferences.afm_time and renpy.game.preferences.afm_enable:
|
||||
|
||||
afm_delay = ( 1.0 * ( renpy.config.afm_bonus + self.afm_length ) / renpy.config.afm_characters ) * renpy.game.preferences.afm_time
|
||||
@@ -311,7 +294,7 @@ class SayBehavior(renpy.display.layout.Null):
|
||||
renpy.game.interface.timeout(afm_delay - st)
|
||||
|
||||
for dismiss in self.dismiss:
|
||||
|
||||
|
||||
if map_event(ev, dismiss) and self.is_focused():
|
||||
|
||||
if renpy.config.skipping:
|
||||
@@ -325,6 +308,23 @@ class SayBehavior(renpy.display.layout.Null):
|
||||
|
||||
return True
|
||||
|
||||
skip_delay = renpy.config.skip_delay / 1000.0
|
||||
|
||||
if renpy.config.allow_skipping and renpy.config.skipping and \
|
||||
st >= skip_delay:
|
||||
|
||||
if renpy.game.preferences.skip_unseen:
|
||||
return True
|
||||
elif renpy.config.skipping == "fast":
|
||||
return True
|
||||
elif renpy.game.context().seen_current(True):
|
||||
return True
|
||||
|
||||
if renpy.config.allow_skipping and renpy.config.skipping and \
|
||||
st < skip_delay:
|
||||
renpy.game.interface.timeout(skip_delay - st)
|
||||
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@@ -423,8 +423,9 @@ class Button(renpy.display.layout.Window):
|
||||
|
||||
self.activated = True
|
||||
self.style.set_prefix(self.role + 'activate_')
|
||||
|
||||
renpy.audio.sound.play(self.style.sound)
|
||||
|
||||
if self.style.sound:
|
||||
renpy.audio.music.play(self.style.sound, channel="sound")
|
||||
|
||||
rv = self.clicked()
|
||||
|
||||
|
||||
+19
-13
@@ -119,7 +119,8 @@ class Displayable(renpy.object.Object):
|
||||
self.set_style_prefix(self.role + "hover_")
|
||||
|
||||
if not default and not self.activated:
|
||||
renpy.audio.sound.play(self.style.sound)
|
||||
if self.style.sound:
|
||||
renpy.audio.music.play(self.style.sound, channel="sound")
|
||||
|
||||
def unfocus(self):
|
||||
"""
|
||||
@@ -698,15 +699,13 @@ class Display(object):
|
||||
|
||||
# Convert the aspect ratio to be square.
|
||||
iw, ih = im.get_size()
|
||||
if iw != ih:
|
||||
imax = max(iw, ih)
|
||||
square_im = renpy.display.scale.PygameSurface((imax, imax), pygame.SRCALPHA)
|
||||
square_im.blit(im, ( (imax-iw)/2, (imax-ih)/2 ))
|
||||
im = square_im
|
||||
imax = max(iw, ih)
|
||||
square_im = renpy.display.scale.PygameSurface((imax, imax), pygame.SRCALPHA, depth=32)
|
||||
square_im.blit(im, ( (imax-iw)/2, (imax-ih)/2 ))
|
||||
im = square_im
|
||||
|
||||
|
||||
if on_windows and im.get_size() != (32, 32):
|
||||
im = renpy.display.scale.real_bilinear(im, (32, 32))
|
||||
im = renpy.display.scale.real_smoothscale(im, (32, 32))
|
||||
|
||||
pygame.display.set_icon(im)
|
||||
|
||||
@@ -1014,16 +1013,23 @@ class Display(object):
|
||||
Saves a full-size screenshot in the given filename.
|
||||
"""
|
||||
|
||||
renpy.display.scale.image_save_unscaled(self.window, filename)
|
||||
|
||||
try:
|
||||
renpy.display.scale.image_save_unscaled(self.window, filename)
|
||||
except:
|
||||
if renpy.config.debug:
|
||||
raise
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def screenshot(self, scale):
|
||||
"""
|
||||
Returns a pygame Surface that is a screenshot of the current
|
||||
contents of the window.
|
||||
Returns a string containing the contents of the window, as a PNG.
|
||||
"""
|
||||
|
||||
surf = renpy.display.module.scale(self.window, scale)
|
||||
surf = self.window.convert_alpha()
|
||||
surf = renpy.display.scale.smoothscale(surf, scale)
|
||||
surf = surf.convert()
|
||||
|
||||
sio = cStringIO.StringIO()
|
||||
renpy.display.module.save_png(surf, sio, 0)
|
||||
|
||||
@@ -78,7 +78,8 @@ class ImageFont(object):
|
||||
def render(self, text, antialias, color, black_color=(0, 0, 0, 255), background=None):
|
||||
|
||||
if not text:
|
||||
return surf
|
||||
return pygame.Surface((0, self.height), 0,
|
||||
renpy.game.interface.display.sample_surface)
|
||||
|
||||
xoff, _ = self.offsets[text[0]]
|
||||
x = -xoff
|
||||
|
||||
+39
-21
@@ -687,7 +687,7 @@ class FrameImage(ImageBase):
|
||||
tilew, tileh = srcsize
|
||||
dstw, dsth = dstsize
|
||||
|
||||
surf2 = pygame.Surface(dstsize, 0, surf)
|
||||
surf2 = renpy.display.scale.PygameSurface(dstsize, 0, surf)
|
||||
|
||||
for y in range(0, dsth, tileh):
|
||||
for x in range(0, dstw, tilew):
|
||||
@@ -707,6 +707,7 @@ class FrameImage(ImageBase):
|
||||
# Blit.
|
||||
dest.blit(surf, (dx0, dy0))
|
||||
|
||||
|
||||
# Top row.
|
||||
draw(0, xb, 0, yb)
|
||||
draw(xb, -xb, 0, yb)
|
||||
@@ -721,7 +722,7 @@ class FrameImage(ImageBase):
|
||||
draw(0, xb, -yb, 0)
|
||||
draw(xb, -xb, -yb, 0)
|
||||
draw(-xb, 0, -yb, 0)
|
||||
|
||||
|
||||
# And, finish up.
|
||||
return rv
|
||||
|
||||
@@ -770,15 +771,20 @@ class Scale(ImageBase):
|
||||
|
||||
def load(self):
|
||||
|
||||
child = cache.get(self.image)
|
||||
|
||||
if self.bilinear:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.smoothscale(cache.get(self.image), (self.width, self.height))
|
||||
renpy.display.render.blit_lock.release()
|
||||
|
||||
try:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = renpy.display.scale.smoothscale(child, (self.width, self.height))
|
||||
finally:
|
||||
renpy.display.render.blit_lock.release()
|
||||
else:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.scale(cache.get(self.image), (self.width, self.height))
|
||||
renpy.display.render.blit_lock.release()
|
||||
try:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.scale(child, (self.width, self.height))
|
||||
finally:
|
||||
renpy.display.render.blit_lock.release()
|
||||
|
||||
return rv
|
||||
|
||||
@@ -813,14 +819,18 @@ class FactorScale(ImageBase):
|
||||
height = int(height * self.height)
|
||||
|
||||
if self.bilinear:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.smoothscale(surf, (width, height))
|
||||
renpy.display.render.blit_lock.release()
|
||||
try:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = renpy.display.scale.smoothscale(surf, (width, height))
|
||||
finally:
|
||||
renpy.display.render.blit_lock.release()
|
||||
|
||||
else:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.scale(surf, (width, height))
|
||||
renpy.display.render.blit_lock.release()
|
||||
try:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.scale(surf, (width, height))
|
||||
finally:
|
||||
renpy.display.render.blit_lock.release()
|
||||
|
||||
return rv
|
||||
|
||||
@@ -856,9 +866,13 @@ class Flip(ImageBase):
|
||||
|
||||
def load(self):
|
||||
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.flip(cache.get(self.image), self.horizontal, self.vertical)
|
||||
renpy.display.render.blit_lock.release()
|
||||
child = cache.get(self.image)
|
||||
|
||||
try:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.flip(child, self.horizontal, self.vertical)
|
||||
finally:
|
||||
renpy.display.render.blit_lock.release()
|
||||
|
||||
return rv
|
||||
|
||||
@@ -893,9 +907,13 @@ class Rotozoom(ImageBase):
|
||||
|
||||
def load(self):
|
||||
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.rotozoom(cache.get(self.image), self.angle, self.zoom)
|
||||
renpy.display.render.blit_lock.release()
|
||||
child = cache.get(self.image)
|
||||
|
||||
try:
|
||||
renpy.display.render.blit_lock.acquire()
|
||||
rv = pygame.transform.rotozoom(child, self.angle, self.zoom)
|
||||
finally:
|
||||
renpy.display.render.blit_lock.release()
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import pygame
|
||||
from pygame.constants import *
|
||||
|
||||
import renpy
|
||||
from renpy.display.render import render, IDENTITY, Matrix2D
|
||||
from renpy.display.render import render, Render, IDENTITY, Matrix2D
|
||||
import time
|
||||
import math
|
||||
|
||||
|
||||
@@ -383,6 +383,7 @@ else:
|
||||
|
||||
if version >= 6009000:
|
||||
def subpixel(src, dst, x, y):
|
||||
|
||||
shift = renpy.game.interface.display.sample_surface.get_shifts()[3]
|
||||
_renpy.subpixel(src, dst, x, y, shift)
|
||||
|
||||
|
||||
+115
-78
@@ -27,6 +27,7 @@ import math
|
||||
|
||||
import renpy
|
||||
|
||||
|
||||
# We grab the blit lock each time it is necessary to blit
|
||||
# something. This allows call to the pygame.transform functions to
|
||||
# disable blitting, should it prove necessary.
|
||||
@@ -177,30 +178,43 @@ def process_redraws():
|
||||
need to redraw the screen now, false otherwise.
|
||||
"""
|
||||
|
||||
global redraw_queue
|
||||
|
||||
redraw_queue.sort()
|
||||
|
||||
|
||||
now = renpy.display.core.get_time()
|
||||
|
||||
rv = invalidated
|
||||
|
||||
new_redraw_queue = [ ]
|
||||
seen = set()
|
||||
|
||||
while redraw_queue:
|
||||
when, d = redraw_queue[0]
|
||||
for t in redraw_queue:
|
||||
when, d = t
|
||||
|
||||
if when > now:
|
||||
break
|
||||
if d in seen:
|
||||
continue
|
||||
|
||||
redraw_queue.pop(0)
|
||||
seen.add(d)
|
||||
|
||||
# Remove this displayable and all its parents from the
|
||||
# render cache. But don't kill them yet, as that will kill the
|
||||
# children that we want to reuse.
|
||||
if d not in render_cache:
|
||||
continue
|
||||
|
||||
if d in render_cache:
|
||||
if when <= now:
|
||||
# Remove this displayable and all its parents from the
|
||||
# render cache. But don't kill them yet, as that will kill the
|
||||
# children that we want to reuse.
|
||||
|
||||
for v in render_cache[d].values():
|
||||
v.kill_cache()
|
||||
|
||||
rv = True
|
||||
|
||||
else:
|
||||
new_redraw_queue.append(t)
|
||||
|
||||
redraw_queue = new_redraw_queue
|
||||
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
@@ -222,7 +236,7 @@ def redraw(d, when):
|
||||
|
||||
if not renpy.game.interface:
|
||||
return
|
||||
|
||||
|
||||
redraw_queue.append((when + renpy.game.interface.frame_time, d))
|
||||
|
||||
|
||||
@@ -475,10 +489,12 @@ def draw(dest, clip, what, xo, yo, screen):
|
||||
if clip:
|
||||
w, h = what.get_size()
|
||||
dest.blits.append((xo, yo, xo + w, yo + h, clip, what, None))
|
||||
else:
|
||||
blit_lock.acquire()
|
||||
dest.blit(what, (xo, yo))
|
||||
blit_lock.release()
|
||||
else:
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
dest.blit(what, (xo, yo))
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
# Subpixel blit.
|
||||
else:
|
||||
@@ -1262,7 +1278,7 @@ class Render(object):
|
||||
vc = [ ]
|
||||
rv = True
|
||||
else:
|
||||
if not source.get_masks()[3]:
|
||||
if not child.get_masks()[3]:
|
||||
vc = [ ]
|
||||
rv = True
|
||||
|
||||
@@ -1333,82 +1349,103 @@ class Canvas(object):
|
||||
self.surf = surf
|
||||
|
||||
def rect(self, color, rect, width=0):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.rect(self.surf,
|
||||
renpy.easy.color(color),
|
||||
rect,
|
||||
width)
|
||||
blit_lock.release()
|
||||
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.rect(self.surf,
|
||||
renpy.easy.color(color),
|
||||
rect,
|
||||
width)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
def polygon(self, color, pointlist, width=0):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.polygon(self.surf,
|
||||
renpy.easy.color(color),
|
||||
pointlist,
|
||||
width)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.polygon(self.surf,
|
||||
renpy.easy.color(color),
|
||||
pointlist,
|
||||
width)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
def circle(self, color, pos, radius, width=0):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.circle(self.surf,
|
||||
renpy.easy.color(color),
|
||||
pos,
|
||||
radius,
|
||||
width)
|
||||
blit_lock.release()
|
||||
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.circle(self.surf,
|
||||
renpy.easy.color(color),
|
||||
pos,
|
||||
radius,
|
||||
width)
|
||||
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
def ellipse(self, color, rect, width=0):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.ellipse(self.surf,
|
||||
renpy.easy.color(color),
|
||||
rect,
|
||||
width)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.ellipse(self.surf,
|
||||
renpy.easy.color(color),
|
||||
rect,
|
||||
width)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
|
||||
def arc(self, color, rect, start_angle, stop_angle, width=1):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.arc(self.surf,
|
||||
renpy.easy.color(color),
|
||||
rect,
|
||||
start_angle,
|
||||
stop_angle,
|
||||
width)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.arc(self.surf,
|
||||
renpy.easy.color(color),
|
||||
rect,
|
||||
start_angle,
|
||||
stop_angle,
|
||||
width)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
|
||||
def line(self, color, start_pos, end_pos, width=1):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.line(self.surf,
|
||||
renpy.easy.color(color),
|
||||
start_pos,
|
||||
end_pos,
|
||||
width)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.line(self.surf,
|
||||
renpy.easy.color(color),
|
||||
start_pos,
|
||||
end_pos,
|
||||
width)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
def lines(self, color, closed, pointlist, width=1):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.lines(self.surf,
|
||||
renpy.easy.color(color),
|
||||
closed,
|
||||
pointlist,
|
||||
width)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.lines(self.surf,
|
||||
renpy.easy.color(color),
|
||||
closed,
|
||||
pointlist,
|
||||
width)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
def aaline(self, color, startpos, endpos, blend=1):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.aaline(self.surf,
|
||||
renpy.easy.color(color),
|
||||
startpos,
|
||||
endpos,
|
||||
blend)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.aaline(self.surf,
|
||||
renpy.easy.color(color),
|
||||
startpos,
|
||||
endpos,
|
||||
blend)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
def aalines(self, color, closed, pointlist, blend=1):
|
||||
blit_lock.acquire()
|
||||
pygame.draw.aalines(self.surf,
|
||||
renpy.easy.color(color),
|
||||
closed,
|
||||
pointlist,
|
||||
blend)
|
||||
blit_lock.release()
|
||||
try:
|
||||
blit_lock.acquire()
|
||||
pygame.draw.aalines(self.surf,
|
||||
renpy.easy.color(color),
|
||||
closed,
|
||||
pointlist,
|
||||
blend)
|
||||
finally:
|
||||
blit_lock.release()
|
||||
|
||||
+228
-50
@@ -39,21 +39,17 @@ try:
|
||||
import _renpy
|
||||
except ImportError:
|
||||
_renpy = None
|
||||
|
||||
|
||||
# The factor we're scaling by.
|
||||
factor = 1.0
|
||||
|
||||
if ('RENPY_SCALE_FACTOR' in os.environ) or ('RENPY_SCALE_WIDTH' in os.environ):
|
||||
enable_scaling = True
|
||||
else:
|
||||
enable_scaling = False
|
||||
# Should we scale fast or scale good-looking?
|
||||
scale_fast = False
|
||||
|
||||
|
||||
##############################################################################
|
||||
# The scaling API that's used if we don't enable scaling.
|
||||
|
||||
|
||||
def init():
|
||||
return
|
||||
|
||||
# Gets the real pygame surface.
|
||||
def real(s):
|
||||
return s
|
||||
@@ -71,7 +67,6 @@ def real_bilinear(src, size):
|
||||
def real_transform_scale(surf, size):
|
||||
global real_transform_scale
|
||||
real_transform_scale = pygame.transform.scale
|
||||
|
||||
return real_transform_scale(surf, size)
|
||||
|
||||
# Loads an image, without scaling it.
|
||||
@@ -92,10 +87,60 @@ def image_save_unscaled(surf, dest):
|
||||
pygame.image.save(surf, dest)
|
||||
|
||||
|
||||
if _renpy:
|
||||
real_renpy_pixellate = _renpy.pixellate
|
||||
real_renpy_transform = _renpy.transform
|
||||
|
||||
def real_smoothscale(src, size, dest=None):
|
||||
"""
|
||||
This scales src up or down to size. This uses both the pixellate
|
||||
and the bilinear operations to handle the scaling.
|
||||
"""
|
||||
|
||||
width, height = size
|
||||
srcwidth, srcheight = src.get_size()
|
||||
iwidth, iheight = srcwidth, srcheight
|
||||
|
||||
if dest is None:
|
||||
dest = PygameSurface(size, src.get_flags(), src)
|
||||
|
||||
if width == 0 or height == 0:
|
||||
return dest
|
||||
|
||||
xshrink = 1
|
||||
yshrink = 1
|
||||
|
||||
while iwidth >= width * 2:
|
||||
xshrink *= 2
|
||||
iwidth /= 2
|
||||
|
||||
while iheight >= height * 2:
|
||||
yshrink *= 2
|
||||
iheight /= 2
|
||||
|
||||
if iwidth != srcwidth or iheight != srcheight:
|
||||
inter = PygameSurface((iwidth, iheight), src.get_flags(), src)
|
||||
real_renpy_pixellate(src, inter, xshrink, yshrink, 1, 1)
|
||||
src = inter
|
||||
|
||||
real_renpy_transform(src, dest,
|
||||
0, 0,
|
||||
1.0 * iwidth / width , 0,
|
||||
0, 1.0 * iheight / height,
|
||||
)
|
||||
|
||||
return dest
|
||||
|
||||
else:
|
||||
real_smoothscale = pygame.transform.smoothscale
|
||||
|
||||
smoothscale = real_smoothscale
|
||||
|
||||
|
||||
def init():
|
||||
global factor
|
||||
|
||||
global scale_fast
|
||||
|
||||
if 'RENPY_SCALE_FACTOR' in os.environ:
|
||||
factor = float(os.environ['RENPY_SCALE_FACTOR'])
|
||||
elif 'RENPY_SCALE_WIDTH' in os.environ:
|
||||
@@ -107,24 +152,26 @@ def init():
|
||||
|
||||
else:
|
||||
|
||||
factor = 1.0
|
||||
|
||||
# Automatically scale to screen if too small.
|
||||
|
||||
# info = pygame.display.Info()
|
||||
info = pygame.display.Info()
|
||||
|
||||
# factor = min(1.0,
|
||||
# 1.0 * info.current_w / renpy.config.screen_width,
|
||||
# 1.0 * info.current_h / renpy.config.screen_height)
|
||||
|
||||
# if factor <= 0:
|
||||
# factor = 1.0
|
||||
factor = min(1.0,
|
||||
1.0 * info.current_w / renpy.config.screen_width,
|
||||
1.0 * info.current_h / renpy.config.screen_height)
|
||||
|
||||
if factor <= 0:
|
||||
factor = 1.0
|
||||
|
||||
if factor != 1.0:
|
||||
print "Using scale factor of %f." % factor
|
||||
load_scaling()
|
||||
|
||||
|
||||
if 'RENPY_SCALE_FAST' in os.environ:
|
||||
scale_fast = True
|
||||
else:
|
||||
scale_fast = False
|
||||
|
||||
|
||||
scaling_loaded = False
|
||||
|
||||
@@ -143,6 +190,29 @@ def load_scaling():
|
||||
def real(s):
|
||||
return s.surface
|
||||
|
||||
|
||||
def same_size(*args):
|
||||
"""
|
||||
If all the surfaces in args are the same size, return them all
|
||||
unchanged. Otherwise, compute smallest width and height, and
|
||||
take subsurfaces of anythign bigger.
|
||||
"""
|
||||
|
||||
w = min(i.get_width() for i in args)
|
||||
h = min(i.get_height() for i in args)
|
||||
|
||||
size = (w, h)
|
||||
|
||||
rv = [ ]
|
||||
|
||||
for i in args:
|
||||
if i.get_size() != size:
|
||||
i = i.subsurface((0, 0) + size)
|
||||
|
||||
rv.append(i)
|
||||
|
||||
return rv
|
||||
|
||||
def scale(n):
|
||||
if n is None:
|
||||
return n
|
||||
@@ -164,7 +234,13 @@ def load_scaling():
|
||||
return rv
|
||||
|
||||
def surface_scale(full):
|
||||
return Surface(old_transform_scale(full, v2p(full.get_size())), wh=full.get_size())
|
||||
|
||||
if scale_fast:
|
||||
scaled = old_transform_scale(full, v2p(full.get_size()))
|
||||
else:
|
||||
scaled = real_smoothscale(full, v2p(full.get_size()))
|
||||
|
||||
return Surface(scaled, wh=full.get_size())
|
||||
|
||||
# Project a tuple from virtual to physical coordinates.
|
||||
def v2p(n):
|
||||
@@ -193,6 +269,8 @@ def load_scaling():
|
||||
func = getattr(PygameSurface, name)
|
||||
def rv(self, *args, **kwargs):
|
||||
return func(self.surface, *args, **kwargs)
|
||||
|
||||
return rv
|
||||
|
||||
class Surface(object):
|
||||
|
||||
@@ -211,7 +289,10 @@ def load_scaling():
|
||||
else:
|
||||
|
||||
w, h = what
|
||||
self.width, self.height = w, h
|
||||
w = int(w)
|
||||
h = int(h)
|
||||
self.width = w
|
||||
self.height = h
|
||||
|
||||
w = int(w * factor)
|
||||
h = int(h * factor)
|
||||
@@ -223,16 +304,68 @@ def load_scaling():
|
||||
sample = sample.surface
|
||||
|
||||
self.surface = PygameSurface((w, h), flags, sample)
|
||||
|
||||
self.virtx = 0
|
||||
self.virty = 0
|
||||
self.physx = 0
|
||||
self.physy = 0
|
||||
|
||||
|
||||
def transform_pos(self, (x, y)):
|
||||
"""
|
||||
Converts a virtual position into a physical one.
|
||||
"""
|
||||
|
||||
x0 = x + self.virtx
|
||||
y0 = y + self.virty
|
||||
|
||||
x0 *= factor
|
||||
y0 *= factor
|
||||
|
||||
x0 = int(x0)
|
||||
y0 = int(y0)
|
||||
|
||||
return (x0 - self.physx, y0 - self.physy)
|
||||
|
||||
def transform_rect(self, (x, y, w, h)):
|
||||
"""
|
||||
Converts a virtual rectangle into a physical one.
|
||||
"""
|
||||
|
||||
x0 = x + self.virtx
|
||||
y0 = y + self.virty
|
||||
x1 = x0 + w
|
||||
y1 = y0 + h
|
||||
|
||||
x0 *= factor
|
||||
y0 *= factor
|
||||
x1 *= factor
|
||||
y1 *= factor
|
||||
|
||||
x0 = int(x0)
|
||||
y0 = int(y0)
|
||||
x1 = int(x1)
|
||||
y1 = int(y1)
|
||||
|
||||
rv = (x0 - self.physx, y0 - self.physy, x1 - x0, y1 - y0)
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<scale.Surface %r %r>" % (self.get_size(), self.surface)
|
||||
|
||||
def blit(self, s, destpos, sourcerect=None):
|
||||
|
||||
if sourcerect is None:
|
||||
self.surface.blit(s.surface, v2p(destpos))
|
||||
self.surface.blit(
|
||||
s.surface,
|
||||
self.transform_pos(destpos))
|
||||
else:
|
||||
self.surface.blit(s.surface, v2p(destpos), v2p(sourcerect))
|
||||
self.surface.blit(
|
||||
s.surface,
|
||||
self.transform_pos(destpos),
|
||||
self.transform_rect(sourcerect))
|
||||
|
||||
def convert(self, *args):
|
||||
if args:
|
||||
@@ -254,7 +387,7 @@ def load_scaling():
|
||||
return self.surface.get_alpha()
|
||||
|
||||
def get_at(self, pos):
|
||||
x, y = v2p(pos)
|
||||
x, y = self.transform_pos(pos)
|
||||
w, h = self.surface.get_size()
|
||||
|
||||
return self.surface.get_at((min(x, w - 1), min(y, h - 1)))
|
||||
@@ -285,9 +418,6 @@ def load_scaling():
|
||||
def get_bitsize(self):
|
||||
return self.surface.get_bitsize()
|
||||
|
||||
def get_clip(self):
|
||||
return p2v(self.surface.get_clip())
|
||||
|
||||
def get_colorkey(self):
|
||||
return self.surface.get_colorkey()
|
||||
|
||||
@@ -303,13 +433,23 @@ def load_scaling():
|
||||
def set_alpha(self, alpha, flags):
|
||||
self.surface.set_alpha(alpha, flags)
|
||||
|
||||
def set_clip(self, rect):
|
||||
self.surface.set_clip(v2pplus(rect))
|
||||
pass
|
||||
|
||||
def subsurface(self, rect):
|
||||
return Surface(self.surface.subsurface(v2p(rect)), wh=rect[2:])
|
||||
|
||||
prect = self.transform_rect(rect)
|
||||
surf = self.surface.subsurface(prect)
|
||||
|
||||
rv = Surface(surf, wh=rect[2:])
|
||||
|
||||
vx, vy, vw, vh = rect
|
||||
px, py, pw, ph = prect
|
||||
|
||||
rv.virtx = vx + self.virtx
|
||||
rv.virty = vy + self.virty
|
||||
rv.physx = px + self.physx
|
||||
rv.physy = py + self.physy
|
||||
|
||||
return rv
|
||||
|
||||
def mustlock(self):
|
||||
return False
|
||||
|
||||
@@ -371,15 +511,19 @@ def load_scaling():
|
||||
pygame.display.get_surface = get_surface
|
||||
|
||||
old_image_load = pygame.image.load
|
||||
old_transform_scale = pygame.transform.scale
|
||||
|
||||
def image_load(*args, **kwargs):
|
||||
|
||||
full = old_image_load(*args, **kwargs)
|
||||
full = full.convert_alpha()
|
||||
|
||||
return surface_scale(full)
|
||||
|
||||
|
||||
pygame.image.load = image_load
|
||||
|
||||
old_transform_scale = pygame.transform.scale
|
||||
|
||||
def transform_scale(surf, size):
|
||||
|
||||
rv = old_transform_scale(surf.surface, v2p(size))
|
||||
@@ -389,6 +533,21 @@ def load_scaling():
|
||||
|
||||
pygame.transform.scale = transform_scale
|
||||
|
||||
old_transform_smoothscale = pygame.transform.smoothscale
|
||||
|
||||
def transform_smoothscale(surf, size, dest=None):
|
||||
|
||||
if dest is not None:
|
||||
rv = old_transform_smoothscale(surf.surface, v2p(size), dest.surface)
|
||||
else:
|
||||
rv = old_transform_smoothscale(surf.surface, v2p(size))
|
||||
|
||||
rv = Surface(rv, wh=size)
|
||||
|
||||
return rv
|
||||
|
||||
pygame.transform.smoothscale = transform_smoothscale
|
||||
|
||||
old_transform_flip = pygame.transform.flip
|
||||
|
||||
def transform_flip(surf, xbool, ybool):
|
||||
@@ -413,7 +572,7 @@ def load_scaling():
|
||||
|
||||
# Ignoring scale2x and chop. The former due to a pending api change,
|
||||
# the latter due to general uselessness.
|
||||
|
||||
|
||||
PygameFont = font_module.Font
|
||||
|
||||
class Font(object):
|
||||
@@ -457,13 +616,9 @@ def load_scaling():
|
||||
def get_descent(self):
|
||||
return int(self.font.get_descent() / factor)
|
||||
|
||||
# Ignored:
|
||||
#
|
||||
# set_at
|
||||
# Anything involving palettes.
|
||||
# Anything involving the parents of subsurfaces.
|
||||
# get_pitch, get_shifts, get_losses
|
||||
|
||||
def set_expand(self, value):
|
||||
self.font.set_expand(value * factor)
|
||||
|
||||
font_module.Font = Font
|
||||
|
||||
old_image_save = pygame.image.save
|
||||
@@ -517,7 +672,8 @@ def load_scaling():
|
||||
old_map = _renpy.map
|
||||
|
||||
def map(pysrc, pydst, r, g, b, a):
|
||||
old_map(pysrc.surface, pydst.surface, r, g, b, a)
|
||||
pysrc, pydst = same_size(pysrc.surface, pydst.surface)
|
||||
old_map(pysrc, pydst, r, g, b, a)
|
||||
|
||||
_renpy.map = map
|
||||
|
||||
@@ -525,7 +681,8 @@ def load_scaling():
|
||||
old_linmap = _renpy.linmap
|
||||
|
||||
def linmap(pysrc, pydst, r, g, b, a):
|
||||
old_linmap(pysrc.surface, pydst.surface, r, g, b, a)
|
||||
pysrc, pydst = same_size(pysrc.surface, pydst.surface)
|
||||
old_linmap(pysrc, pydst, r, g, b, a)
|
||||
|
||||
_renpy.linmap = linmap
|
||||
|
||||
@@ -567,8 +724,8 @@ def load_scaling():
|
||||
|
||||
|
||||
def alpha_munge(pysrc, pydst, srcchan, dstchan, amap):
|
||||
old_alpha_munge(pysrc.surface, pydst.surface,
|
||||
srcchan, dstchan, amap)
|
||||
pysrc, pydst = same_size(pysrc.surface, pydst.surface)
|
||||
old_alpha_munge(pysrc, pydst, srcchan, dstchan, amap)
|
||||
|
||||
_renpy.alpha_munge = alpha_munge
|
||||
|
||||
@@ -596,18 +753,27 @@ def load_scaling():
|
||||
old_blend = _renpy.blend
|
||||
|
||||
def blend(pysrca, pysrcb, pydst, alpha):
|
||||
old_blend(pysrca.surface, pysrcb.surface, pydst.surface, alpha)
|
||||
pysrca, pysrcb, pydst = same_size(pysrca.surface, pysrcb.surface, pydst.surface)
|
||||
old_blend(pysrca, pysrcb, pydst, alpha)
|
||||
|
||||
_renpy.blend = blend
|
||||
|
||||
old_imageblend = _renpy.imageblend
|
||||
|
||||
def imageblend(pysrca, pysrcb, pydst, pyimg, aoff, amap):
|
||||
old_imageblend(pysrca.surface, pysrcb.surface, pydst.surface,
|
||||
pyimg.surface, aoff, amap)
|
||||
pysrca, pysrcb, pydst, pyimg = same_size(pysrca.surface, pysrcb.surface, pydst.surface, pyimg.surface)
|
||||
old_imageblend(pysrca, pysrcb, pydst, pyimg, aoff, amap)
|
||||
|
||||
_renpy.imageblend = imageblend
|
||||
|
||||
old_colormatrix = _renpy.colormatrix
|
||||
|
||||
def colormatrix(src, dst, *args):
|
||||
src, dst = same_size(src.surface, dst.surface)
|
||||
old_colormatrix(src, dst, *args)
|
||||
|
||||
_renpy.colormatrix = colormatrix
|
||||
|
||||
|
||||
def draw_scale(o):
|
||||
if isinstance(o, int):
|
||||
@@ -643,7 +809,19 @@ def load_scaling():
|
||||
pygame.draw.aaline = draw_wrap(pygame.draw.aaline)
|
||||
pygame.draw.aalines = draw_wrap(pygame.draw.aalines)
|
||||
|
||||
# Smoothscale:
|
||||
|
||||
def smoothscale(surf, size, dest=None):
|
||||
if dest is not None:
|
||||
dest = dest.surface
|
||||
|
||||
rv = real_smoothscale(surf.surface, v2p(size), dest)
|
||||
|
||||
if rv is None:
|
||||
return rv
|
||||
else:
|
||||
return Surface(rv, wh=size)
|
||||
|
||||
# Now, put everything from this function's namespace into the
|
||||
# module namespace.
|
||||
|
||||
|
||||
@@ -813,6 +813,7 @@ class Text(renpy.display.core.Displayable):
|
||||
return True
|
||||
else:
|
||||
renpy.game.interface.timeout((self.slow_done_time + self.pause_length) - st)
|
||||
|
||||
if self.slow and self.style.slow_abortable and renpy.display.behavior.map_event(ev, "dismiss"):
|
||||
self.slow = False
|
||||
raise renpy.display.core.IgnoreEvent()
|
||||
@@ -1301,6 +1302,9 @@ class Text(renpy.display.core.Displayable):
|
||||
Called to call slow_done, and also to update slow_done_time.
|
||||
"""
|
||||
|
||||
if not self.slow:
|
||||
return
|
||||
|
||||
self.slow = False
|
||||
|
||||
if self.slow_done:
|
||||
|
||||
@@ -286,7 +286,6 @@ class Pixellate(Transition):
|
||||
|
||||
rdr = render(visible, width, height, st, at)
|
||||
|
||||
# No alpha support.
|
||||
surf = rdr.pygame_surface(False)
|
||||
|
||||
if surf.get_size() != self.surface_size:
|
||||
@@ -348,7 +347,7 @@ class Dissolve(Transition):
|
||||
|
||||
bottom = render(self.old_widget, width, height, st, at)
|
||||
top = render(self.new_widget, width, height, st, at)
|
||||
|
||||
|
||||
bottom_surface = bottom.pygame_surface(self.alpha)
|
||||
top_surface = top.pygame_surface(self.alpha)
|
||||
|
||||
@@ -356,7 +355,7 @@ class Dissolve(Transition):
|
||||
height = min(top.height, bottom.height)
|
||||
|
||||
def draw(dest, x, y):
|
||||
|
||||
|
||||
dw, dh = dest.get_size()
|
||||
|
||||
w = min(dw, width + x)
|
||||
@@ -371,6 +370,7 @@ class Dissolve(Transition):
|
||||
dest.subsurface((0, 0, w, h)),
|
||||
alpha)
|
||||
|
||||
|
||||
if self.alpha:
|
||||
|
||||
rv = renpy.display.render.Render(width, height)
|
||||
|
||||
+10
-5
@@ -58,7 +58,7 @@ def roll_forward_info():
|
||||
def in_rollback():
|
||||
return renpy.game.log.in_rollback()
|
||||
|
||||
def checkpoint(data=None):
|
||||
def checkpoint(data=None, keep_rollback=False):
|
||||
"""
|
||||
This creates a checkpoint that the user can rollback to. The
|
||||
checkpoint is placed at the statement after the last statement
|
||||
@@ -67,7 +67,8 @@ def checkpoint(data=None):
|
||||
statement.
|
||||
"""
|
||||
|
||||
renpy.game.log.checkpoint(data)
|
||||
if renpy.store._rollback:
|
||||
renpy.game.log.checkpoint(data, keep_rollback=keep_rollback)
|
||||
|
||||
def block_rollback():
|
||||
"""
|
||||
@@ -589,7 +590,7 @@ def pause(delay=None, music=None, with_none=None, hard=False):
|
||||
roll_forward = None
|
||||
|
||||
rv = renpy.ui.interact(mouse='pause', type='pause', roll_forward=roll_forward)
|
||||
renpy.exports.checkpoint(rv)
|
||||
renpy.exports.checkpoint(rv, keep_rollback=True)
|
||||
|
||||
|
||||
if with_none is None:
|
||||
@@ -684,10 +685,14 @@ def rollback():
|
||||
Rolls the state of the game back to the last checkpoint.
|
||||
"""
|
||||
|
||||
if not renpy.store._rollback:
|
||||
return
|
||||
|
||||
if not renpy.game.context().rollback:
|
||||
return
|
||||
|
||||
if renpy.config.rollback_enabled:
|
||||
renpy.config.skipping = None
|
||||
renpy.game.log.complete()
|
||||
renpy.game.log.rollback(1)
|
||||
|
||||
@@ -734,7 +739,7 @@ def take_screenshot(scale=None):
|
||||
|
||||
renpy.game.interface.take_screenshot(scale)
|
||||
|
||||
def full_restart(transition=False, label="_invoke_main_menu"):
|
||||
def full_restart(transition=False, label="_invoke_main_menu", target="_main_menu"):
|
||||
"""
|
||||
This causes a full restart of Ren'Py.
|
||||
"""
|
||||
@@ -742,7 +747,7 @@ def full_restart(transition=False, label="_invoke_main_menu"):
|
||||
if transition is False:
|
||||
transition = renpy.config.end_game_transition
|
||||
|
||||
raise renpy.game.FullRestartException((transition, label))
|
||||
raise renpy.game.FullRestartException((transition, label, target))
|
||||
|
||||
def utter_restart():
|
||||
"""
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ seen_session = { }
|
||||
# The set of statements we've ever seen.
|
||||
seen_ever = { }
|
||||
|
||||
# True if we're in the first interaction after a rollback.
|
||||
# True if we're in the first interaction after a rollback or rollforward.
|
||||
after_rollback = False
|
||||
|
||||
# Code that's run after the init code.
|
||||
|
||||
+9
-3
@@ -108,15 +108,21 @@ def image_exists(name, expression, tag):
|
||||
check_file_cache = { }
|
||||
|
||||
def check_file(what, fn):
|
||||
if fn in check_file_cache:
|
||||
return True
|
||||
|
||||
check_file_cache[fn] = True
|
||||
present = check_file_cache.get(fn, None)
|
||||
if present is True:
|
||||
return
|
||||
if present is False:
|
||||
report("%s uses file '%s', which is not loadable.", what.capitalize(), fn)
|
||||
return
|
||||
|
||||
if not renpy.loader.loadable(fn):
|
||||
report("%s uses file '%s', which is not loadable.", what.capitalize(), fn)
|
||||
check_file_cache[fn] = False
|
||||
return
|
||||
|
||||
check_file_cache[fn] = True
|
||||
|
||||
try:
|
||||
renpy.loader.transfn(fn)
|
||||
except:
|
||||
|
||||
+1
-1
@@ -307,7 +307,7 @@ def main():
|
||||
try:
|
||||
run(restart)
|
||||
finally:
|
||||
restart = (renpy.config.end_game_transition, "_invoke_main_menu")
|
||||
restart = (renpy.config.end_game_transition, "_invoke_main_menu", "_main_menu")
|
||||
save_persistent()
|
||||
|
||||
except game.QuitException, e:
|
||||
|
||||
+14
-5
@@ -601,13 +601,19 @@ class RollbackLog(renpy.object.Object):
|
||||
self.ever_been_changed = { }
|
||||
self.rollback_limit = 0
|
||||
self.forward = [ ]
|
||||
|
||||
# Did we just do a roll forward?
|
||||
self.rolled_forward = False
|
||||
|
||||
|
||||
# Reset the RNG on the creation of a new game.
|
||||
rng.reset()
|
||||
|
||||
def after_setstate(self):
|
||||
self.mutated = { }
|
||||
|
||||
self.rolled_forward = False
|
||||
|
||||
|
||||
def begin(self):
|
||||
"""
|
||||
Called before a node begins executing, to indicate that the
|
||||
@@ -639,6 +645,8 @@ class RollbackLog(renpy.object.Object):
|
||||
# save code.
|
||||
global mutate_flag
|
||||
mutate_flag = True
|
||||
|
||||
self.rolled_forward = False
|
||||
|
||||
def complete(self):
|
||||
"""
|
||||
@@ -738,7 +746,7 @@ class RollbackLog(renpy.object.Object):
|
||||
return None
|
||||
|
||||
|
||||
def checkpoint(self, data=None):
|
||||
def checkpoint(self, data=None, keep_rollback=False):
|
||||
"""
|
||||
Called to indicate that this is a checkpoint, which means
|
||||
that the user may want to rollback to just before this
|
||||
@@ -760,7 +768,10 @@ class RollbackLog(renpy.object.Object):
|
||||
# Otherwise, clear the forward stack.
|
||||
fwd_name, fwd_data = self.forward[0]
|
||||
|
||||
if (self.current.context.current == fwd_name and data == fwd_data):
|
||||
if (self.current.context.current == fwd_name
|
||||
and data == fwd_data
|
||||
and (keep_rollback or self.rolled_forward)
|
||||
):
|
||||
self.forward.pop(0)
|
||||
else:
|
||||
self.forward = [ ]
|
||||
@@ -768,8 +779,6 @@ class RollbackLog(renpy.object.Object):
|
||||
# Log the data in case we roll back again.
|
||||
self.current.forward = data
|
||||
|
||||
|
||||
|
||||
def block(self):
|
||||
"""
|
||||
Called to indicate that the user should not be able to rollback
|
||||
|
||||
+7
-7
@@ -44,14 +44,15 @@ _window = False
|
||||
# The window subtitle.
|
||||
_window_subtitle = ''
|
||||
|
||||
# Should rollback be allowed?
|
||||
_rollback = True
|
||||
|
||||
# config.
|
||||
_config = renpy.config
|
||||
|
||||
|
||||
class _Config(object):
|
||||
|
||||
def __init__(self, name):
|
||||
vars(self)["_name"] = name
|
||||
|
||||
def register(self, name, default, cat=None, help=None):
|
||||
setattr(self, name, default)
|
||||
_config.help.append((cat, name, help))
|
||||
@@ -60,7 +61,7 @@ class _Config(object):
|
||||
cvars = vars(_config)
|
||||
|
||||
if name not in cvars:
|
||||
raise Exception('%s.%s is not a known configuration variable.' % (self._name, name))
|
||||
raise Exception('config.%s is not a known configuration variable.' % (name))
|
||||
|
||||
return cvars[name]
|
||||
|
||||
@@ -68,7 +69,7 @@ class _Config(object):
|
||||
cvars = vars(_config)
|
||||
|
||||
if name not in cvars and renpy.config.locked:
|
||||
raise Exception('%s.%s is not a known configuration variable.' % (self._name, name))
|
||||
raise Exception('config.%s is not a known configuration variable.' % (name))
|
||||
|
||||
if name == "script_version":
|
||||
renpy.store._set_script_version(value)
|
||||
@@ -81,8 +82,7 @@ class _Config(object):
|
||||
else:
|
||||
delattr(renpy.config, name)
|
||||
|
||||
config = _Config("config")
|
||||
library = _Config("library")
|
||||
config = _Config()
|
||||
|
||||
_list = list
|
||||
_dict = dict
|
||||
|
||||
@@ -190,7 +190,7 @@ label marry:
|
||||
s "I know. So, will you marry me?"
|
||||
m "Ummm, of course I will. I've actually been meaning to ask you, but since you brought it up..."
|
||||
s "I know, but you are so indecisive, that I thought I'd take the initiative. "
|
||||
m "I guess... It's all all about asking the right question... at the right time."
|
||||
m "I guess... It's all about asking the right question... at the right time."
|
||||
|
||||
show sylvie2 giggle
|
||||
|
||||
|
||||
Reference in New Issue
Block a user