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

Author Topic: DBZ2 (FC/NES) - Write on [han]dakuten Line  (Read 2248 times)

Gyroballer

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
DBZ2 (FC/NES) - Write on [han]dakuten Line
« on: February 09, 2019, 07:41:48 am »
Hey, all. I'm wrestling with textbox space contraints on DBZ2 for the Famicom/NES.

It definitely works very similar to DBZ1,3,Gaiden that RedComet and company worked on.
I looked at his ASM source code and for now just added the dbz1vram.asm in blank space in the rom and changed pointers to the old text routine to his hack.
The text still writes well, but only on every other line instead of taking advantage of the dakuten/handakuten space.

If I change one of the vram_access_1 function to load accumulator with $0605 ([han]dakuten area), then my text will display in doubles (each character concurrently, not alternating handakuten line and main line by either characters or line) on the normal line and the line above, but it will create graphical glitches as well.


For example, it might look like this normally:


But like this (along with slight graphical glitches)
if I edit lda $0604 -> lda $0605:


Of course, I'd like it to look like this
(Directly edited PPU mem for mockup):



Code in question:
Code: [Select]
vram_access_1:
lda $0604,x ;This will read in the dakuten/handakuten information from RAM,
sta $2007 ;and load it into the nametable.
inx ;Increment X so the base character will be read next.
dey

vram_access_2:
lda $0604,x ;This loads the base character into the nametable on the line
sta $2007 ;below the previously loaded dakuten/handakuten.
inx
dey
bne vram_access_1 ;if (y != 0) {goto vram_access_1;}
;This won't happen when dealing with displaying text.


This is the closest I've come to progress. What I want is for it to alternate, starting with [han]dakuten and then base, repeating, instead of cloning base up to [han]dakuten. But if at all possible, I want all of the text to be read from the base ($0604).

What's the best way of doing this? Presumably this routine already alternates but simply grabs blank characters/spaces.

Additionally, I've been having some other troubles. I've been doing everything manually and it feels tedious since I know there are better ways to do things.

For instance, I'm manually hex editing (with tables) the script when I make a change. I've successfully dumped it without pointers with Cartographer, but I don't understand how to safely change it and reinsert it with Atlas.

This goes for testing RedComet's ASM hack as well. I had to go into DBZ1 translated and look for the routine, copy the hex values using FCEUX's hex editor, and then paste them into blank space (FFs) in a valid bank on the rom (that took me forever to find in DBZ2 -- seemingly little free space).

I've also had to manually find the pointer tables (although they're typically right above a wall of text), and manually discover their internal logic, but I've yet to come up with a tried and true "formula" for it. I take care to subtract 10 for the header in general, but the pointer table might ignore the first byte out of a 2 byte address (like if the text is at 0174BC, I'd assume the pointer will be somewhere looking like AC74, but instead there may be a value before or after AC that isn't 74 -- something to do with reading it from RAM instead of the ROM?).

Finally, for the vast majority of the script, being able to write on the [han]dakuten lines will give me effectively double the space, especially since I can take advantage of pointers, but it's possible that a text-heavy area would require a lot of pointer maintenance or even just not be possible to fit in its current bank, etc.
What would I do in that situation?
Expand the ROM? I tried this and couldn't access more than the normal amount of banks anyway.
Would I need to go with a dictionary/compression method? Any suggestions if so?

I could definitely use some direction in general, and I appreciate any help you can give this novice lol.
« Last Edit: February 09, 2019, 07:49:42 am by Gyroballer »

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6927
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: DBZ2 (FC/NES) - Write on [han]dakuten Line
« Reply #1 on: February 09, 2019, 01:26:54 pm »
I've also had to manually find the pointer tables (although they're typically right above a wall of text), and manually discover their internal logic, but I've yet to come up with a tried and true "formula" for it. I take care to subtract 10 for the header in general, but the pointer table might ignore the first byte out of a 2 byte address (like if the text is at 0174BC, I'd assume the pointer will be somewhere looking like AC74, but instead there may be a value before or after AC that isn't 74 -- something to do with reading it from RAM instead of the ROM?).
It doesn't sound like you are understanding pointers correctly.
AC 74 would be $74AC which is RAM (normally, I think on the Bandai mappers that is MMIO).
To calculate the pointer you need to know the ROM bank size for the mapper you are using.
If it uses a 16KB ($4000 bytes) bank size, then you need to take your pointer, minus the header (-> $174AC), then figure out how far into the current bank that is (address modulo 0x4000. Or in other words, find out where the current bank starts ($14000) and subtract the difference. $174AC - $14000 - $34AC). Then take that difference and add it to one of the possible CPU address locations. (with a 16KB bank size, that's probably $8000 since $C000-FFFF is typically mapped to the final PRG-ROM bank). Then add the bank's CPU address to the bank offset ($8000 + $34AC = $B4AC ), and that is the pointer value.
"My watch says 30 chickens" Google, 2018

Gyroballer

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
Re: DBZ2 (FC/NES) - Write on [han]dakuten Line
« Reply #2 on: February 10, 2019, 09:29:04 am »
It doesn't sound like you are understanding pointers correctly.
AC 74 would be $74AC which is RAM (normally, I think on the Bandai mappers that is MMIO).
To calculate the pointer you need to know the ROM bank size for the mapper you are using.
If it uses a 16KB ($4000 bytes) bank size, then you need to take your pointer, minus the header (-> $174AC), then figure out how far into the current bank that is (address modulo 0x4000. Or in other words, find out where the current bank starts ($14000) and subtract the difference. $174AC - $14000 - $34AC). Then take that difference and add it to one of the possible CPU address locations. (with a 16KB bank size, that's probably $8000 since $C000-FFFF is typically mapped to the final PRG-ROM bank). Then add the bank's CPU address to the bank offset ($8000 + $34AC = $B4AC ), and that is the pointer value.

Thank you for this advice. I realized that at least the first set/block/chunk of text is offset by 4000. So if I have the pointer, I subtract 4000 and add 10 to find the text. If I have the text, I add 4000 and subtract 10 to locate the pointer. (Switching the bytes to account for endianness, etc.)

I'm still reading everything I can find on DTE, VWF, and methods to write on the handakuten line though, because those could save me a ton of space or allow me to express my script better with the space available.

I think the game may use what Madhacker's guide called "Sequential Text" because I believe no matter how I set up the control codes, etc., I've only got so many windows/pages/paragraphs to work with. So if that's true, I see the usefulness to my script as: handakuten line writing, variable width font, DTE/compression in that order.

Of course, this is because I'm favoring on-screen space VS rom space. I've ran into many locations in the game where I had enough room to type, but not enough screen economy to display it.

Because if I have enough space (pointer manipulation and DTE/dictionary/compression) in the rom, then I can effectively double what's being presented per page by writing to the handakuten lines (if it's page-limited by sequential text). So a 100% increase in text appearance.

If I use VWF, instead of being limited to 24 characters per line, as long as there's enough rom space for the script, I could maybe do 30 characters per line. So that's a roughly 25% increase in text appearance.

I still will probably need DTE or a compression scheme to make enough space when pointer manipulation isn't enough, though, and I know that besides there being very little extra space in the rom as it is, my script is also going to be larger than the Japanese in plenty of places.
Of course, that could be a little naive. I already save a ton of space with the "ll" tile, so if there are other super common pairs like "er", "re", etc. then I'll save more space than I'm giving DTE credit for.

My concern is just trying to figure out the priority here, and then just going for it one thing at a time. Today I'll work on (more) pointer table manipulation to see how much of my ideal script I can fit.

But today or here soon, I really need to figure out one of those three things (or other potential things), prioritizing screen economy, and then move on from there.
« Last Edit: February 10, 2019, 09:41:18 am by Gyroballer »

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 6927
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: DBZ2 (FC/NES) - Write on [han]dakuten Line
« Reply #3 on: February 10, 2019, 10:54:44 am »
VWF is rarely a usable option on the NES.

First of all, many games use CHR-ROM which by definition should not be writable. (I don't know if emulators will but that sounds like an accuracy issue if they do.)
Second is tile space.
Generally, on 8/16 consoles, making a VWF means you have to have enough tile space to effectively draw the entire text window as a graphic.
Even 24 tiles x 6 lines is 144 tiles. That's over half the BG tile space.
"My watch says 30 chickens" Google, 2018

Gyroballer

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
Re: DBZ2 (FC/NES) - Write on [han]dakuten Line
« Reply #4 on: February 10, 2019, 01:24:12 pm »
I see. That somewhat backs me into the corner of having to figure out how to write on the other lines then.

I'm glad you warned me so I didn't end up wasting a lot of my time on that.

RedComet

  • Hero Member
  • *****
  • Posts: 3166
    • View Profile
    • Twilight Translations
Re: DBZ2 (FC/NES) - Write on [han]dakuten Line
« Reply #5 on: February 14, 2019, 07:36:29 pm »
It's been a long time since I looked at these games.

The patches for DBZ1, 3, and Gaiden all use Huffman compression and a lot of bank switching to take advantage of *all* of the available space in the ROMs. Just copying and pasting the routines from one game to another isn't enough. As I recall each was sufficiently different enough that I need logic specific to each game to handle everything correctly.

At one point I had the script dumped and all of the assembly mods (including the compression) worked up for DBZ2. This fell by the wayside over the years because a translator never showed up. I would happily pick it back up if someone were interested in translating the scripts, though.
Twilight Translations - More than just Dragonball Z. :P

Gyroballer

  • Jr. Member
  • **
  • Posts: 26
    • View Profile
Re: DBZ2 (FC/NES) - Write on [han]dakuten Line
« Reply #6 on: February 14, 2019, 08:23:34 pm »
At one point I had the script dumped and all of the assembly mods (including the compression) worked up for DBZ2. This fell by the wayside over the years because a translator never showed up. I would happily pick it back up if someone were interested in translating the scripts, though.

After I finish cleaning up my next version of this, I'd be happy to give you my script (the full one, not the somewhat truncated one that I have to fit in the game), but I also really want to learn how to do some of the stuff you'd be doing/have done.