Development Progress Report, week 47

For a change, this week I buckled down and tried to work on just one thing, rather than dozens.

Or, perhaps, it might be fairer to say that I started working on one thing, and just got kind of caught up in it. You know how that is.

The core of what I was working on was story-embeddable image-transitions. An overhaul to the image-widgets that would make it easy for it to handle a variety of transitions from one image to another. Dissolves/crossfades, swipes, rotations, etc, etc.

For which I needed a duration, a type, and a curve (I believe they’re also called easings).

I already had a bunch of the curves, which I use for a variety of visual effects.

In the end, after some experimentation to prove out the basic concept, I decided to use a polymorphic structure for my image transitions. An instance pointer to a base transition object that could be held by the image-widget and – if set – used to subvert the widget’s rendering process.

By encapsulating core functionality in the Transition base-class, I can dash off lots of different transitions that are nice and simple. eg:

trans_crossfader::trans_crossfader(Image* widget, msecs limit, std::function<float(float)> curve, SharedTexture newimage)
 : Transition(widget, limit, curve, newimage)
{
 _newimage->GetAlphaMod(&_original_alphamod);
}

trans_crossfader::~trans_crossfader()
{
 _newimage->SetAlphaMod(_original_alphamod);
}

bool trans_crossfader::Draw(msecs now, SDL_Renderer* rendertarget)
{

 if (complete(now, rendertarget, [&]() { _newimage->SetAlphaMod(255); }))
   return true;

 PaintBitmap(rendertarget, current_image());

 int alphalevel = proportional_progress(interval, _duration, 255, _curve);
 _newimage->SetAlphaMod(alphalevel);
 
 PaintBitmap(rendertarget, _newimage);

 WidgetManager::ptr()->need_update(); // Signal that we need more love
 return false;
}

And that’s the crossfade, nice and compact.

The results look great in-game, but a still-image isn’t going to show it off, and I don’t really have time to make up a video of the effects at the moment, so just imagine it looking very cool.

I did notice a bit of a gotcha in when I added the transitions to the story-file, however. They’re handled in a fashion not dissimilar to my other visual and audio effects. That means that they get collected and tagged to a line of story.

What’s the gotcha? That means that none of them actually happen until the engine produces a new line of text for output. If I select an visual/audio effect, change in background-music, change in image, or switch transitions – and change it again before the next line of story is output, the first change is lost (this is done to eliminate wasted cycles in screen-painting, which is important).

Technically, it’s a feature, not a bug. But it is something to watch out for. I should think about putting some tests in the story-compiler to try and trap circumstances where things don’t work like you expect, but that could turn out to be an awful lot of work.

This is probably one of those document-it-and-it-becomes-a-feature things. It’s working as designed, just not as you might always expect.

And, surprisingly, that’s about all I have for this week. Yes, I also added a widget-motion framework at the beginning of the week, but that’s just a prototype for later on. I’ll probably talk about that more when the time comes to finish it off.

Happy gamedevving!