2007-04-11

Slideshow - Optimisation and Bugfixing

(Written 01/04/2007)

Back to it again. Today I’m altering the slideshow so that it allows the user to skip to the next image or to the end of the slideshow, by either tapping the touchscreen or pushing a button. Should be fairly simple, but the fading process makes it a little more complex.

When the fade calculations are occurring, the slideshow is in a subroutine that can take a few seconds to run. We need to remember if an event has occurred that could cause the slideshow to skip during this routine so that there isn’t a few seconds of “dead time” during which the user can’t interact with the DS. We can’t fade out immediately because of the need to do the precalculations, so we just remember the event and process it when we get back to the main loop.

Another update I’m working on is using the memcpy() command to output to the screen instead of drawing each pixel one by one. I’m surprised that the PALib doesn’t already use this - having done some tests, it seems that using memcpy() to output an image in one go is significantly faster than looping through the array of pixels.

(Some time later)

It seems that the “dead time” solution was no good. Although it worked perfectly, the fact that the system was essentially locked up whilst the fade frames were being calculated, nothing else could happen at the same time. This isn’t a problem on a normal system, but the DS has two screens - we can’t just have a slideshow on the top screen and nothing on the bottom one.

What I’ve done instead is calculate a single frame of the fade every time the main slideshow play() function gets called, until all frames have been calculated. This means that the DS doesn’t lock up for a significant amount of time. It would be possible to change the function so that only half of a fade frame is calculated each time the play() function is called, which would result in the function taking less than a frame to run, but the problem with this is that each image would therefore be on-screen for much longer whilst the extra steps are runnng.

(Some more time later)

Actually, scratch that. I’ve implemented the half-frame calculation system to enable me to have something going on on the bottom screen whilst the slideshow is running. I’ve also stripped out the “skip to end” functionality, because there’s no practical way to make it work with all of the caching I’m doing.

(Some more time later)

I’ve now modified it so that I can specify exactly how much of each fade frame to generate in each loop by changing just one variable. Whacking it down to ¼ fade frames per VBL, reveals that the real speed problem now is probably more to do with drawing the bitmaps than generating the fade images, so I’m keeping it at ½ fade frames per VBL.

I’ve also discovered and, excitingly, fixed, a bug in the PALib. The “Pad.Held.Anykey” function wasn’t checking the status of the Y button. An awful lot of complicated digging into the internals of PALib revealed this bit of code:

type.Anykey = (!(!((pad&2047))));

This just checks if any single bit in the button bitmask is set, and returns 1 if so (0 otherwise). However, the Y button has a value of 2048, so its bit is masked out. Changing it to this fixed the problem:

type.Anykey = (!(!((pad&4095))));

I’ve submitted the bug to the PALib forum; let’s see what happens!