2007-11-19

PALib Palette Rotation

As PALib doesn’t include any functions for rotating a palette, here’s a function that will rotate the background palette on a given screen between two palette indexes. It will rotate in either clockwise or anti-clockwise order.


void RotatePalette(u8 screen, u8 start, u8 end, u8 direction) {
    if (direction == 0) {

        // Remember first colour
        u16 firstColour = BG_PALETTE[start + ((screen) << 9)];

        // Shuffle palette towards front
        for (u8 i = start; i < end; i++) {
            BG_PALETTE[i + ((screen) << 9)] = BG_PALETTE[i + 1 + ((screen) << 9)];
        }

        // Wrap end colour
        BG_PALETTE[end + ((screen) << 9)] = firstColour;
    } else {

        // Remember last colour
        u16 lastColour = BG_PALETTE[end + ((screen) << 9)];

        // Shuffle palette towards end
        for (u8 i = end; i > start; i--) {
            BG_PALETTE[i + ((screen) << 9)] = BG_PALETTE[i - 1 + ((screen) << 9)];
        }

        // Wrap start colour
        BG_PALETTE[start + ((screen) << 9)] = lastColour;
    }
}

To rotate the colours from indexes 10 to 20, for example, on screen 1 in clockwise order, use this:


while (1) {
    PaletteRotate(1, 10, 20, 1);
    PA_WaitForVBL();
}

To do the same thing in anti-clockwise order:


while (1) {
    PaletteRotate(1, 10, 20, 0);
    PA_WaitForVBL();
}

BG_PALETTE is an array that stores the colours for each 8-bit screen. In fact, it’s probably just a pointer to the palette memory. Anyway, the first 256 indexes are screen 0’s background palette. Indexes 1024 to 1279 are screen 1’s background palette.

Looking through the PALib code, it seems that the indexes between 256 and 511 are the sprite palette for the lower screen, and the same is true of the 256 indexes from 1280 for the upper screen. However, this system may have been removed at some point, as there appear to be two different implementations of sprite palettes, with this simpler method commented out.