+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  Zelda Tile *Layout* Hacking
Pages: [1]
Author Topic: Zelda Tile *Layout* Hacking  (Read 2 times)
Dr. Floppy
Guest
« on: January 10, 2009, 08:54:58 pm »

Greetings all,


          I'm roughly 40% done with my Complete Overhaul hack of The Legend of Zelda, and have come to a point where many of my ideas require significant alteration of some of the original paradigms.

Lately, the major manifestation of this is with the dungeon bosses. For example, the Aquamentus (Level 1's lime-flavored wussdragon) sprite consists of a block of three 8x8 tiles horizontally, and four tiles vertically. (The game actually identifies "tiles" as being 16x8.) My Aquamentus replacement concept is best displayed with different dimensions, so it's not a matter of merely redrawing tiles in TLP or reconfiguring the tile pointers at $[11844-F].

Somewhere in the ROM exists a block of data which tells the game,

  • Lime Wussdragon is 24 pixels wide and 32 pixels tall.
  • These tiles are animated; these tiles aren't.
  • Any H/V tile flipping, direct or implied.
  • Look $here for actual tile pointers.


...for every boss character (as well as regular rank-and-file creatures). I imagine there might also be some info nearby about HP, damage potential, weapon susceptibility, movement patterns and/or palette references. But for now, I'm mostly concerned with the dimension/animation/flipping controls. The question remains, how does one find such data? Are there certain byte values which, when used in a certain context with each other, suggest that this is the sort of thing being programmed? Can one set a breakpoint for this data in a debugger?


After giving me a very thoughtful answer, Mr. Disch suggested I post this question publicly. To avoid redundancy, I've included his input below. 

From Mr. Disch:

Quote
Easiest way I can think of is to corrupt.  Figure out the tile IDs used by the sprite by looking at the PPU viewer.  After checking Zelda briefly I see that the head of that dragon from level 1 is tile $C0 on the left-hand pattern table.  Keep in mind this game uses 8x16 sprites, so tiles $C0 and $C1 on the left pattern table would be '$C0' in the game, and those same tiles on the right pattern table (which in this case seems to be graphics for the wall) would be '$C1' in the game.

ANYWAY, once you know one of the tiles is $C0, corrupt the ROM looking for $C0 and narrow it down until you find the byte in the ROM which controls the tile used for the dragon graphic (there might be more than one -- like a separate one for each frame of animation.  If that's the case you'll probably want to find all of them, but they should be close together).

Other things, like X,Y positioning, H/V flipping, palette assignment, etc is probably all stored in the same chunk along with that tile ID.  So once you find that tile ID you've probably found all the info you need to rearrange the sprite however you want.  In-game formats may vary, but they probably keep it in the same order as the NES uses it which I remember as "YTAX (why tax?)"  That's:  Y coord, Tile number (what you're corrupting to find), Attributes (H/V flip, palette), X coord.  The whole YTAX block is 4 bytes, and there's probably several YTAX's for the sprite layout with possibly a small header indicating how many YTAX's there are.

But this is a guess mostly -- like I say the game may do it differently.  However it's a solid bet that if you find that tile number, you find the sprite layout.  Even if it's not in YTAX form, it should still all be together.  And worst case... if all the stuff is separate, finding the tile ID will at the very least give you a solid spot to set a breakpoint on and start tracing from in order to find the rest.

(Moderator edit: BBCode does not work in the thread subject. Fortunately for us all.)
« Last Edit: January 11, 2009, 10:35:41 am by Kiyoshi Aman »
Disch
Guest
« Reply #1 on: January 11, 2009, 09:14:35 am »

I checked Zelda for a bit the other day.  Apparently I was wrong about $C0 being the head -- it's the head with an open mouth, which isn't used as often as the head with the closed mouth, which seems to be tile $CC.


EDIT

Looked further, at first glance it almost looks as if the sprite drawing is hardcoded.  Ugh!

The tiles for the dragon are at offset 0x11844.  There's 12 bytes, each byte being a tile number.  The first 6 bytes are for the first frame of animation, and the next 6 are for the second frame (the game switches between to two to animate the dragon's wings and legs).  So each frame has 6 sprites, each sprite is 8x16 pixels, which makes the dragon 24x32 pixels (3 sprites wide, 2 sprites tall).

IN ADDITION, offset 0x11898 is the $C0 -- the tile used for the open mouth of the dragon when he's about to throw fireballs as you.  This tile is most definately hardcoded (it's in the middle of an LDA immediate instruction).

Don't see how to reshape the objects.  It's definately not as simple as I was hoping.  I'm probably not going to look at this much more, but good luck with it.
« Last Edit: January 11, 2009, 02:12:37 pm by Disch »
Dr. Floppy
Guest
« Reply #2 on: January 11, 2009, 06:29:50 pm »

Quote from: Disch on January 11, 2009, 09:14:35 am
Looked further, at first glance it almost looks as if the sprite drawing is hardcoded.  Ugh!

Don't see how to reshape the objects.  It's definitely not as simple as I was hoping.  I'm probably not going to look at this much more, but good luck with it.


Snap. And my deadline is only 354 days away...

Any idea on what would possess the programmers to do this? As legend has it, it was the same team that did SMB1 (and during the same timeframe as well- Miyamoto has commented on having to discern between "Mario" ideas and "Zelda" ideas). At least the Moblins and Goriyas are achiral.


[disclaimer] Dr. Floppy knows BBcode doesn't work in headers. [/disclaimer]
Tauwasser
Guest
« Reply #3 on: January 11, 2009, 07:06:08 pm »

Well, it might be part of the same philosophy in early video game programming that brought us hardcoded X and Y values for events in Pokémon R/B/Y Tongue It just wasn't worth building a good engine that is variable for only 8 bosses. It's probably hardcoded just because they could.

Also, a lot of games hardcode the Player not as an instance of other people events in ram but just display its picture and check collision for the center of the screen, so no surprise there.
If you want to change the objects' shape, then delve into ASM and do it properly. You probably won't find a suitable alternative for doing that - one that works 100% like you wanted no maybe's - either way.

cYa,

Tauwasser
Jigglysaint
Guest
« Reply #4 on: January 12, 2009, 11:42:30 pm »

Since games are not intended to be modified, it makes sense that stuff is hardcoded.  If there is free space left in the bank, I suggest a JSR to new routines that re-define the tiles.  I mean, if I can code in Lock Blocks for LOZ, how hard is it to reprogram Aquamentus?  Of course there IS always Zelda Classic...
Dr. Floppy
Guest
« Reply #5 on: January 13, 2009, 06:45:09 pm »

Quote from: Jigglysaint on January 12, 2009, 11:42:30 pm
Since games are not intended to be modified, it makes sense that stuff is hardcoded.  If there is free space left in the bank, I suggest a JSR to new routines that re-define the tiles. 


That sounds like the most likely option at this point. It's annoying how the programmers pulled out all the stops to save a few tiles on chincy things in the dungeons, then they go and write seperate pointer sequences for blue and red Octoroks. Just damn...


UPDATE: While we're on the topic, what's the deal with these "smart" tiles used for overworld objects and backgrounds? If I try to reassign the "sand" pointers to a slate of tiles that were originally used for water, they still act like water when used in the game. The ROM somehow knows that tiles 90-91-92-93 are to act like a solid barrier, even when assigned to a You-Can-Walk-On/Thru-It object.

This vexes me even further...  Angry
« Last Edit: January 17, 2009, 09:11:57 pm by Dr. Floppy »
Tauwasser
Guest
« Reply #6 on: January 17, 2009, 09:24:22 pm »

Collisiondata? It's Zelda. Odds are, it's hardcoded. Look for compares with 0x90 that branch off/return when smaller than 0x90 and are followed by a check for smaller than 0x94 thet makes it branch/return to the same as before.

cYa,

Tauwasser
Dr. Floppy
Guest
« Reply #7 on: January 18, 2009, 10:01:18 pm »

If I'm not completely sick of it by next year, I have half a mind to invest some serious effort in another hack that de-hardcodes all this stuff, while maintaining the original gameplay/layout/etc.

Now I learn that the music engine automatically mutes a channel once the overall song program exceeds 256 bytes. SMB1 allowed for such programs, provided that the first byte of the final channel (usually Noise) was within the 256-byte header offset limit.

That said, the Triangle Channel has a delicious selective-repeat function, which is just begging to be expanded to other channels...
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC