CadEditor - Animation Editor update and Sprites
Repository
https://github.com/spiiin/CadEditor
CadEditor is the universal level editor for NES/SMD/SNES games, I describe project on steemit here.
What feature(s) did you add?
CadEditor has plugin Anim Editor for showing object sprites for several Capcom NES games. I created it for testing my understanding of animation format for game Chip & Dale Rescue Rangers. This animation format also used in games Darkwing Duck, Duck Tales 1, Tale Spin, Little Mermaid (Settings for this games was added by romhacker Roket). It will also be used in several other Capcom games (some games of Mega Man series ), but not in all (Duck Tales 2, Chip & Dale 2 used another format).
In this update I improved plugins features for:
- change the scale of sprites
- change or disable background color
- export sprites in png format (with calculating sprite bounding box, if background color disabled)
- view sprite with tiles and palette, loaded from any binary file (it need for NES games, which use CHR-RAM memory or change only parts of CHR-ROM banks – i.e. most of the games)
Related commits
Screenshot of the plugin before:
And now:
My idea is to use this plugin for preparing sprites for CadEditor Object Editor. I used it to research animation in this games and to create sprites for Object Editor. Export correct sprites is not a trivial process, so I describe it below.
Commits per games:Object editor without sprites:
And with sprites:
How did you implement it/them?
Now, Object Editor by default shows sprites as numbers with an object type, but it also supports option to show prepared sprites instead of the default, for certain games (as shown at screenshots above).
One way to prepare these sprites is to make screenshots with every object in the emulator while playing the game, and cut objects from it.
(Background can be disabled in the emulator, and only sprites rendering enabled)But the more interesting way for research - is to build sprites from ROM data. It needs to make additional work for it, but after complete it, the researcher can view really all animations, even hidden secret animations, not used in the game at all.
For example, there are sprites of unused enemy in Duck Tales 2 (found by romhacker Ti_)
Format of animations for Capcom games
Every object in the game is described with two arrays per 4 bytes each. The first array contains objects lives and three zeros. Another array contains such object's properties:
byte 1 - unique object type number.
byte 2 - the number of object's behavior function (called every frame when the object is showed)
byte 3 - initial animation number
byte 4 - additional field. Can contains flags bits of second animation number
Object type number - with this number object on the level can be described with only this one byte.
Object's behavior function is called every frame when the object showed, and it describes, how the object will be updated.
Initial animation number defines, how the object will render when it appears on screen (animation number can be changed by behavior function. For example, initial animation "Robot stand" can be changed to "Robot walk" to the player.
Additional field saves all data related to object state (is enemy, is visible so on) needed to classify the object. In some games, it saves an additional animation number.Animations themselves are described with fields:
{
1 byte - Frames count N
1 byte - Timer (defines the speed of change frames in animation)
N byte - Indexes of frames in the animation
}
Every frame defined with the structure:
{
1 byte - Tiles count N
1 byte - index in coordinates array (array with Xs and Ys of every tile). Coordinates stores as the separate array for compactness reasons. Some frames stores different tiles, but positions of tiles keep unchanged - they can share coordinates between frames.
N*2 byte - pairs of tile index and tile attribute (1st byte - tiles index, 2nd byte - tile attribute (standard NES system ability - tile mirroring by X and Y, transparency and palette bits) ).
}For example, addresses of arrays for Chip and Dale
5:B55F-B4B6 (168 items) animations array
5:9CAE-9B82/
5:9DAE-9C82 (300 items, separated by 2 arrays) - frames arrays
5:B145-B08E (183 items) - coords arrays
AnimEditor plugin can show all animations as the tree:
Frame rendering
Frame rendering has one problem - NES draws sprites with a prepared table with 256 tiles (called CHR bank). Enemies used in one level grouped in one tile bank. Almost always, the game contains several different banks, and bank switching is programmed in the game code, often before the level or sublevel start.
So, object editor doesn't know, what bank of tiles must be used for correct rendering. The only user of the editor can choose a correct bank from all banks used in the game.
For example, there is the same frame, rendered with the correct and incorrect bank:
But some NES games not stores full CHR-bank in ROM, and switch only part of the bank. For this games, it's hard to describe all combinations of banks in the settings file. For this case, Anim Editor can load bank from the file.
There is the lua script, that can make a dump of CHR-bank while play game in Fceux emulator.
The user can run it exactly at the moment when object rendered in game. For example, at this moment (Duck Tales logo screen):
For this case, tiles of sprites stores in bank 1 and use palette 2, and tiles of background stores in bank 2 and use palette 1. It's normal case, NES can use any combination of palette and bank for sprites. So, we need files with names chr1.bin and pal2.bin from directory with dump_chr_and_pal.lua script
We need to open these files from Anim Editor with "load CHR from file" and "load pal from file" buttons and search Scrooge's head animation:
Chip and Dale, Darkwing Duck and Tale Spin change full banks only, so it's no need to make dumps for this games (but this method can be applied with it also), and Duck Tales and Little Mermaid change banks by small parts, so dumps is only way to see all animations inside these games.
Sometimes it's not easy to understand, what sprite do you see (for example, if there is only one tile in it). But animations often grouped by numbers, so if you can identify adjacent animations and set correct bank for it, you will see the frame with this bank also).
Using sprites in Object Editor
After finding all sprites and export it, there is the last step for using it in Object Editor. You need to find object numbers that using animation files. It can be done with analyzing level in Object Editor and in the game - just see how an object looks in the game and find correspond sprite for it. Sprites must be renamed correspond to object number with postfix "b" ("big") after it. For example, for object 0, the file name must be "000b.png", and so on.
Folder with these sprites can be selected in game settings file:
public string getObjTypesPicturesDir() { return "obj_sprites_dwd"; }
After that, Object Editor will render prepared sprites:
Series Backlinks
- CadEditor - Universal level editor for NES/SMD/SNES games
- CadEditor. Support levels with mixed screens
- CadEditor. Release 5.1
- CadEditor - Two new plugins
- CadEditor. Release 5.2
- CadEditor. History of the project
GitHub Account
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]
Thanks for the review. Maybe, using gifs really will be interesting =)
My code is undocumented now, I'll try to add comments in the project at least to shared parts.
Thank you for your review, @helo! Keep up the good work!
This project is being supported by @Fundition
Fundition is a next-generation, decentralized, peer-to-peer crowdfunding and collaboration platform, built on the Steem blockchain.
#upfundition and #fundition tags on Steem represent the projects that are started on https://fundition.io.
Are You Prepared to Make the World a Better Place too?
Read the full details of Fundition Fund program
Learn more about Fundition by reading our purplepaper
Join a community with heart based giving at its core
Congratulations,
you just received a 11.04% upvote from @steemhq - Community Bot!
Wanna join and receive free upvotes yourself?
![](https://steemitimages.com/0x0/https://www.steemhq.com/steemhq_voting.gif)
Vote for
steemhq.witness
on Steemit or directly on SteemConnect and join the Community Witness.This service was brought to you by SteemHQ.com
Hey, @pinkwonder!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Congratulations! This post has been upvoted from the communal account, @minnowsupport, by spiiin from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.
If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
Be sure to leave at least 50SP undelegated on your account.
Congratulations @pinkwonder! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board of Honor
If you no longer want to receive notifications, reply to this comment with the word
STOP
Congratulations @pinkwonder! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board of Honor
If you no longer want to receive notifications, reply to this comment with the word
STOP