Sprite Plotter

Discussion in 'Engineering & Reverse Engineering' started by MarkeyJester, Nov 13, 2012.

  1. MarkeyJester


    A D V A N C E Resident Jester
    I posted this quite a long time ago on SSRG, and due to a bug which I've recently fixed, I had to update it and make a bump. Seeing as I haven't actually posted it here yet, I'm going to now, so here's a copy paste for you...

    Right, this is for all of those sprite artists out there, one of the biggest tedious tasks of putting a new player/character (or even as simple as a design change), has to be “importing the art”. Now there are a few tools available, with the most recommended tool being SonMapEd, however, due to its “Import Sprite Sheet” option being incomplete, all sprites require being imported one by one, and the problem here is time consumption.

    As members of the community we strive to find new and innovative ways of getting awesome work done the quickest and professional, and we're learning every year to improve, self-correct, and find alternative solutions to problems, and today I release a two weeks’ worth of work of a tool to contribute to this growth.

    Today I give you “Sprite Plotter”:


    This tool is designed to read almost any sprite sheet (within reason), and import all of the sprites correctly (in order of the sheet). Of course, that's not to say it'll wipe your arse for you, it'll just do the tedious task of importing. Here's how it works:

    Step 01 – Selecting a Sprite Sheet

    When you run the program, the first thing it'll ask you to provide is a sprite sheet (this must be a 24-bit bitmap image), here is an example of a good sprite sheet to import:

    Dragon Ball Z

    Notice how all sprites have a certain seperation space? That is necessary, the tool will generate a box around each sprite, and if any of the boxes touch, it will assume that the sprites are together as one major sprite, and it will fuse them.

    Step 02 - Selecting a palette

    The next thing it'll ask for is a palette, now, there are three things you can do, if you do not have a palette at all, you may click cancel, the program will try to generate one out of the sheet as best as it can. If you would rather not have the program generate a palette and would like to provide a pre-made one, then there are two types you can select:

    1. A "binary" file - this is in the Mega Drive's palette format, you can open up a binary palette that's already made
    2. A "bitmap" file - this is a simple 24-bit bitmap image of a palette of colours, it is important to understand that the program is sensitive when it comes to reading colours from bitmaps, here is an example of a "bitmap" palette that is suitable for the program:

    Step 03 - Selecting a Sprite Distance


    Now, you might have a sheet that has a sprite with pieces that are not attatched, but you would like the program to read as one major sprite, for example:


    A dialog box will pop up, requesting that you type in a distance, by default 1 will be there, you may click OK to proceed if you wish, what that number is, is how many pixels away from the sprite (on X and Y axis) the "touch box" has to be. As I mentioned earlier, each sprite will be given a square box around it, and if any of them touch, they will be fused together as 1 sprite, well, this will allow you to expand that box a certain number of pixels away from each sprite, allowing you to fuse certain untouching sprites together.

    THIS IS IMPORTANT THOUGH SO PLEASE READ, you need to get this right, this "touch box" WILL apply to every sprite, so be VERY sure that all sprites you don't want to fuse together are seperated on your sheet by a longish distance, here's an example of a sheet with a decent distance between sprites:

    Monkey Sheet Seperated

    That sheet has a shadow under the monkey that is about 14 (hex) pixels away from the monkey, so I have made sure that all other sprites are moved away from each other by more than 14 pixels, and then typed in 14 in that dialog box, my program will now know that the shadow should be fused with the monkey, but the other monkeys shouldn't be fused with each other.

    1 pixel should be fine for sheets that don't have untouching pieces though. But you do still need to make sure every sprite is not touching each other within the "touch box".

    Step 04 - Sprite Control


    Next up, in this dialog box you'll get to choose which palette line you want the sprites to advance themselves to, whether they're flipped/mirrored sprites, and if they are high/low plane, and if you would like it to setup and dump pattern load cues to go with the mappings, there's also an option to make the first sprite automatically null (Sonic sprites in Sonic games usually have a first null sprite for flashing when getting hurt).

    Once you have made your selection, click OK.

    Step 05 - Selecting a script

    So I don't bore you with the details, I'll keep this simple, there are 5 scripts that come with the program, each one for a different game's format, the ones available are Sonic 1, Sonic 2, Sonic 3, Sonic 3 (For non-character objects PLC) and Sonic Crackers. Select the one you require to import the sheet to.

    The reason why I've made scripts for each game, is so that those of you who have a slightly different format, or those who have their own engine/game, you can make your own script, it is limited, but not too limited, and there's a table in each one explaining the format.

    Step 06 - PLC Lables (Sonic Crackers Only)

    If you did not select Sonic Crackers, then you may skip to step 07, this is for Sonic Crackers Only.

    Because of the nature of Sonic Crackers' format being so different, instead of having a tile count and a tile "add" address like the other Sonic games, it has a DMA styled PLC, which contains the EXACT location fo the sprite art on the ROM, and the EXACT VRAM address to dump to, I have compensated for this by setting up the script in Sonic Crackers in such a way that the "O" and "D" flags will prompt you to type in your own "Lable" or "$035F2lalalaexample" address for the "Destination" VRAM and sprite art "Source", the program will place the Art add address in first and the will place your lable in after a "+" symbol, an example if you typed in "SonicArtLoc" as the source lable and "$F000" as the VRAM lable:

    Code (Text):
    1. P34458294_0001:
    2.         dc.w    $F000
    3.         dc.l    $97000000+((SonicArtLoc/2)&$7FFFFF)
    4.         dc.w    $0000+$F000,$FFFF
    6. P34458307_0002:
    7.         dc.w    $F000
    8.         dc.l    $970000F0+((SonicArtLoc/2)&$7FFFFF)
    9.         dc.w    $0000+$F000,$FFFF
    11. P34458307_0003:
    12.         dc.w    $E000
    13.         dc.l    $970001E0+((SonicArtLoc/2)&$7FFFFF)
    14.         dc.w    $0000+$F000,$FFFF
    Step 07 - Saving your files

    If Successfully imported, it'll ask you to save up to 4 items:

    1. Art file (Mega Drive binary 8x8 tiles)
    2. Palette file (Mega Drive CRAM binary palette)
    3. Mappings file (Assemblable mapping source code)
    4. PLC file (Assemblable pattern load cues source code)
    Now like I said, this tool doesn't do "everything" for you, when importing these sprites, it centred all of them, because it cannot know what sprites you want positioned where and how (it isn't human like us), so you may want to open up these files with SonMapEd or something and adjust them to your liking.

    The animation scripts will also need fixing (that's if the order of the sprites on your sheet does not match the order of the original set), but animation scripts are a piece of piss to work with anyway.

    What you use them for is up to you.

    Bug Reporting

    If you find any bugs like crashing, or the sprite sheet not importing correctly, then please be sure that you follow my recommendations first:

    1. Make sure the sprites are at a decent enough distance away from each other so my tool knows what is seperate.
    2. Make sure you have selected the right format script (it's no good selecting Sonic 2 if you wanted Sonic 1).
    3. Make sure the palette file (if you've selected one) is correct.
    4. If you opened up the output map and plc files using SonMapEd and it doesn't show up correctly, then this is likely a bug with SonMapEd, it doesn't read source files correctly and if there are any specific numbers in a specific order in the lable names, then it simply won't read it correctly, to get around this, I recommend either manually changing the lable names to something SonMapEd likes, or running it through sprite plotter again, my tool will output with a different set of lable names that SonMapEd might not be so cuntish about...
    If none of the above is the reason, then be sure to report it, make sure you include the sprite sheet you used and palette (if you selected one) and please be sure to include the script file you selected (so I can take a look at it and see if it's been modified incorrectly, etc). If it's a bug with my program, I might look into fixing it, depending on how I feel, but no promises.
  2. Hitaxas


    Retro 80's themed Twich streamer Member
    Holy crap. This is something I've wanted for a long time. It's frustrating when I'd import a sprite, and have to manually edit the mappings to fit something in that wasn't attached, and therefore ported as a separate sprite. I will be using this when I get back into importing artwork again. :)
  3. Cinossu


    London, UK
    Sonic the Hedgehog Extended Edition
    Markey, I love you. One of the most tedious things ever with spritework is actually splitting the art into (optimised) segments, then into each component 8x8 tile in order, then actually sorting out the segments into the correct format, etc. etc.

    I will be giving this a lovely run-through later and try it out on a full-scale sheet of a character. Should be interesting to see how much it speeds up the process, to say the least.

    Someone should write up a wiki article for this one, and I'll possibly make it later if nobody else has by then. Tempted to front page it too, considering how damn useful something like this is.
  4. Retroman


    This is amazing! Jester, you are the man!

    I always wanted something like this as this could make importing sprites much less time-consuming and 100% accurate!

    I will try to use this with my Sonic Advance Sonic Worlds Multimedia Fusion 2 Project porting hobby work. Will try this.

    Actually, no, this is only for Sega Genesis sprite porting.

    I only wish there's a program to export sprite sheets into frames.
  5. MarkeyJester


    A D V A N C E Resident Jester
    If you could give me a more thorough example of what you're looking for, then I can modify Sprite Plotter to do what you would like, by the sound of things, you want something that's a lot more easier to make than what's above, in which case I'd be more than happy to make something specific for you.

    EDIT: here's a little something I've made based on what you said in your post:

    Sprite Plotter Raw

    This one is a raw version, meaning it won't output the data in Mega Drive genesis format, but rather output the sprites as seperate bitmap files in one folder, to use this, it will ask you to select a sprite sheet (bitmap 24-bit obviously), it won't ask for a palette, it will ask for a seperation distance (see the tutorial for details), and once you've selected a distance, it will find, and split all of the sprites in the sprite sheet into seperate bitmap files inside a folder named "Frames" in the same directory as the program. No palettes required, no scripts, no mappings/PLC, just frames in seperate bitmap files. I hope that's what you meant...

    It's actually kinda cool, I was able to split this entire sheet of pokemon with it:

  6. dsrb


    MarkeyJester delivers – even in response to misunderstandings :v:
  7. Retroman


    Thank you so much! This is a very good program, and I really appreciate your work!

    MarkeyJester once again delivers! 10/10

    Can we promote MarkeyJester to God-Like status? :v: