Points of Required Attention™
Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,482,840
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 04-25-24 06:27 PM
Guest: Register | Login

0 users currently in ROM Hacking | 2 guests

Main - ROM Hacking - F-Zero? New thread | New reply

Pages: 1 2

GuyPerfect
Posted on 06-23-07 05:16 AM Link | Quote | ID: 48762


Paratroopa
Level: 30

Posts: 74/155
EXP: 152592
Next: 13277

Since: 03-14-07

Last post: 6044 days
Last view: 5993 days
That would explain the magical "fixes itself" I was seeing. Even if you screw up the first few path values, the machine will somehow correct itself on the second half of the lap. I knew it had to load in another reference coordinate pair, but I didn't know how to find it. Good job tracking it down.

smkdan
Posted on 06-23-07 05:52 AM (rev. 3 of 06-23-07 07:12 AM) Link | Quote | ID: 48785


Ninji
Level: 36

Posts: 32/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
I spoke too soon, there's more of it. 1B more 'coordinates'. When you destroy the coordinates I listed before, it seems to turn around and head to the large diagonal straight, and it turns away and heads there again when it reaches just before the finish line.

Part one (17h)
174A3 - 174BA X
174DE - 174F5 Y

Middle Value 1
160A8 X
160AA Y

Part two (06h)
17695 - 1769B X
1769C - 176A2 Y

Middle Value 2
160B1 X
160B3 Y

Part 3 (1Bh more)
174C2 - 174DD X
174FD - 17518 Y

I see what the other 16bits than comes with the length counter does. It's an index added to the base ROM address supplied during the start and between transitions.

The value is 3A1Fh, where 3A is the length counter and 1F is the index. Because it's this that's compared to the length (Part two had 0600h for example), 3A-1F=1B is the actual length.

Changing everything here effectively destroys all the last remnants the AI had, the car does nothing that hints it knows the track. I changed to all 00's. I said that the car drove to the diagonal straight when one of these parts was modified, well reverse detection just happens to kick in here the moment you enter the area.


Heian
Posted on 06-23-07 09:36 AM Link | Quote | ID: 48853


Red Koopa
Level: 27

Posts: 70/126
EXP: 111883
Next: 4276

Since: 03-08-07

Last post: 5846 days
Last view: 5845 days
VL-Tone! Great to see you back! It was your giant track PNGs that I was trying to find before. How did you make those? I'm interested in making new courses first (since we can always do time trials on those) and then worrying about computer AI.

If you made those PNGs directly from the ROM data, does that mean that you figured out the relationship between the 2-byte pairs and the 2x32 "strips" that they define? Once we can make new strips, we can make new courses.

Smkdan, that old F-Zero thread was on the "old" Acmlm board, so it probably would have taken some digging to find it. Look through that thread (from 2004!) and you'll see us slowly slogging through all the basic stuff from this game -- at the time the inner workings of this game were like a complete mystery.

And Guy, did you generate that map from the X and Y values that you found, or did you just draw it as an approximation? I'm wondering why the game defines so many points in places where they don't seem to be needed. The 5 points down the backstretch, and the 3 following the starting point, don't seem to do anything -- the car could just head for the point right before the next curve without any problems, right?

(I ask this because I'm designing a TrueType font for one of my grad courses, and if the Mute City 1 course were a letterform, all those points would be deleted.)

smkdan
Posted on 06-23-07 12:52 PM (rev. 2 of 06-23-07 01:48 PM) Link | Quote | ID: 48880


Ninji
Level: 36

Posts: 33/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
If I saw that topic in the archives I probably wouldn't have made this thread. Spent a fair bit of time reinventing the wheel.

Heian, I put what I hope to be a fair description of the track format on my site (first post). Everything is in place, it even conforms to VL-Tone's posts in the archive. I hope it makes sense to someone. Conditional course modifications are up there too. 2x2 panels / 64x64 tiles are changed per entry.

Heian
Posted on 06-23-07 02:33 PM Link | Quote | ID: 48893


Red Koopa
Level: 27

Posts: 72/126
EXP: 111883
Next: 4276

Since: 03-08-07

Last post: 5846 days
Last view: 5845 days
SMkdan, I'm looking at your 26th and 27th posts (made on June 20) and am still figuring out what your explanation says! ^^;

Could you give us amateurs a straight-from-the-game example of how those bytes pull data from that 3rd table and bring about the lines of 2x2-tile squares? Table 2 -- the row pointer table -- in particular is giving me fits. What exactly does 'is indexed by' mean, in your document?

Long ago, knowing nothing of how it worked, I saw a number of "BE 71" bytes following the 32x16 Big Blue panel layout. I turned just the first one to 'C4 C4', arbitrarily experimenting, and got:






VL-Tone
Posted on 06-23-07 03:49 PM (rev. 3 of 06-23-07 03:50 PM) Link | Quote | ID: 48899


Micro-Goomba
Level: 10

Posts: 4/12
EXP: 3292
Next: 1122

Since: 02-22-07

Last post: 6101 days
Last view: 5666 days
You might take a look at another archived F-Zero thread where I explained to you how the track data is stored. http://acmlm.no-ip.org/archive2/thread.php?id=12682 Maybe you'll understand it better now, though I'm sure I could give a better explanation now if I had the time.

Essentially, the whole track is compressed using 4 layers of LZ-like compression. (Track/Panels/Rows/2x2Tiles)

For each layer, you have two elements: a list of pointers, and the non-repeating data referred by these pointers.

Changing only the pointers is very limiting, I tried to build an editor by doing that and quickly realized that it wouldn't work. To make any serious arbitrary changes to tracks, they would need to be decompressed, then re-compressed. That means the track data could vary in size when re-compressed, so we would have to extend the ROM and put the track data where space is not an issue. That in itself wouldn't be that hard.

Like I said at the end of the clipping I posted bellow, the hard part of making an F-Zero track editor/creator would be building a tool to assist the user when "drawing" these huge tile-based tracks. I had imagined a program that could easily draw diagonals at various angles of those "spheres" delimiting the track without having to manually click on hundreds of 8x8 tiles.


So here's one of the post I made in this old thread:


Let me try to make a simple explanation.

The basic graphic tiles are 8x8 pixels. Track panels are 256x256 pixels which means 32x32 basic tiles.

What defines what goes inside the panels are 16 pointers that are each 2 bytes long (16-bits).

Each pointer represents a row which is composed of sixteen 2x2 basic tiles graphics.

The number indicate what part of the row data will be used to display this particular row.



The whole row data itself is composed also of 2 bytes numbers but this time pointing to tile data.

The whole row data is uncompressed and starts at $10C13 in a ZST state for a particular track.

Each 2 bytes value in the row data is a pointer that represents a 2x2 basic tiles graphic.


The 2x2 tiles graphics data are also stored elsewhere, starting at $64580 in ROM.

Tile data is using one byte for each 8x8 pixels tile. So for each basic 2x2 tiles graphic 4 bytes are used.

Here is the 256 tiles set used by the tile data for Mute City (it's not the tile data itself)



If anyone already has the full set of these graphics for all tracks with all palette variations I would really need that. As you can see that palettes are off in some of my maps as I only have some of the graphic sets.

Anyway I guess the reason why it can get confusing is that the same thing is happening at several levels. The same "compression" method is used at the row and tile level, and actually it works much the same across the whole hierarchy of track parts:

Track/Panels/Rows/2x2Tiles/SingleTiles

If there is any part you don't understand, don't hesitate to ask...

Don't get too over hyped about editing the tracks. Even with this data, editing will be hard, unless someone designs a special tool to draw arbitrary tracks that would be then re-compressed as new panel, rows and tile data. That's how I think Nintendo proceeded, there is no way they worked by hand at the row and tile level unless they are really crazy

GuyPerfect
Posted on 06-23-07 06:27 PM (rev. 2 of 06-23-07 06:33 PM) Link | Quote | ID: 48919


Paratroopa
Level: 30

Posts: 75/155
EXP: 152592
Next: 13277

Since: 03-14-07

Last post: 6044 days
Last view: 5993 days
Heian
The data was generated from the data I found in the ROM. There are so many points for two reasons. 1) When you bump into the wall, the game repels you towards the "next" point along the way. If it was too far up ahead, you'd be bumped at a very odd angle. Didn't GP Legend do that? 2) The AI uses the points to drive. If you got one off-center, it would slowly drag itself back to the center of the course because it's only heading to the next control point.

