This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Tutorial: cutting, pasting chr/bin strips together with ca65

Tutorial: cutting, pasting chr/bin strips together with ca65
by on (#220982)
This tutorial answers how to slice and merge binary NES assets, using the cc65 suite.

So the example is kind of redundant for all you seasoned programmers since you can achieve the same result with one line in bash or PowerShell (probably).

I found it useful to make this little "ca65 script" to be able to quickly pick and merge strips of tile data into one chr-rom file.

In the example, it takes most rows of tiles from dummy0.chr and the 3 last rows of dummy1.chr and concatenate them into one 4kB binary. This was used to copy common tiles (an alphabet + some HUD symbols) across level tilesheets.

ca65 has a very versatile .incbin directive. it lets you set offset and length. This means you can grab a portion of any binary. This is pretty useful for tiles especially.

For me, it circumvened having to use yy-chr to do the job, and since you can't copypaste between several NESST instances (each has its own clipboard space for tile data), this was the quickest way for me. Now i've got the script for every time i need to bake a new level tileset specific to this project.

Baby steps to make the example work:
1) install cc65 suite somewhere if you haven't
2) You need to rename the path:s in the .bat file to fit your environment.
3) optional: in merger.s, replace dummy0.chr and dummy1.chr with the files you want to merge
4) run merger.bat

It will replace and produce a new tileset called merged.chr

For any practical use of the example files specific to your project, you can:
al) adjust the offsets and lengths to taste. Remember to multiply by 16 or $10 if you're counting tiles, rather than bytes
b) add in as many or as few .incbin directives as you need.
c) change the expected size of the output in the .cfg file by changing "size = $1000" (4kB:s) to something else.
d) replace my magic numbers with some defined constants that make sense to you.

Mostly, i'm just hoping this'll raise some awareness that you can use .incbin more flexibly in any project. It can for example nondestructively pick and choose subsets of assets everytime you build your program, or sometimes just simply circumvene the need for external tools or repeated command line tasks.
Re: Tutorial: cutting, pasting chr/bin strips together with
by on (#220991)
Yes, this option is useful and if your set flags even better. You could set a flag to slice specific files when in debug mode, test mode, release etc. With those flags passed on the command line to your make file, you could create many variation of assets for testing this way.
Re: Tutorial: cutting, pasting chr/bin strips together with
by on (#221161)
Waaaaat how did I miss this??

Ha ha, how many times I've wished .incbin had exactly that, and apparently it did all along?

(Since 2001, anyway, long before I ever used it.)

I usually just write quick python scripts to cut up ROMs though, example:
Code:
rom = open("smb.nes","rb").read()
open("0.prg","wb").write(rom[16+0x0000:16+0x4000])
open("1.prg","wb").write(rom[16+0x4000:16+0x8000])
open("0.chr","wb").write(rom[16+0x8000:16+0xA000])
Re: Tutorial: cutting, pasting chr/bin strips together with
by on (#221172)
FrankenGraphics wrote:
Mostly, i'm just hoping this'll raise some awareness that you can use .incbin more flexibly in any project.


rainwarrior wrote:
Waaaaat


Mission accomplished! :D I figured after a search that this might not be well known. Easy to miss
nice features when the sum of them are so extensive.

---

Another good thing is that you can always be sure that you're not breaking the ROM budget with a file that has been mistakenly padded. A recurring mistake i do is, when using NESST > all > save is that it defaults and pads the tilemap size to 8kB:s, rather than 4kB:s, which is the expected size in my workflow.

Doing full tilemap inclusions like so:
.incbin "name.chr",0,$1000
makes similar situations failsafe / human error less likely.
Re: Tutorial: cutting, pasting chr/bin strips together with
by on (#221178)
A place where I've wanted this was when preparing patches for existing games. Say I found 32 bytes of space at $D840, I could do something like this:

Code:
.segment "prg_8000"
.incbin "smb.nes", 16, $D840 - $8000

; patch goes here

.segment "prg_D860"
.incbin "smb.nes", 16 + $D860 - $8000, $10000 - $D860


In the past, I'd instead split the ROM up into separate files to go around the patch space.

Not really that much extra work, but it's yet another step that had to be done with yet another tool, rather than just the cc65 build.
Re: Tutorial: cutting, pasting chr/bin strips together with
by on (#221179)
Yeah, I too was very glad to discover this a while back.
Re: Tutorial: cutting, pasting chr/bin strips together with
by on (#221180)
My mapper hack of Solar Wars from CNROM to UNROM uses this overlay technique. (The Action 53 volume 2 builder couldn't handle CNROM yet; that was added for volumes 3 and 4.)