2007-12-05

Fast Horizontal Line Drawing and Other Things

Based on Jeff’s discovery of DMA_Force, here’s a hardware-accelerated 16-bit horizontal line drawing routine:


void drawHorizLine(u8 screen, s16 x, s16 y, s16 width, u16 colour) {

    if (width > 0) {
        // Draw first pixel
        PA_DrawBg[screen][x + (y << 8)] = colour;

        if (width - 1 > 0) {
            // Duplicate pixel
            DMA_Force(PA_DrawBg[screen][x + (y << 8)], (PA_DrawBg[screen] + x + (y << 8) + 1), (width - 1), DMA_16NOW);
        }
    }
}

It could be improved upon by pre-calculating the (x + (y << 8)) value, but I’ll leave that as an exercise for the reader (not that I’m lazy or anything).

I’ve integrated this into Woopsi, replacing the existing pixel-plotting line routine and a section of the filled rectangle code. It seems to go a little faster, at least in DeSmuMe under VMWare Fusion.

I’ve fixed the problem with the _decorationCount getting screwed. I started pulling Woopsi apart in order to find the bug - commenting out first the demo code, and then chunks of the GUI code. Eventually I decided that there wasn’t a bug in the code - the “getDecoration()” function was returning the wrong value. Weird. Of course, what I’d done was forget to initialise the _flags.decoration value (despite having a vivid memory of writing that code - maybe I dreamt it). Hopefully I’ve uncommented everything correctly…

Also changed the boolean getter naming convention. Previously, I was using “getXXX()” (as in “getDecoration()” above). Not the best system, really. I think I decided to use it because I was trying to adhere to an explicit separation between setters (called “setXXX()”) and getters (called “getXXX()”). C# has spoiled me and I’m so used to being able to say “object.IsXXX = true” that I felt it important to draw the distinction between putting things into an object and getting them back out again. However, it just made the functions’ meaning less than obvious. All boolean getters are now called “isXXX()” (so “getDecoration()” is now called “isDecoration()”).

Last thing for this post - SourceForge seems to be down, so I can’t update the SVN repository or access the bug list. Foiled again.

Comments

Jeff on 2007-12-05 at 22:03 said:

Turn:

if (width) …

into

if (width--)

and you can replace the two ‘width-1’ computations with ‘width’

ant on 2007-12-06 at 00:12 said:

Now there’s a thought. Done!