Code Swap Meet

Hey everybody! I just created a script that may be useful, and thought I’d share with the community in the hopes that maybe you will find it useful as well. I’d like to make this a general thread of other useful snippets, so feel free to post any others here. (I’m aware of a previously existing thread, but it was suggested I make a new one instead of performing necromancy).

Much of this code is borrowed from @FManga’s existing conversion scripts in femtoIDE. It takes any *.pal files in the project’s root folder and converts them to header files usable with TAS (and, likely, PokittoLib in general).

//!MENU-ENTRY:Convert Palettes
//!MENU-SHORTCUT:C-M-p

// This script looks in the root project folder and converts any palette files (JASC format) into palettename.h.
// Press Ctrl+Enter to run this script or use the menu.

let palettes = dir(".")
    .filter( (file) => file.endsWith('.pal') )
    .forEach( (file) => {
        let filename = path.basename(file).split('.')[0];
        let filetext = read(`${file}`);
        let lines = filetext.split('\n');

        if (lines[0].replace(/\s+/g, '').trim() != 'JASC-PAL') { return; }
        if (parseInt(lines[2]) > 256) { return; }

        let output = '#pragma once\n\n';
        output += `inline const uint8_t ${filename}[] = {\n`;

        for (let i=3; i<parseInt(lines[2])+3; i++) {
            let color = lines[i].replace(/\r|\n/g, '').trim().split(' ');
            output += `    ${color[0]},${color[1]},${color[2]},\n`
        }

        output += '};'
        write(`${filename}.h`, output);
        log(`Palette conversion to ${filename}.h complete!`);
    });

Save the above script to your project’s scripts folder as PaletteConverter.js and use it just like the other converters. You can either use the hotkey provided (C-M-p) or run it from the Scripts menu.

The palette file must be in JASC format and have the extension .pal. Any palette on Lospec will contain a JASC format download link, and femtoIDE itself contains (I think) every palette that’s bundled with Aseprite in [femtoIDE folder]/javacompiler/femto/palette/ if you need some.

Once you convert the palette to a .h file, you’ll still need to do a few things:

  1. Update project.json with the path to your palette. To point at the project path, under “PNGFlags” edit the palette entry to say palette=${projectPath}/palettename.h.
  2. Include the new palette. This is as simple as adding #include "palettename.h" in your main.cpp.
  3. Load the palette. If you’re using the TAS template, replace PD::loadRGBPalette(miloslav); with PD::loadRGBPalette(palettename);.
  4. Make sure your graphics conform to your palette. If you’ve already been using your palette to create your sprites/tiles in the first place, you’re good to go! Otherwise, you can load a palette in Aseprite thusly:

aseprite-force-palette

The steps above are:

  1. Make sure your image is in RGB color mode. If you go directly from indexed->indexed, the colors will map according to index and probably look whacked out.
  2. Load your palette.
  3. Switch to Indexed mode. Colors will be matched as closely as possible to your palette automatically.
  4. Save!

I meant this to be a quick snippet, but now it’s a small tutorial on loading custom palettes. Happy coding! :stuck_out_tongue:

8 Likes

Good tutorial!

Since it’s a code swap, here’s a snippet. I’ll add some more later.

Z-sorting your TAS sprites

This demonstrates the general idea, using the Y value for Z sorting (sprites higher up are behind those that are closer to the bottom of the screen).
Feel free to swap in a proper algorithm or std::sort. Note that Sprite here is not the same one from sprites.h, so you might want to put this in its own cpp file to avoid the conflict. Or use a namespace.


struct Sprite;
using draw_t = void (*)(uint8_t *line, Sprite &sprite, int y);
struct Sprite {
    int16_t x, y;
    const void *data;
    draw_t draw;
    uint8_t maxY;
    uint8_t b1, b2, b3;
};
extern Sprite spriteBuffer[PROJ_MAX_SPRITES];
extern uint32_t spriteBufferPos;

void sortSprites(){
    if(!spriteBufferPos)
        return;
    Sprite tmp;
    for(u32 i=0; i<spriteBufferPos - 1; ++i){
        if(spriteBuffer[i].y > spriteBuffer[i+1].y){
            tmp = spriteBuffer[i];
            spriteBuffer[i] = spriteBuffer[i+1];
            spriteBuffer[i+1] = tmp;
            if(i > 0) i -= 2;
        }
    }
}
3 Likes