VL-Tone
The idea we came up with when pulling apart F-Zero Maximum Velocity was to have the editor come with expandable definitions for "meta panels"; groups of track parts that could be puzzled together fairly easily. While the exact panels in the game vary, certain combinations could be moved as though they were panels in themselves, making something akin to Climax's editor.

smkdan
Posted on 06-24-07 05:01 AM Link | Quote | ID: 49035


Ninji
Level: 36

Posts: 34/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
Guy I'm a bit confused on how you generated that data. I listed 3 'sections' of AI data. What ranges of them did you use? X and Y are stored differently from what i'm seeing.

GuyPerfect
Posted on 06-24-07 05:06 AM Link | Quote | ID: 49037


Paratroopa
Level: 30

Posts: 76/155
EXP: 152592
Next: 13277

Since: 03-14-07

Last post: 6044 days
Last view: 5993 days
0x176A2 - 0x176DB for X and 0x176DC - 0x17715 for Y. Again, the low-order byte was Not'd.

smkdan
Posted on 06-24-07 11:03 AM (rev. 2 of 06-24-07 03:25 PM) Link | Quote | ID: 49143


Ninji
Level: 36

Posts: 35/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
I don't know how I missed this...

1) When you bump into the wall, the game repels you towards the "next" point along the way.

That explains why changing these points / starting coordinate ruined collision. If the next point closest to you was out of range, you'd be dragged along the 'nothingness' following the same path as the AI. I picked the Wild Goose for the extra mileage and followed the rival car into the nothingness and as I got pulled in I followed my rival, even changing direction when my rival did.

EDIT: I got a graphing program suited for it, so here's a Mute City 1 AI map from RAM. They're plain enough coordinates to plot from. As stated before, there's 59 points.

7E:1200-1274: X coord words
7E:1400-1474: Y coord words



I understand how they're stored in ROM (8 bits exapanded to 11 excluding 'middle bytes') , just makes me wonder why the segmented it like that. Doesn't look like a very hack friendly layout.

GuyPerfect
Posted on 06-24-07 06:56 PM Link | Quote | ID: 49172


Paratroopa
Level: 30

Posts: 77/155
EXP: 152592
Next: 13277

Since: 03-14-07

Last post: 6044 days
Last view: 5993 days
I actually mentioned that earlier in the thread.

Posted by GuyPerfect
As a machine glides across the course, it travels over each of the path points, in order. That's how the game knows when you're facing the wrong way, etc. When you drive on a tile on a panel that you're not supposed to drive on, the game says "OMFG Collision!" and pushes the machine back towards the path point they're supposed to be on while administering a little damage.

If you modify the track but not the path, you have to be very careful not to step in the wrong spot. If you do, it'll painfully drag you across the netherworld until it puts you back where it thinks you're supposed to be, which may very well be in the middle of nothingness itself, causing your machine to blow up.

smkdan
Posted on 06-26-07 08:26 AM (rev. 3 of 06-27-07 08:12 AM) Link | Quote | ID: 49706


Ninji
Level: 36

Posts: 37/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
Guess I neglected the first page a bit. Anyway, I got a solid handle on the path data. There's some stuff it's loading along with it that I'm not sure what it plans to do with it, but most of the stuff that effects the path is sorted. A 'master table' per track which has say, 3 entries for Mute City 1 (3 segments), each of which have length counters / indexes, 'Middle values' shown earlier, a pointer to a subtable to get the X and Y offsets in ROM along with some other stuff and a byte which signifies that the load is complete (non zero on real tables).

For the format, the game is treating bytes as if they're signed. Quick example:

7F: 7F << 3 = 3F8. 'Positive'. It simply adds that to the last value.

80: 80 is 'negative', it first sets all the high bits. Now you have FF80.
FF80 << 3 = FC00 when trimmed. This is simply added to the last value.

If the last value was 1000h, you'd get C00h. A byte in ROM of 80 would effectively subtract 400h, one of FF would subtract 8.

GuyPerfect
Posted on 06-26-07 06:58 PM Link | Quote | ID: 49814


Paratroopa
Level: 30

Posts: 79/155
EXP: 152592
Next: 13277

Since: 03-14-07

Last post: 6044 days
Last view: 5993 days
Could you give a more thorough explination of the path data in ROM, describing what it is you mean by 'Midle Values' (I'm lost as it is, and your quotations don't help either), and working specifically with the Mute City I data?

Basically, if I were to write a program to pull the path out of the ROM (hint, hint), what would I need to do?

smkdan
Posted on 06-27-07 03:22 PM Link | Quote | ID: 50141


Ninji
Level: 36

Posts: 38/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
I've uploaded a work in progress write up of the path data under 'Checkpoints'. The main table for Mute City 1 is at 1609A headerless. All the data for loading the path and how it is done stems from this table.

Heian
Posted on 06-29-07 01:21 PM Link | Quote | ID: 50665


Red Koopa
Level: 27

Posts: 73/126
EXP: 111883
Next: 4276

Since: 03-08-07

Last post: 5846 days
Last view: 5845 days
OK VL-Tone, I think I've finally got it. Your and SMKdan's explanations go from big to small, whereas I'm trying to imagine how the course starts with the little tiles and then builds the 2x2-tile 'macro-tiles', then the rows, then the big panels.

Forgive my slonwess, but using your examples, is this correct?



* From this set of 256 mini-tiles (8x8), a 'macro-tile' is made from four of them, like this:



They're stored in the order 'upper left, lower left, upper right, lower right', so at index 0F19 somewhere in the ROM ('table 3') we'll find 9A 9A 9B 9B.

* The game then strings 16 of these macro-tiles to form a row. One row that contains macro-tile 0F19 is this one:



...stored at index C676 in 'table 2'.

Since that row is used many times -- namely rows 4 through 10 in the large 'panel' here:



...we'll find "C6 76 C6 76 C6 76..." in the table where Sand Ocean's panel composition is described, possibly elsewhere if other courses have the same stuff at their starting lines.

So the game isn't actually compressing this stuff; it's just creating re-usable chunks of intermediate size because at the 32x16-tile 'panel' level too much data is re-used, and laying out thousands of tiny tiles is similarly unwieldy?

And what we course-makers might want to do is to re-arrange these 'macro-tiles' (keeping their structure intact) into new rows, and/or re-arranging existing rows into new panels?

smkdan
Posted on 06-29-07 02:41 PM Link | Quote | ID: 50673


Ninji
Level: 36

Posts: 39/238
EXP: 288633
Next: 19477

Since: 05-26-07

Last post: 4062 days
Last view: 4011 days
Tables 1 and 2 appear in RAM as you see them in ROM. Table 3 is compressed. Every 16bits in ROM that corresponds to table 3 has 2 bits belonging to another entry that's unpacked when storing to RAM. It's pretty simple but I see it being very frustrating working on it solely with hex. A visual editor + decompressor would be really handy for that.

It looks like you got it right Heian. If it was stored in simple 8x8 fashion (1024 x 512 tiles), it would be just as big as the ROM image itself. The reusable style cuts it down to 23k~ for the Mute City set for example.

And what we course-makers might want to do is to re-arrange these 'macro-tiles' (keeping their structure intact) into new rows, and/or re-arranging existing rows into new panels?

That's about right. I envision a panel editor, which decomposes panels to 32x2 rows, which allows the user to select 2x2 tiles from the global tile pool to construct new rows, and to construct new panels from these new rows. Luckily, it uses 24bit pointers so you can relocate the track data if you want to exceed the size of an original track.

One concern I have is the 16bit pointers for just about everything else. For variable length data like the path points it's a real concern. You're confined to a 32k space of which you don't have much room to work with. The loaders would need to be re written to allow for a 24bit pointers for any real flexibility (i.e. you don't impose a maximum of 3A points for Mute City or 63 for Port Town). SMK is really flexible in this regard since it uses 24bit pointers for just about everything. You could expand the ROM to 4MB and happily stick whatever you please whereever you please.
Pages: 1 2


Main - ROM Hacking - F-Zero? New thread | New reply

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.026 seconds. (340KB of memory used)
MySQL - queries: 112, rows: 147/148, time: 0.018 seconds.