Compare commits

...

25 Commits

Author SHA1 Message Date
Tom Rothamel 693cf9f8c9 Version bumps for 6.9.2 2009-05-05 02:09:59 -04:00
Tom Rothamel 35c2ec5a83 Fixed a bug that could cause it to take two tries to define a joystick
button.
2009-05-02 23:31:13 -04:00
Tom Rothamel 3b60efd744 Update changelog.
Fix dequeue to have correct semantics.
2009-05-02 23:05:27 -04:00
Tom Rothamel daac5d8ebf Doing anything besides rollforward during rollback now terminates
rollback.

Queueing music immediately after a play statement now allows the first 
track from the play statement to play.
2009-05-02 22:41:04 -04:00
Tom Rothamel 1fab6d8707 Prevent slow_done from being repeatedly called. 2009-05-02 21:32:24 -04:00
Tom Rothamel aaff11668a Catch errors when saving screenshots. 2009-05-02 20:21:18 -04:00
Tom Rothamel 536341a819 Fix problem with window icon on 16bit screen. 2009-05-01 22:16:29 -04:00
Tom Rothamel b9c468e446 Fix repeate word in the question. 2009-04-27 07:50:09 -04:00
Tom Rothamel 03edec9785 Fix a bug with Container. 2009-04-24 19:22:04 -04:00
Tom Rothamel da70a85d75 Bring in changes from staging. 2009-04-23 00:53:14 -04:00
Tom Rothamel 4ba170b8d8 Bring in features from mainline. 2009-04-23 00:52:04 -04:00
Tom Rothamel 72ae15c635 Back out some changes that lead to a slowdown in dissolve. 2009-04-22 23:16:49 -04:00
Tom Rothamel 1179066dda Bump version to 6.9.1h 2009-04-20 23:05:00 -04:00
Tom Rothamel 62d0093bee End skipping on rollback. 2009-04-20 23:01:10 -04:00
Tom Rothamel 55c0d3b4a7 Convert to alpha before smoothscaling windows icon. 2009-04-19 16:03:42 -04:00
Tom Rothamel 92014eafdd Fix a bug with the icon on windows. 2009-04-19 16:01:55 -04:00
Tom Rothamel b1be4c8ed4 The library alias for config has been removed. 2009-04-19 02:00:53 -04:00
Tom Rothamel 06f36dd8d1 Prevent infinite loop in error handling. 2009-04-19 01:31:26 -04:00
Tom Rothamel 3a15f5c717 6.9.1g 2009-04-18 23:24:22 -04:00
Tom Rothamel 031f3338b1 Scale screenshot using an alpha image. 2009-04-17 19:44:00 -04:00
Tom Rothamel 66125b2e10 Bump version. 2009-04-16 21:03:48 -04:00
Tom Rothamel e6becffc4c Blacklist obsolete file formats.
Properly deallocate VideoStates of short/invalid media files.
2009-04-16 19:31:50 -04:00
Tom Rothamel d281e57879 Fix reported bugs.
Make scaling more accurate.
2009-04-16 18:04:10 -04:00
Tom Rothamel 5196a970a0 Channels now have a default tightness. 2009-04-15 12:12:40 -04:00
Tom Rothamel efcbc92e7a Reimplement smoothscale in terms of _renpy.pixellate and _renpy.bilinear. 2009-04-15 01:10:13 -04:00
23 changed files with 260 additions and 112 deletions
+40
View File
@@ -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
-------------------
+3
View File
@@ -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
@@ -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):
+1 -1
View File
@@ -1,3 +1,3 @@
init -999:
$ config.script_version = (6, 9, 1)
$ config.script_version = (6, 9, 2)
+25 -25
View File
@@ -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);
+27 -13
View File
@@ -111,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;
@@ -172,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.
*/
@@ -443,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;
@@ -491,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;
@@ -1089,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
View File
@@ -14,6 +14,7 @@ except:
# 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
+1 -1
View File
@@ -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.1d"
version = "Ren'Py 6.9.2a"
script_version = 5003000
savegame_suffix = "-LT1.save"
+39 -16
View File
@@ -181,7 +181,7 @@ class Channel(object):
This stores information about the currently-playing music.
"""
def __init__(self, name, default_loop, stop_on_mute):
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.
@@ -237,6 +237,14 @@ class Channel(object):
# 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?
@@ -337,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)
@@ -376,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:
@@ -420,6 +437,7 @@ class Channel(object):
of seconds. Also clears any queued music.
"""
self.keep_queue = 0
self.dequeue()
if not pcm_ok:
@@ -431,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
@@ -439,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)
@@ -496,11 +519,11 @@ all_channels = [ ]
channels = { }
def register_channel(name, mixer=None, loop=None, stop_on_mute=True):
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, stop_on_mute)
c = Channel(name, loop, stop_on_mute, tight)
c.mixer = mixer
all_channels.append(c)
channels[name] = c
+2 -4
View File
@@ -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
+2 -3
View File
@@ -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):
+17 -12
View File
@@ -699,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)
@@ -1015,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)
+5 -4
View File
@@ -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
@@ -775,7 +776,7 @@ class Scale(ImageBase):
if self.bilinear:
try:
renpy.display.render.blit_lock.acquire()
rv = pygame.transform.smoothscale(child, (self.width, self.height))
rv = renpy.display.scale.smoothscale(child, (self.width, self.height))
finally:
renpy.display.render.blit_lock.release()
else:
@@ -820,7 +821,7 @@ class FactorScale(ImageBase):
if self.bilinear:
try:
renpy.display.render.blit_lock.acquire()
rv = pygame.transform.smoothscale(surf, (width, height))
rv = renpy.display.scale.smoothscale(surf, (width, height))
finally:
renpy.display.render.blit_lock.release()
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1278,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
+64 -6
View File
@@ -67,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.
@@ -88,6 +87,54 @@ 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():
@@ -191,7 +238,7 @@ def load_scaling():
if scale_fast:
scaled = old_transform_scale(full, v2p(full.get_size()))
else:
scaled = old_transform_smoothscale(full, v2p(full.get_size()))
scaled = real_smoothscale(full, v2p(full.get_size()))
return Surface(scaled, wh=full.get_size())
@@ -468,12 +515,11 @@ def load_scaling():
def image_load(*args, **kwargs):
full = old_image_load(*args, **kwargs)
full = full.convert_alpha()
if full.get_bitsize() < 24:
full = full.convert() # Less than 24 bits means no alpha.
return surface_scale(full)
pygame.image.load = image_load
old_transform_scale = pygame.transform.scale
@@ -526,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):
@@ -763,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.
+4
View File
@@ -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:
+3 -3
View File
@@ -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)
+4 -3
View File
@@ -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
@@ -68,7 +68,7 @@ def checkpoint(data=None):
"""
if renpy.store._rollback:
renpy.game.log.checkpoint(data)
renpy.game.log.checkpoint(data, keep_rollback=keep_rollback)
def block_rollback():
"""
@@ -590,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:
@@ -692,6 +692,7 @@ def rollback():
return
if renpy.config.rollback_enabled:
renpy.config.skipping = None
renpy.game.log.complete()
renpy.game.log.rollback(1)
+1 -1
View File
@@ -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.
+14 -5
View File
@@ -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
+3 -7
View File
@@ -53,9 +53,6 @@ _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))
@@ -64,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]
@@ -72,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)
@@ -85,8 +82,7 @@ class _Config(object):
else:
delattr(renpy.config, name)
config = _Config("config")
library = _Config("library")
config = _Config()
_list = list
_dict = dict
+1 -1
View File
@@ -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