Qhimm.com Forums

Final Fantasy 7 => Other Mods => WIP => Topic started by: halkun on 2011-07-26 02:00:12

Title: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-07-26 02:00:12
Hi all :)

So for the last week or so I've been playing in my lab coming up with a pretty keen project, I was wondering if anyone wants to help. I figure as I kicked off the "Gears (http://forums.qhimm.com/index.php?topic=3342.0)" project which became The Wiki (http://wiki.qhimm.com/Main_Page), then creating the Q-Gears project (http://q-gears.sourceforge.net/index.phtml?content=1), which was gracefully taken over by Akari, I decided to add something back to the community.

Introducing N-Gears.
N-gears is the systematic disassembly and reassembly of the FF7 ROM for the NES, recoded so that it's more like it's PSX counterpart.

Over at Romhacking.net (http://www.romhacking.net/forum/index.php/topic,12466.0.html) someone decided to make a little project to take the Chinese FF7NES rom, translate into English, and give it a graphical makeover. I saw what they were doing and decided while they were doing that, why not balance the game and convert scene.bin over to the NES to make it more like it's PSX counterpart...

Sadly, the game's engine is broken on the inside. I'm not going to enumerate what's wrong with it, but after a week of trying to shim in my changes, I have declared the engine beyond repair and in need of a rewrite...

Here's how it's going to go down...

1) Set up a toolchain so that I can compile a 2MB nes game.
This is done, I'm using the same mapper as the FF7NES, Mapper 163, It needs tweaks, but does generate a 2MB rom. For those not in the know, the largest game over made by Nintendo in the NES era was Kirby's Adventure, which was 768K.

2) Disassemble FF7NES.
The game weighs in at 2MB. Lucky for us, the code is an inefficient mess. I saw almost 512K of blank space in there, and the code is all over the place. I've got the disassembly scripts started, if anyone wants to help, I can show you how to use da65. You need to have a good handle on NES architecture and 6502 code.

3) Reassemble FF7NES into workable code
The code that is disassembled will be rewritten as source code. The dissembler does about 70% of the job, minus the symbol names. This will require keeping track of variables and routines in a 2MB game. The good news is all the important global variables are in the save map.

4) Rewrite the parts that suck.
This is the big part, throw out the linear growth curves, create a small LZW routine. Import a tiny version of kernel.bin, scene.bin and savemap. Get muti-slot Matreria working. Keep things that "work" like the event system, but expand the mapping. My dream is to have this compatible with Black Chocobo :)

Feel free to tell me I'm insane. Post here if you want to help or ask questions. This might be fun, this might be a complete waste of time. Who Knows! I'm off to post the mechanics in "Reverse Engineering (http://forums.qhimm.com/index.php?topic=12163.msg168495#msg168495)" now.

Title: Re: Halkun's new Project... Introducing N-gears
Post by: Kemlin on 2011-07-26 03:54:55
You're a raving lunatic, yes, however most projects on this forum started as the ravings of madmen and became beautiful things the sane among us could never have imagined being possible.

So...go-go Gadget Project.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: SymphoniC on 2011-07-26 04:24:05
Like I said on your other post, if this NES rendition needs music more true to FF7, let me know.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: BloodShot on 2011-07-26 04:46:06
Oh god...he's lost it  :-P
Title: Re: Halkun's new Project... Introducing N-gears
Post by: syntax error on 2011-07-26 15:37:12
I have seen LZ compression code for c64 somewhere.
Title: .
Post by: Jenova's Witness on 2011-07-26 19:45:18
.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Tekkie.X on 2011-07-26 19:55:04
En Geerz doesn't quite sound like nig urz (not the actual phonetics but you get the point).
Title: Re: Halkun's new Project... Introducing N-gears
Post by: WeretigerRei on 2011-07-29 04:24:38
Like I said on your other post, if this NES rendition needs music more true to FF7, let me know.

Definitely already some good ones on youtube.
http://www.youtube.com/watch?v=6kG_z_XxyWw
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Covarr on 2011-07-29 05:11:13
Definitely already some good ones on youtube.
http://www.youtube.com/watch?v=6kG_z_XxyWw
Keep in mind that those on youtube are quite likely sequenced in modern software using soundfonts or other tricks to give the impression of being from a NES, but the end result is probably MP3 or something. An actual NES rom hack needs NES audio data, not just something designed to sound like it.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: WeretigerRei on 2011-07-29 08:56:54
Keep in mind that those on youtube are quite likely sequenced in modern software using soundfonts or other tricks to give the impression of being from a NES, but the end result is probably MP3 or something. An actual NES rom hack needs NES audio data, not just something designed to sound like it.

You are correct. Here is an example.
http://www.youtube.com/watch?v=_mOXdBqyUH4&feature=related

The one I posted above sounds legit but since Im not an audio wizard I cant say for sure. It certainly does sound like it could have come from an NES. I dont detect anything that the NES wouldnt be capable of.

If they used Famitracker then it certainly is legit and you can export to NSF with it. Would have to ask the authors to find out if that is what they used.
Some more stuff I found.
http://www.youtube.com/watch?v=1JvLwZI8GVI&feature=related
http://www.youtube.com/watch?v=RMr3v5FCq-k&feature=related
http://www.youtube.com/watch?v=pgZcmXAHFpc&feature=related
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-07-30 07:11:35
They are already doing music for the original ROM...

However, the ROM I'm working with has quickly become unwieldy, retooling.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Cupcake on 2011-08-01 01:55:53
Halkun, you're absolutely insane, and I look forward to seeing this project advance.  If this winds up compatible with BC, I'll crap myself.  If not out of shock, just to keep true to my word.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: apz freak on 2011-08-01 20:52:57
Hey! Crazy or not I'm interested!  :D
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-08-02 08:21:59
Well, I have good and bad news...

It seems the ROM is a pain to work with because there is next to no documentation on the mapper. It's the only mapper I can see that goes to 2MB, so I'm a little stuck.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Zande on 2011-08-02 13:29:45
Can't you use the source code of an emulator as a documentation for the mapper? Provided it supports it, everything should be in there, aye? Maybe not the most convenient way but still...
If you want some help with the disasm and analyzing I could assist you abit, it's always fun to waste some time with.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-08-03 09:11:52
I found some code from two different emulators that describes how the bank switcher works for Mapper 163. What I was doing was just copying the bank switch code from the original rom, but I 'd like to have an idea of how it works. Here is two code snippets from two different emulators.

I think that $5000 is a security check, and 5001-5003 switch the rom, but are the arguments?

there is also a scan-line interrupt at line 127... I think.
You want to help decipher?

Code: [Select]
//////////////////////////////////////////////////////////////////////////
//           Mapper163  NanJing Games (NES Chinese RPR game)            //
//////////////////////////////////////////////////////////////////////////

void Mapper163::Reset()
{
reg[1] = 0xFF;
strobe = 1;
security = trigger = reg[0] = 0x00;
SetPROM_32K_Bank(15);
SetCRAM_8K_Bank(0);
}

BYTE Mapper163::ReadLow( WORD addr )
{
if((addr>=0x5000 && addr<0x6000))
{
switch (addr & 0x7700)
{
case 0x5100:
return security;
break;
case 0x5500:
if(trigger)
return security;
else
return 0;
break;
}
return 4;
}
else if( addr>=0x6000 ) {
return CPU_MEM_BANK[addr>>13][addr&0x1FFF];
}
return 0;
}

void Mapper163::WriteLow(WORD addr, BYTE data)
{
if((addr>=0x4020 && addr<0x6000))
{
if(addr==0x5101){
if(strobe && !data){
trigger ^= 1;
}
strobe = data;
}else if(addr==0x5100 && data==6){
SetPROM_32K_Bank(3);
}
else{
switch (addr & 0x7300)
{
case 0x5000:
reg[1]=data;
SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) );
if(!(reg[1]&0x80)&&(nes->ppu->GetScanlineNo()<128))
SetCRAM_8K_Bank(0);
break;
case 0x5200:
reg[0]=data;
SetPROM_32K_Bank( (reg[1] & 0xF) | (reg[0] << 4) );
break;
case 0x5300:
security=data;
break;
}
}
}
else if( addr>=0x6000 ) {
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
}
}

void Mapper163::HSync(int scanline)
{
if( (reg[1]&0x80) && nes->ppu->IsDispON() ) {
if(scanline==127){
SetCRAM_4K_Bank(0, 1);
SetCRAM_4K_Bank(4, 1);
}
if(scanline==239){
SetCRAM_4K_Bank(0, 0);
SetCRAM_4K_Bank(4, 0);
}
}
}

void Mapper163::SaveState( LPBYTE p )
{
p[0] = reg[0];
p[1] = reg[1];
}

void Mapper163::LoadState( LPBYTE p )
{

reg[0] = p[0];
reg[1] = p[1];
}

Code: [Select]
/*************************************************************

 Bootleg Board by Nanjing

 Games: A lot of pirate originals

 iNES: mapper 163

 In MESS: Unsupported.

 *************************************************************/

static void nanjing_irq( device_t *device, int scanline, int vblank, int blanked )
{
nes_state *state = device->machine().driver_data<nes_state>();

if (BIT(state->m_mmc_reg[0], 7))
{
if (scanline == 127)
{
chr4_0(device->machine(), 1, CHRRAM);
chr4_4(device->machine(), 1, CHRRAM);
}

if (scanline == 239)
{
chr4_0(device->machine(), 0, CHRRAM);
chr4_4(device->machine(), 0, CHRRAM);
}
}

}

static WRITE8_HANDLER( nanjing_l_w )
{
nes_state *state = space->machine().driver_data<nes_state>();
LOG_MMC(("nanjing_l_w, offset: %04x, data: %02x\n", offset, data));

offset += 0x100;

if (offset < 0x1000)
return;

if (offset == 0x1100) // 0x5100
{
if (data == 6)
prg32(space->machine(), 3);
return;
}

if (offset == 0x1101) // 0x5101
{
UINT8 temp = state->m_mmc_count;
state->m_mmc_count = data;

if (temp & !data)
state->m_mmc_latch2 ^= 0xff;
}

switch (offset & 0x300)
{
case 0x000:
case 0x200:
state->m_mmc_reg[BIT(offset, 9)] = data;
if (!BIT(state->m_mmc_reg[0], 7) && ppu2c0x_get_current_scanline(state->m_ppu) <= 127)
chr8(space->machine(), 0, CHRRAM);
break;
case 0x300:
state->m_mmc_latch1 = data;
break;
}

prg32(space->machine(), (state->m_mmc_reg[0] & 0x0f) | ((state->m_mmc_reg[1] & 0x0f) << 4));
}

static READ8_HANDLER( nanjing_l_r )
{
nes_state *state = space->machine().driver_data<nes_state>();
UINT8 value = 0;
LOG_MMC(("nanjing_l_r, offset: %04x\n", offset));

offset += 0x100;

if (offset < 0x1000)
return 0;

switch (offset & 0x700)
{
case 0x100:
value = state->m_mmc_latch1;
break;
case 0x500:
value = state->m_mmc_latch2 & state->m_mmc_latch1;
break;
case 0x000:
case 0x200:
case 0x300:
case 0x400:
case 0x600:
case 0x700:
value = 4;
break;
}
return value;
}
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Zande on 2011-08-03 21:16:46
Right, so if I've understood the bank system right it works something like this...

There's only one program bank with a size 32k, using the range $8000-$FFFF. The bank is switched with a 12 bit value made up from the values written to $5000 and $5200. The low nibble of the $5000 value is used for the low nibble (bit 0-3) of the bank value, and the whole byte of $5200 is used for bits 4-11 of the bank selection value.
With a 12 bit value for the bank selection, the maximum amount of banks this mapper can handle is 4096 (for max memory of 128 MB)? Oo

Since the entire program bank is swapped at once, the bank swapping code is written to the system ram @$0400, and then executed from there instead (in abit fo a stange way... Oo). Each bank have atleast one bank swap code, in the very end of the bank.
(Can I post/link to dissed code?)

What's $5300 used for? I don't know, but the only value written by the game seems to be $04.


I have to dive thru that thread on romhacking.net...
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-08-03 23:45:11
Cool..

The reason why the bank switching code is at $400 is because you need the Program Counter up there when you do the switch. Switching out a bank while the PC is in the ROM will result in the PC executing code in another bank randomly.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Zande on 2011-08-04 01:08:27
Yepp, it seems to copy 256 bytes into $400 for the bank switching though, but the actual code for the swap is only 19 bytes, ah well. :D
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-08-04 02:09:37
The are several functions that are copied from bank 1 from the $200 -$600 address range at 256 byte intervals

Did you see what it does to the stack? :P
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Zande on 2011-08-04 07:48:13
Did you see what it does to the stack? :P
Nopes, don't think I have yet, what's it do?

Have you compiled together any document with known data inside the rom?
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-08-04 12:27:21
no, just made a space for it in the wiki, the guys over at RHDN have a bunch of locations.
Want Wiki access?
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Zande on 2011-08-04 13:25:21
Hmm, well I used to have wiki access, at least for the FF9 section. :)


Abit of expansion of your savemap info:

$602E-$6030: Gil

$603B: Number of characters in party

$603C-$6042: Character indices/slots
$6043-$6049: Levels
$604A-$6050: Low byte of current HP
$6051-$6057: High byte of current HP
$6058-$605E: Equipped headgear
$605F-$6065: Equipped armour
$6066-$606C: Equipped bracers
$606D-$6073: Equipped accessory
$6074-$607A: Equipped weapon
$607B-$6081: Equipped materia

$60C1-$60C7: Low byte of max HP
$60C8-$60CE: High byte of max HP

All the data from levels to max HP are stored in an array of seven bytes, one by for each character (so for level, $6043 for Cloud, $6044 for Barret etc..).

Also, in bank 0 @$D4F8 ($54F8 in the ROM), there's 56 bytes which contains the initial stats of all seven characters (with 8 bytes each), it's stored like this:

byte Level
byte Headgear
byte Armour
byte Bracers
byte Accessory
byte Weapon
byte Materia
byte Materia Level
Title: Re: Halkun's new Project... Introducing N-gears
Post by: syntax error on 2011-08-13 18:42:42
Still coding or did some problem occur?
Title: Re: Halkun's new Project... Introducing N-gears
Post by: halkun on 2011-08-17 01:54:44
Had a bunch of wind in my sails, but it wound up being too daunting with little return. Trying something else..
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Lugia2009 on 2011-08-20 02:55:11
How is the coding going? If it helps any, I have a little info on how the event system works. And where the events are located.
Title: Re: Halkun's new Project... Introducing N-gears
Post by: ajthedj747 on 2012-03-19 20:23:29
... And this project is still going, right?
Title: Re: Halkun's new Project... Introducing N-gears
Post by: Lugia2009 on 2012-04-14 01:02:07
The project is still continuing over at Romhacking.net
The world map just got done being completely redone.
Also, the battle system has been adjusted a little. Along with Weapons, armor, magic, Enemy and boss stats, and character stats.