Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
1 user currently in Rom Hacking: hukka | 2 guests
Acmlm's Board - I2 Archive - Rom Hacking - Mario 64 - Amazing Stuff | |
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4943/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-12-05 04:49 PM Link | Quote
Just been tinkering around a lot with the game. It seems to have some sort of protection or something? No matter what I do to the compressed level files it just goes into an endless loop.

Anyway, here's some notes:
347A50 - level 6 textures (probably layout too, didn't check though)
3E76B0 - first file before level 1 data
3FC2B0 - level 1 data (ends @ 405A5E with byte sequence EE E4 FF FF)
405FB0 - first file after l1
2AC0EE - some kind of pointer table?
405CCD - pointer to l1?
7CC700 - free space

RAM addys:
07E64E - pointers from 2AC0EE in RAM
0FA45D - in-RAM from 405CCD when in l1
32DDF9 - level #
380608 - reads from 0FA45D loading l1
380574 - reads level number loading l1

;Disassembled from 380574
;$at = 8039000C
;$t2 = 00000001
;$ra = 80380624
lui $t0,8033
lh $t0,DDF8($t0) ;$t0 = level #
lui $at,8039
sw $t0,BE24($at) ;level # -> 8039BE30
beq $zero,$zero,3805A0
nop

3805A0:
lui $t2,8039
lw $t2,BE28($t2) ;$t2 <- 8039BE29
lui $at,8039
lbu $t3,0001($t2) ;$t3 <- ($t2 + 1)
addu $t4,$t2,$t3 ;$t4 = $t2 + $t3
sw $t4,BE28($at); $t4 -> 8039BE34
jr $ra
nop

At both 2AC0ED and 405CCD in the ROM are the bytes 3F C2 B0, which just happens to be the location in the ROM file of level 1's graphics and level layout data. Changing the pointer at 2AC0ED doesn't seem to do anything? Changing the one at 405CCD crashes the game when you go into level 1 (but not level 2, which uses the same textures and music, so it's not either of those). This means this is probably the pointer we need. I wasn't able to repoint the data however. Moving the compressed file to 7CC700 and updating both pointers still only crashes the game when entering the level (it goes into an endless loop). I also tried decompressing the file, deleting some of the graphics (blanking them out for better compression as my compressor is not quite as efficient as Nintendo's) and re-inserting the (now much smaller) re-compressed file but this still only crashes the game, though with real error messages this time. It really seems as if there is some mechanism in place to prevent this from working, but I have got minor results from just making small random edits to the compressed data right in the ROM, so I'm not sure what to think...

Keep in mind that you'll need to fix the ROM's checksum after you edit anything if you want it to actually run.
Squash Monster

New Age Retro Hippie
Togateiru Fohku Kohgeki!!
GRUNGE no HAMSTER otona bite
Peace love and turnpike!

Level: 40

Posts: 601/677
EXP: 430507
For next: 10802

Since: 03-15-04
From: Maryland (of the Country Between Canada and Mexico)

Since last post: 5 hours
Last activity: 5 hours
Posted on 06-12-05 07:25 PM Link | Quote
Above my head, but I can think of a few things:

Maybe there's another pointer to the level somewhere?
Have you found the locations or pointers to any other levels? Could you try repointing level one to one of them?
Could something inside the level data be a pointer to other parts of the level data? For using the same object multiple times, for example.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4948/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-12-05 11:27 PM Link | Quote
I do have a few ideas which I'm going to try out in a minute. These don't really pan out though. I couldn't find any sign of another pointer, I don't know where any other level's data is (possibly level 6 but I haven't tested it, and doing so would be very tedious on such a large level; pointing it to that just crashed it), and since the level data is compressed any pointers inside it that pointed to itself would have to be relative, which shouldn't be affected by being moved. (Unless they could point to things in RAM? Hmm...)

BTW, forgot to mention - the pointer at 2AC0EE seems to be part of a table. It contains a pointer to the first file before level 1's file (3E76B0) and level 1's file itself, but there's also a few between them that don't point to compressed files at all. Changing this doesn't seem to do much anyway, unless it was sound-related. The pointer at 405CCD looks as though it might be in some type of data block, possibly the level header.

[edit] Just thought I'd dump my latest notes into here.

405CCD definetely seems to be part of a level header of some sort.
405CEF - change 05 to 06, game crashes when a water bomb appears
-change to 04 to really screw up graphics - many objects/Mario missing, textures smear, screen duplicates into a small rectangle and flattens, PJ64 gives continuous exception errors but runs anyway

addr: 00 01 02 03|04 05 06 07|08 09 0A 0B|0C 0D 0E 0F 0123456789ABCDEF
405CC0 07 04 00 00|1B 04 00 00|18 0C 00 07|00 3F C2 B0 .............?..
405CD0 00 40 5A 60|1A 0C 00 09|00 32 D0 70|00 33 4B 30 .@Z`.....2.p.3K0
405CE0 18 0C 00 0A|00 2A C6 B0|00 2B 8F 10|18 0C 00 05 .....*...+......
405CF0 00 13 4D 20|00 13 B5 D0|17 0C 00 0C|00 13 B5 D0 ..M ............

405CC0 - 07040000 \
405CC4 - 1B040000 if changed, game crashes > these could be coords/size?
405CC8 - 180C0007 crash on change /
405CCC - 003FC2B0 pointer to level 1 layout
405CD0 - 00405A60 pointer to 2 bytes past the end of level 1 layout file (no file here O_o)
405CD4 - 1A0C0009
405CD8 - 0032D070 pointer to GFX (bars, wall, etc)
405CDC - 00334B30 pointer to GFX (textures)
405CE0 - 180C000A if changed, PJ64 just kinda stops O_o (tried 1810000A and 1808000A)
405CE4 - 002AC6B0 pointer to GFX (clouds, water)
405CE8 - 002B8F10 pointer to GFX (BGs?)
405CEC - 180C0005 graphic-related (value=1.80946e-024)
405CF0 - 00134D20 pointer to GFX (big weird balls - ones that roll down mountain?)
405CF4 - 0013B5D0 looks like a pointer, but doesn't point to a compressed file
405CF8 - 170C000C
405CFC - 0013B5D0 again
note frequent occurrences of 180Cxxxx - 32-bit float, ~1.8

also note pattern:
405CC0 - 07040000 (float)
405CC4 - 1B040000 (float)
405CC8 - 180C0007 (float) <-- pattern starts here
405CCC - 003FC2B0 (pointer)
405CD0 - 00405A60 (pointer)
405CD4 - 1A0C0009 (float)
405CD8 - 0032D070 (pointer)
405CDC - 00334B30 (pointer)
405CE0 - 180C000A (float)
405CE4 - 002AC6B0 (pointer)
405CE8 - 002B8F10 (pointer)
405CEC - 180C0005 (float)
405CF0 - 00134D20 (pointer)
405CF4 - 0013B5D0 (pointer)
405CF8 - 170C000C (float)
405CFC - 0013B5D0 (pointer)

The float-pointer-pointer pattern is very interesting. Most of these point to graphics used in level 1. Changing the floats just seems to crash the game, maybe they tell what to do with the graphics? The pointer at 405CD0 is also intruiging as it seems to point right to the end of the compressed file that holds the level layout. Maybe the game needs to know where the file ends? (But why not just specify its size?) This seems likely as AFAIK the game needs to DMA everything from ROM into RAM, and thus should know exactly how much data it needs before doing so.

[edit again] W0000000T! I was right! To repoint the level layout, you not only have to change the pointer at 405CCC, but also the one at 405CD0 (it has to point to two bytes past the end of the level file - not sure on this, it might just need to point to the next 32-bit-aligned addy). I now have the game running successfully with the level data moved. Excuse me while I change my pants.

[guess what, an edit] Well I can't seem to get anything besides the original level data to work. Even if I just decompress the file, compress it again, and stick it back in, boom. This could mean several things:
  • Some sort of checksum or filesize check.
  • The MIO0 spec we've been using is wrong, or the game isn't following it exactly (maybe some additional technical limitations).
  • Every compression program released thus far doesn't work. (I only know of one other than mine and I don't think it even comes close to working right. Mine seems to work (it decompresses to exactly what went in), but it's possible that the compression has some kind of flaw that causes problems with the game but not with my own decompressor.)
  • Bad decompressor? Looking at the graphics in Tile Molestor, there seems to be one byte missing from the very beginning of the file, but adding a byte there doesn't seem to help. (Bug in TM maybe? Or the game's byte-swapping the graphics?) Both mine and the other give the same output, though.
  • There's more to the process that needs to be figured out.


I'm not giving up yet though. Mario Kart 64 contains code to compress this stuff...


(edited by HyperHacker on 06-12-05 06:27 AM)
(edited by HyperHacker on 06-12-05 08:50 AM)
(edited by HyperHacker on 06-12-05 09:10 AM)
(edited by HyperHacker on 06-12-05 10:45 AM)
(edited by HyperHacker on 06-12-05 10:46 AM)
Violent J

Melon Bug
Level: 41

Posts: 438/749
EXP: 479154
For next: 991

Since: 05-05-04
From: The Lotus Pod

Since last post: 8 hours
Last activity: 8 hours
Posted on 06-13-05 06:11 AM Link | Quote
Whoa whoa whoa whoa. Hold up HyperGeek...Your saying you changed some stuff in the SM64 Rom and finally got it to run it? Does this mean that you can edit the levels layouts?

HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4952/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-13-05 08:37 AM Link | Quote
If you'd read the post, I managed to move the level file without the game going boom. Actually editing anything, though, kills it. And I am not a geek.
Squash Monster

New Age Retro Hippie
Togateiru Fohku Kohgeki!!
GRUNGE no HAMSTER otona bite
Peace love and turnpike!

Level: 40

Posts: 605/677
EXP: 430507
For next: 10802

Since: 03-15-04
From: Maryland (of the Country Between Canada and Mexico)

Since last post: 5 hours
Last activity: 5 hours
Posted on 06-14-05 12:26 AM Link | Quote
It's entirely possible for compressed files to refer to adresses within themselves in a non-relative manner, kindof like how some checksums include the checksum in its own calculation. It's not impossible, just a bitch to deal with.

But it sounds like you're on the right track, I'm willing to bet that the problem is in the recompression. So... I'm curious, where's the MIO0 specification? I've always wanted to try to write a compressor.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4987/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-15-05 03:36 AM Link | Quote
It's possible but I doubt it. Especially since moving the data and not modifying or recompressing it works fine.

The spec is here. I'm not going to try to clean up the HTML.




MIO0 Binary Encoding Specification
Written by BGNG of Godspeed, 06/27/04
=====================================


Data Member Data Type Size
---------------------------------------------------

Identifier Str 4 Bytes
Destination Data Size UInt 4 Bytes
Compressed Data Offset UInt 4 Bytes
Uncompressed Data Offset UInt 4 Bytes
Data Map Prefixes Bits Unspecified
Compressed Data LDPairs Unspecified
Uncompressed Data Bytes Unspecified

*The Identifer is the 4-byte string "MIO0"

*UInts are stored as Big-Endian
*Offsets are base 0
*The bytes decoded tell your program when to stop
*LDPairs are 4/12-bit LZ77 length/distance pairs.



Notes:
======
LZ77 is a compression algorithm based on a series of headers,
compressed "pairs" and raw data. The headers are a series of
bits that, obviously, are either 1's or 0's corresponding to
the next piece of data being raw or compressed, respectively.

If it's 1, just pull the next byte of uncompressed data. If
it's 0, read the next two bytes of compressed data. These
bytes are a 16-bit pair of values, where these values are 4
bits then 12 bits.


The 12-bit value is a Distance value that tells the decoder
how many bytes backwards in the previously decoded data to
go from the end of the decoded data, minus 1. Add 1 to this
value when you decode it.

The 4-bit value is a Length value that tells how many bytes
to read from the Distance position which are to be copied
to the end of the output file, minus 3. Add 3 to this value
when you decode it.

Simply keep track of the current Header, Pair and Raw
offsets in the file you're decoding and you're good to go.
For encoding, it's simply a matter of checking an 18-byte
forward-read buffer with the previous 4096 bytes of the
file, looking for the longest match. If the length of the
match is greater than 2, then the data is compressed. Else,
it's included raw.



Sample File:
============

000000 4D494F300000002C 000000150000001F MIO0...,........
000010 FFAFFBFB40000200 0700130021002254 ....@.......!."T

000020 6865207261696E20 4D65207374617973 he rain Me stays
000030 206D6C79206F6E20 74706C2E mly on tpl.

Identifier: 4D494F30 ("MIO0")
Destination Data Size: 0000002C (44 bytes)
Compressed Data Offset: 00000015
Uncompressed Data Offset: 0000001F
Data Map Prefixes: FFAFFBFB40
(11111111 10101111 11111011 11111011 01000000)

Compressed Data: 0002 0007 0013 0021 0022
(3, 3; 3, 8; 3, 20; 3, 34; 3, 35)
Uncompressed Data:
The rain Me stays mly on tpl.

Output:
The rain in Maine stays mainly on the plain.


And then of course, there's my [de]compressor and its source code. You may want to go through the source code and remove some of the printfs so that it doesn't take ages to compress. I intend to clean that up once it's working perfectly or being used in some other project.
BGNG

Snifit
Level: 22

Posts: 34/276
EXP: 56579
For next: 1771

Since: 06-03-05

Since last post: 8 days
Last activity: 3 hours
Posted on 06-15-05 04:52 AM Link | Quote
Man, whoever wrote that specification is an utter genius. That specification is correct, however; as I've used it to extract zillions of textures from F-Zero X without any flaw at all. And since I've also extracted image data from Super Mario 64 using it, that essentially rules out the possibility that I've documented it incorrectly. There MIGHT be something in there causing problems, but I'm gonna go ahead and say there isn't.

There could be some checksummage in the level data, but I highly doubt that the checksum bytes are included in the calculation. All checksums that I've ever seen substitude zeroes for the checksum field and just put in the calculated value afterwards. Then, when the checksum is checked, it re-substitutes with zeroes to ensure the values are the same.

There may be an issue with the lack of sufficient compression utilities, but if you say that your program gives you identical output as the data you compressed, then that rules out the possibility of incorrect compression; given that your decompressor follows the specification, which it must in order to get that far anyways.

Tile Molester does some stuff incorrectly, as you've noticed. I've seen that it both leaves off the first byte and also ("and also" is redundant, isn't it?) incorrectly shows colors in 16-bit RGBA mode amongst others. It's not too reliable; it's just useful for finding offsets.
__________

The best bet is some kind of checksum dealie. Based on what you've found, I'm willing to bet that the checksum would be in the level data itself. Take apart the file after decompressing it and see if you can find anything.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 4988/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-15-05 09:18 AM Link | Quote
What really bugs me is that none of these theories really pan out. It can't be a checksum because editing the data without moving or decompressing it (just changing random bytes in the compressed data) has got some results (though essentially useless). It can't be a technical limitation that prevents the game from working with too efficient a compression, because Nintendo's compressed the original data much more efficiently than I'm able to. And it can't be (well, I suppose it's slightly possible) a flaw in the compression program because it decompresses just fine.

One idea does come to mind, though. Maybe something based on the file's size? The game might be checking to make sure it's the proper size, or it could just be that it only allocates enough memory for the original file or something stupid like that. (I only once managed to get it smaller than the original by blanking out a lot of the graphics, and I'm not 100% sure all of what I blanked out was in fact graphics. )

[edit] The original thread. Pics are gone though.


(edited by HyperHacker on 06-15-05 12:37 AM)
VL-Tone

Red Cheep-cheep
Level: 23

Posts: 50/200
EXP: 64158
For next: 3565

Since: 06-06-04
From: In the Moon!

Since last post: 5 days
Last activity: 2 hours
Posted on 06-18-05 02:35 PM Link | Quote
I have a little MIO0 decompressor and RGBA to .raw converter running but they are too slow to be released in the wild. I started to look for polygon data in the files, for example I suspect that the Castle data is at 44ABC0. I think I found the vertex list, but I'm not 100% sure about that.

This image is from 44ABC0, showing the Peach glasswork from the castle and the "secret" slide.



The image was cropped, you can also find more data and the Peach letter graphics and her signature in 44ABC0.

Here is an image from 49E710...


Hey look it's the "Sorry we didn't have time to make a real ending sequence to Mario 64" cake image extracted from the ROM

By the way, I guess most of you saw that fake Revolution video called "Nintendo ON". The last part of the video was creepy, but I was really impressed by what the guy did with the Mario 64 castle. The model is just about exactly the same, so I suspect that he already did decode it from ROM, but didn't tell the ROM hacking community about it.

Or maybe he just looked at this map




(edited by VL-Tone on 06-18-05 05:41 AM)
(edited by VL-Tone on 06-18-05 05:43 AM)
(edited by VL-Tone on 06-18-05 05:53 AM)
(edited by VL-Tone on 10-26-05 11:50 PM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 5063/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 06-19-05 05:09 AM Link | Quote
Niiiice. What algorithm are you using to get the right colours? I couldn't get them to work.
BGNG

Snifit
Level: 22

Posts: 45/276
EXP: 56579
For next: 1771

Since: 06-03-05

Since last post: 8 days
Last activity: 3 hours
Posted on 06-19-05 05:22 AM Link | Quote
It's 16-bit RGBA. rrrrrggg ggbbbbba

Channel values are, of course, 0 to 31. To convert this to 24-bit RGB, which you probably know anyways, take any channel value X: Result = X / 31 * 255
Cellar Dweller

Flurry
!!!
Level: 27

Posts: 224/269
EXP: 107817
For next: 8342

Since: 03-15-04
From: Arkansas

Since last post: 16 days
Last activity: 34 min.
Posted on 06-19-05 12:41 PM Link | Quote
All of the compressed files in SM64 have the backreference list start on a dword boundary. The decompressor in the game may depend on that condition. If so, could that account for the reinsertation fKitten Yiffers?

Could there be related data immedetly following the compresssed file?

HyperHacker: Does your compressor pad the data map to a multiple of 4 bytes so that the backreferences start on a dword boundary?

BGNG: I'd make that "Result = X * 255 / 31" so that integer only calculations do not round any value of X other than 31 down to 0.
VL-Tone

Red Cheep-cheep
Level: 23

Posts: 51/200
EXP: 64158
For next: 3565

Since: 06-06-04
From: In the Moon!

Since last post: 5 days
Last activity: 2 hours
Posted on 06-19-05 02:00 PM Link | Quote
I've been dreaming of achieving this for a long time....

Here it is! Peach's Castle is at 44ABC0 !! easy as ABC

Yes it's decoded from the ROM and yes it's low poly It's Mario 64, not Super Mario Sunshine!

No textures for now, and obviously I've not cracked everything yet.









Here is the back of the castle, you can see the room you fall into using the infamous "fall into the castle" glitch.
The main castle tower is a different object than the rest of the castle so I guess it has something to do with it.


I'm too tired to explain how it was done, but here are some adresses in the 44ABC0 decoded MIO0 file.

Castle Field Tower
Vertex Lists: 3000 6F98 96F8 A328 A8D0 B240 BD50 C2A0
Triangle Lists: 5F60 89F8 9FD8 A728 AFD0 B820 C070 C3A0



(edited by VL-Tone on 10-26-05 11:53 PM)
Kyoufu Kawa
I'm not bad. I'm just drawn that way.
Level: 70

Posts: 1648/2481
EXP: 3008456
For next: 7355

Since: 03-19-04
From: Catgirl Central

Since last post: 14 hours
Last activity: 13 hours
Posted on 06-19-05 02:30 PM Link | Quote

Holy mother of Jehosephat!
I wake up to THIS!? Today is a good day.
The Kins

Kodondo
Level: 38

Posts: 516/595
EXP: 354733
For next: 15714

Since: 03-15-04
From: Melbourne, VIC, Australia

Since last post: 2 days
Last activity: 9 hours
Posted on 06-19-05 02:31 PM Link | Quote
Pardon my language, but holy fucking fuck.
BMF98567
BLACK HAS BUILT A SILLY DICE-MAZE!
GO!

Current list of BURNING FURY >8( recipients:
- Yiffy Kitten (x2)
- Xkeeper
Level: 53

Posts: 937/1261
EXP: 1094149
For next: 62970

Since: 03-15-04
From: Blobaria
Special Move: Rising Meatloaf Backhand Combo

Since last post: 21 hours
Last activity: 1 hour
Posted on 06-19-05 02:51 PM Link | Quote
SWEET MERCIFUL CRAP.

"Impressed" just...isn't the right word...English...fails.

(So, umm, can Mario walk on that geometry, or is there separate data that defines solid areas of the map, a la Goldeneye? I'm such a n00b when it comes to newer consoles...)
richyawyingtmv

Koopa
Level: 15

Posts: 2/116
EXP: 14829
For next: 1555

Since: 06-14-05

Since last post: 15 hours
Last activity: 14 hours
Posted on 06-19-05 02:52 PM Link | Quote
Amazing.........

I think its time to change the name of this thread now dont you think?
Kyoufu Kawa
I'm not bad. I'm just drawn that way.
Level: 70

Posts: 1651/2481
EXP: 3008456
For next: 7355

Since: 03-19-04
From: Catgirl Central

Since last post: 14 hours
Last activity: 13 hours
Posted on 06-19-05 02:58 PM Link | Quote
"Mario 64 - Now it's REALLY getting interesting!"
Cellar Dweller

Flurry
!!!
Level: 27

Posts: 225/269
EXP: 107817
For next: 8342

Since: 03-15-04
From: Arkansas

Since last post: 16 days
Last activity: 34 min.
Posted on 06-19-05 03:01 PM Link | Quote
Originally posted by BMF54123
(So, umm, can Mario walk on that geometry, or is there separate data that defines solid areas of the map, a la Goldeneye? I'm such a n00b when it comes to newer consoles...)


I'd say the latter. When I was able to mess up just a few polygons in the Bob-Omb battlefield by corruption, Mario moved as if nothing had changed.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Rom Hacking - Mario 64 - Amazing Stuff | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.040 seconds.