Repository
https://github.com/spiiin/CadEditor
CadEditor is the universal level editor for NES/SMD/SNES/Game Boy games, the introduction of the project was here
Introduction
New update of CadEditor project:
Tool for search levels data in GameBoy ROM files. It's implemented as Lua-script for emulator Bizhawk, as the best emulator for Game Boy supporting scripting. (commit)
Plugin for building GameBoy graphics - now CadEditor supports configs for Game Boy games (pull request). Example of the config file for Darkwing Duck [Game Boy version] included.
Battletoads Race Editor plugin added. This is an example of the plugin for the specific level of the game, but it can be upgraded to generic table editor, with the ability to choose, how data can be saved, loaded, displayed and edited (pull request).
Post Body
Game Boy graphics
CadEditor supported graphics for NES/SMD platforms before, and now it supports Game Boy graphics also.
Game Boy has pretty simple graphics format, described here, it supports only four colors (2 bits per pixel). It was not very hard to create the plugin, that will build tiles of this types from a predefined palette and dump of PPU memory, made with emulator Bizhawk (almost every modern emulator allows to create memory dumps).
For example, there is dump of PPU memory for game Darkwing Duck, level 1.
Dump starts from 0x8800 address of PPU and contains 128 8x8 tiles (at top half), used for building level background. It can be viewed with console graphics editors, like Tile Layer Pro
Real games rarely used only tiles, more ofter they describe blocks - structures from several tiles. One way to find it - disassemble the game code and analyze, how blocks built.
But I choose another method with no need to use debugger and disassembler. With modern emulators, the user can automate actions with lua scripts, so I decide to make lua script, that will corrupt every byte of ROM-file and see, does it change the picture on the screen or not.
I already checked this method with NES emulators like Fceux and Mesen. Example of usage this method:
So I ported Autocorrupter script for Bizhawk emulator with Game Boy core.
The big disadvantage of this emulator is the impossibility to checks exactly bytes in ROM changed between two saves. Because of this, the script needs to check every byte in ROM - it takes 10-15 minutes until it finished on an average machine, instead of 1-2 minutes for emulators, that supports code-data logging from lua-scripts. I hope, this feature will be added in the next version of Bizhawk (I contacted one of the developers, so they inform about the problem).
But even without optimization, it's not a problem to wait 15 minutes, you can just drink a cup of tea, before checking results. The script saves them in "snaps" folder. Each screenshot has a name with the address of the corrupted byte.
Often, it's enough to see on these screenshots for the understanding level format of the game. For example, there are 3 screenshots from corrupting results of the Darkwing Duck game:
Here, we can see, that game describe level with blocks of size 16x16 (2x2 tiles). One byte change leads to change one block, and blocks are described per rows. With the analyze of the neighboring screenshots, we also can calculate, that game describe level by screens of size 10x8 blocks and address of the first screen is 0x8453
What is really good is that the description of the blocks themselves also found with Autocorrupter. Looks at the screenshot made after corrupting byte 0xB7EB:
One byte change leads to a change of every the same block of the screens. If you can't see block here, wait to the next screenshot from CadEditor, where this blocks can be marked with the axis.
For now, it's all required information for made config file:
using System;
//css_include shared_settings/BlockUtils.cs;
public class Data
{
public OffsetRec getScreensOffset() { return new OffsetRec(0x8453, 20 , 10*8, 10, 8); } //address of the first screen, screens count and sizes
//...
public bool isUseGbGraphics() { return true; } // we use plugin for building Game Boy graphics
public bool isBuildScreenFromSmallBlocks() { return true; } //no macro blocks defined, screen built with blocks 2x2
public OffsetRec getBlocksOffset() { return new OffsetRec(0xB7E7, 1 , 0x1000); } //offset of blocks' description
public int getBlocksCount() { return 256; } //blocks count
//standard function for saving/loading block in ROM file (linear description, not additional information bytes)
public GetBlocksFunc getBlocksFunc() { return BlockUtils.getBlocksLinear2x2WithoutAttribs;}
public SetBlocksFunc setBlocksFunc() { return BlockUtils.setBlocksLinear2x2WithoutAttribs;}
//...
// read palette and video chunk from dump files
public byte[] getPallete(int palId)
{
return Utils.readBinFile("pal1.bin");
}
public byte[] getVideoChunk(int videoPageId)
{
return Utils.readVideoBankFromFile("chr1.bin", videoPageId);
}
}
...And edit game in CadEditor (blocks and screens described in the standard way, so no additional code is needed):
Now, the game background can be changed:
Battletoads Race Editor
Another plugin, added with this update, is Battletoads Race Editor plugin.
It's very specific, created for only one level of the game, but it can be upgraded for being a highly configurable plugin for editing table data, defined in config files (with the ability to change save/load methods, rendering, formatting and editing methods).
This types of plugins not loaded on the editor start but included only from specific configs. For example, this plugin included only in the config for Battletoads, level 3:
public string[] getPluginNames()
{
return new string[]
{
"PluginBattletoadsRaceEditor.dll",
};
}
The plugin is used for editing positions and types of obstacles for racing in level "Turbo Tunnel" in NES Battletoads game. Obstacles have 7 parameters:
type - type of the obstacle, icon represent pictures of object in the game.
x - position on the track, then obstacle showed to the player.
x1 - position on the track, when obstacle starts moving to the player.
y - position of the bottom of the obstacle. Two standard positions - on the ground and on the height of jump of the player.
z - position on the track. Three standard positions - on the top part, on the bottom part, on the middle part
blinkTime - time to blink. By default, synced to the x1 position - object stops blink, when start moving.
jumpPower - only for trampolines. Defines power of jump after touching the trampoline.
X, y, z positions described on the screen:
This plugin was made is a separate utility, but rewritten as CadEditor plugin for the ability to create other Tables Editors for other games (in ideal, according to the CadEditor philosophy, there is only one universal Table Editor, configurable from config files by games). For now, only the address of objects can be changed from scripts (for editing other regional versions of Battletoads game).
Example of the track, built with the old version of this plugin:
Resources
CadEditor-related resources:
- CadEditor plugins list - description of CadEditor plugins (in Russian)
- CadEditor on fundition.io - project's page on Fundition.io
External docs and tools:
- Bizhawk - the emulator of Game Boy (and other consoles) with lua scripting support.
- Displaying a 2BPP Tile - description of Game Boy graphics format
- Tile Layer Pro - graphics editor for editing PPU dumps.
- Battletoads disasm - disassembled sources of the Battletoads game.
Similar projects
Basically, there are no other universal level editors.
Almost all level editors for Game Boy specific games listed on romhacking.net.
Battletoads also has no level editor. One attempt with predefined pictures made with GameMaker by romhacker Ti_ (old forum post in Russian).
Roadmap
- Adding support for graphics for other consoles by Nintendo - Super Nintendo, Game Boy Advance.
Series Backlinks
Previously I described CadEditor in articles: