News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Legend of Zelda(NES)Need help Expanding text line/Moving data forward in rom  (Read 2775 times)

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
So thanks to Dr. Floppy awhile ago, Ive managed to move the Hearts counter up. :thumbsup:
Now im trying to move the line from 0001A305-0001A30D back about 8 bytes to start at 0001A2FD and move the line starting at 0001A30E forward by four bytes (Erasing part of the "Inventory" text) in order to make room on the status bar where my Hearts counter used to be to draw some fancy background dots for my timer (Yes I HAVE TOTALLY LEGIT PRIORITIES), but when I try, I get weird garbage graphics and a bug that prevents me from leaving the screen, I think maybe I need to modify pointers? but Im not sure how to find them, I tried searching 0005A301 but turned up nothing so I dunno what im doing right now.
« Last Edit: February 27, 2016, 09:14:59 pm by SleepyFist »
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

Trax

  • Hero Member
  • *****
  • Posts: 515
    • View Profile
    • Trax ROM Hacking
Most of the graphics commands sent to the PPU in Zelda 1 (and in many games) are structured this way:

PPPP NN
XX ... XX
FF

PPPP = PPU Address to write to, big-endian, 2 bytes
NN = Number of bytes to transfer, 1 byte
XX = Bytes to transfer, variable length
FF = End of sequence, 1 byte

There are a few other details to consider...
When bit 7 of the byte count is set, the tiles are drawn vertically...
When bit 6 of the byte count is set, the next byte is repeated (using bits 0-5 of the byte count)...

Example with the INVENTORY line:

1A316

29 84 09   PPU Address 2984, transfer 9 bytes
12 17 1F 0E 17 1D 18 1B 22   INVENTORY
FF


For example, if you want to push the word INVENTORY two tiles left, you replace 2984 with 2982...

The lowest PPU address you can use for the Subscreen is 2940...

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
Pardon me for being an idiot, but I can't understand what you just told me. :P
I probably could have done a better job explaining and maybe 'pointers' was the wrong term for what I was trying to do.

Basically im not trying to move anything graphics wise except for shortening Inventory to Items so I could try to jam some data sideways into the gap in order to make room to the right of 0001A30D to put some graphics where the hearts counter used to be before I moved it up, moving it up also rendered the LIFE text useless so i figured id try to monopolize the space by pulling 0001A305 back to 0001a2fd but doing any of this causes the game to lose it shit and stop working when I try to leave a screen so I thought maybe there was something telling the game where lines start and end but I dont know where it is to modify it.
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

Trax

  • Hero Member
  • *****
  • Posts: 515
    • View Profile
    • Trax ROM Hacking
Well, you have to understand if you want to do it yourself. The data you're trying to edit is not a 1-to-1 equivalent of the tiles you can see in-game in the Subscreen menu. The Subscreen, like many other places in the game, is drawn using commands sent to the PPU, which tells what tile to use and where. The Subscreen menu is drawn in several groups of these commands...

At 1A000, Bank 6, there's a large table of pointers (0x40 pointers) that point to various PPU commands used throughout the game. They don't seem to be in any particular order. Some are for the Intro story, some for the Continue Save Retry screen, some for the Subscreen, some for palette changes, some point to the Cartridge RAM, etc...

At 1A2D3, you have the PPU commands for palette mappings, the A/B Buttons Item boxes, the "-LIFE-" string, and the little icons for Rupees, Bombs and Keys, all in one. At 1A316, you have the "INVENTORY" string, alone. At 1A323, it's for the Current Item box and the inventory box. And so on...

Dr. Floppy

  • Restricted Access
  • Hero Member
  • *
  • Posts: 972
  • Make America GREAT Again!
    • View Profile
    • BaddestHacks.net
Quote
I get weird garbage graphics and a bug that prevents me from leaving the screen,

That's Sprite-Zero shit detection. The garbage graphics overwrite or interfere with the Bomb icon, yes?

The good news is that's fixable, most likely by simply refining your new "Inventory/Timer Dots" code.

Quote
Now im trying to move the line from 0001A305-0001A30D back about 8 bytes to start at 0001A2FD and move the line starting at 0001A30E forward by four bytes (Erasing part of the "Inventory" text) in order to make room on the status bar where my Hearts counter used to be to draw some fancy background dots for my timer

Post a screencap of this data segment and I'll advise accordingly (unless someone else gets to it first).

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
Its no screenshot but will a copy paste work?
lower-case letters standing in for graphics b=bomb, d=dot, a=arrow, []=ff

This is just before the move, INVENTORY=ITEMS, LIFE is erased.
W.E.B..A.________W.6......W...W...W...W...W...a.b[]!.9___5ITEMS
or
206F 0E69 0B6B 690A 6B24 2424 2424 2424
2420 CF06 6E6A 6D6E 6A6D 208F C26C 2091
C26C 2092 C26C 2094 C26C 206B 84F7 5AF9
61FF 2984 0924 2424 0512 1D0E 161C

And this is the code im trying to use

W.E.B..A.W.6......_.dddddd.___W...W...W...W...W...a.b[]!.5ITEMS
or
206F 0E69 0B6B 690A 6B20 CF06 6E6A 6D6E
6A6D 245F 5E5E 5E5E 5E5E 5F24 2424 208F
C26C 2091 C26C 2092 C26C 2094 C26C 206B
84F7 5A49 61FF 2984 0512 1D0E 161C
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

Dr. Floppy

  • Restricted Access
  • Hero Member
  • *
  • Posts: 972
  • Make America GREAT Again!
    • View Profile
    • BaddestHacks.net
Aight, this is good. Starting from the beginning:

20-6F-0E

This tells the game "we're going to start writing tiles at PPU location $206F, and we're going to write a linear string of #0E (fourteen) of them. Thus, the next fourteen bytes will be interpreted as the 14 tile ID's to write, starting on the fourth line down from the top and just barely left-of-center. You only want to write six tiles there, so replace that #0E with #06.

Here's how the rest of your code parses-out:

20-CF-06: Write six tiles starting at $20CF:: 6E, 6A, 6D, 6E, 6A, 6D.
24-5F-5E-5E: Write tile #5E thirty times in a row, starting at $245F. (I'm guessing this isn't desired.)

Replacing the #06 with #12 should fix that section.

208F C2: 6C
2091 C2: 6C
2092 C2: 6C
2094 C2: 6C

No problems there.

206B 84: F7 5A 49 61 (also no problems)
FF

The #FF tells the game that it's done suctioning up PPU/background data for this go-around. (There's only so much that can be interpreted and executed per frame.) Since that break comes right before "ITEM" in the original, I'd say you're fine here.

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
Okay thanks,  ill try this when I get back to my computer,  so to clarify what you and trax are explaining, this data is sent to the ppu to be displayed onscreen based on the control codes at the beginning of each line right?
And ff is the stop code at the end of the line,  up till now i had only figured out the position code for the inventory text.
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

zonk47

  • Sr. Member
  • ****
  • Posts: 343
    • View Profile
Just leaving this here: zeldaclassic.com
A good slave does not realize he is one; the best slave will not accept that he has become one.

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
Just leaving this here: zeldaclassic.com
I have heard of Zelda Classic but I don't plan on using it, I intend to do more hacking later on so im using Zelda as a stepping stone to more complicated things. :thumbsup:
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

Trax

  • Hero Member
  • *****
  • Posts: 515
    • View Profile
    • Trax ROM Hacking
It's not exactly one chunk of commands per line, although some of them do draw a line of tiles. It's just an arbitrary number of elements (or groups of elements). The INVENTORY string just happens to be alone in its group, so it's easy to move it or change its contents. As Dr. Floppy pointed out, moving the Sprite Zero is bad, so the one command that you should not move is the one at 1A30E. Its data sequence (F7 24 F9 61) draws a vertical line of 4 tiles: Rupee, nothing, Key, Bomb...

Dr. Floppy

  • Restricted Access
  • Hero Member
  • *
  • Posts: 972
  • Make America GREAT Again!
    • View Profile
    • BaddestHacks.net
As Dr. Floppy pointed out, moving the Sprite Zero is bad, so the one command that you should not move is the one at 1A30E. Its data sequence (F7 24 F9 61) draws a vertical line of 4 tiles: Rupee, nothing, Key, Bomb...
Alternatively, you can replace that segment with whatever you want as long as you make absolutely sure another segment puts Tile #61 at $20CB.

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
Thanks, I'm starting to get the hang of this now, ;D
It's not exactly one chunk of commands per line, although some of them do draw a line of tiles. It's just an arbitrary number of elements (or groups of elements). The INVENTORY string just happens to be alone in its group, so it's easy to move it or change its contents.
You mean, like the section just before the inventory data right?  I guess it's also a general rule to never let the ppu grab one command/string and part of the next either, I figured that out fast :P
But could someone explain what exactly sprite zero is/means?
Also modified the code  so as to only take one space from "INVENTORY" but now the entire section "inventory" is in has stopped working, only way to get it back is to shorten my dot line by one and give the space back to inventory, not a major problem but annoying.
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

Dr. Floppy

  • Restricted Access
  • Hero Member
  • *
  • Posts: 972
  • Make America GREAT Again!
    • View Profile
    • BaddestHacks.net
But could someone explain what exactly sprite zero is/means?

Sprite Zero is the first (technically 0th) sprite defined in the SPR-OAM loading dock at $200-3. The NES contains special hardware that detects when the electron gun reaches the first non-transparent pixel of Sprite Zero that overlaps a non-transparent pixel of the background tile. When this happens, the hardware activates a special bit in the PPU Registers (d6 of $2002). NES games can use the status of that bit to pull off special midframe tricks, most notably a "split-screen" status bar that doesn't scroll with the gaming field proper.

As it usually takes between a third to ½ a scanline's worth of time to get all the proverbial ducks in a row, there is often a visible ray of gibberish along the rightmost portion of the scanline post-Sprite Zero "hit". This is due to the electron gun being informed that it's now supposed to be drawing data from a different Name Table for the remainder of the frame. (The title screen of Zelda 2 hides this "line of derple" behind a pile of rock sprites.)

Moving or redrawing Sprite Zero (or its corresponding background tile) alters the timing of the Sprite-Zero hit detection. This can be harmless, if you're lucky. It can result in modest de-synchronization between the static status bar and the playing field: perhaps a few additional Lines of Derple. But most of the time, it simply locks up when game gets caught in an endless BIT $2002 / BVC #FB loop. (I call this Sprite Zero shit detection, as the game is constantly polling the $2002 register for a "hit" that never happens.)

SleepyFist

  • Hero Member
  • *****
  • Posts: 842
    • View Profile
Okay, I think I understand mostly, had to look up what an electron gun is though.

So what LOZ is doing is using a Sprite zero trick to generate/sync the status bar, and this trick needs to be executed every time the screen changes right?, and if it tries to pull the trick on the wrong graphic it goes into an endless loop, so there always needs to be a call for it at the proper address.
Sleepy's tune of the week|| 2 Mello - after midnight: unaired broadcasts || https://youtu.be/FKqLCJ4mStI

Dr. Floppy

  • Restricted Access
  • Hero Member
  • *
  • Posts: 972
  • Make America GREAT Again!
    • View Profile
    • BaddestHacks.net
So what LOZ is doing is using a Sprite zero trick to generate/sync the status bar, and this trick needs to be executed every time the screen changes right?, and if it tries to pull the trick on the wrong graphic it goes into an endless loop, so there always needs to be a call for it at the proper address.

Zelda 1 does its music/sound handling at the top of each frame, and probably a few other tasks that don't take much time. Then it goes into a semi-infinite loop of BIT $2002 / BVC #FB, which means "Check to see if d6 of $2002 is set yet? If not, check again!" When the electron gun hits the first colored pixel of Sprite Zero which overlaps a colored pixel of the Bomb icon, d6 of $2002 gets set and the loop is escaped. The game then proceeds to inform the electron gun that it will now be drawing background data from a different Name Table source, and that's how the status bar remains "split" from the game field proper.

If the Bomb BG tile is moved, and nothing takes its place, then d6 of $2002 will never be set and the game remains in the now-endless BIT $2002 / BVC #FB loop. If another tile replaces the bomb tile, it will probably alter the location of the first colored-pixel-on-colored-pixel overlap, which will result in the split-screen being mistimed and looking "off".