oh right it /might/ generate one at runtime
56 comments
what if I just extended the "conditions" function to add a new datatype, which is HUGE HEX STRINGS that get dumped to the log? Delightfully devilish, Foone! I'm now sorting fonts by how big they are, since I can see their load sizes and compare them against the files on the disk. A full boot of this game loads FIVE fonts. I know the IDs of three, and the names of TWO I found another by dumping all resources that were 2,528 bytes long and then hex editing them to see if they're a font buh suspicious okay so I figured out when and where that one is loaded so I miscounted. 6 fonts. I have names for three, IDs for 5, and source files for 4. I could get the final source file if I could parse the Weird Bundle, and I could get the filenames if I could parse the filename trie. ANYWAY I think I have what I need for my current hax this font file ALMOST makes sense. Like I'll look at 19 out of 20 characters and they'll match perfectly and then one will just be completely wrong. well I manually extracted the hidden font, good ol' GENERICFONT.FDX.PRD. NOPE! it's similarly aligned, so it's not the right one either. the fuck? okay after matching all the dumped textures with the fonts by process of elimination, this is the font I want: that symbol in the top left, which appears to render as "ss", is §. what the fuck are they doing, exactly? there is a SLIGHT chance that it's actually ß and they invented a new encoding that's a hybrid of utf-8 and MacRoman. But I really, really hope not why is this function being called with this->__vt set to 5? I'M PRETTY SURE YOUR OBJECT'S VTABLE IS NOT AT ADDRESS 5, GAME especially considering that this is PowerPC and it'd presumably generate an unaligned address fault, and OH YET THE WII HAS NO MEMORY MAPPED AT 0 So it's a 16-bit RGBA color format. You might say "I can do basic math, and 5+5+5+3 isn't 16", but guess what: it's weirder and worse than you imagine! it's two formats combined into one. well I tried to decode one these images and I got this. I think that's supposed to look like this, just guessing from the dumped textures. oh yeah it's a blocked format, because Nintendo hates the idea of storing pixels in an order that makes sense this is a 32bit console doing 3D rendering! okay I can decode it now. I basically just took my existing parsing code and made it pretend every texture was 4x4, then ran it (width+3)//4*(height+3)//4 times for the whole image, compositing all the subimages together. ugh. I'm like 99% sure the game's texture format doesn't store the size. ah-ha. look at this. both res_ids are identical, but one is only 16 bytes, uncompressed. This is a res_id for a texture. and 16 bytes is exactly the same size as the WiiTextureHeader structure used by the engine! so they have two copies of the resource in the file, but one of them has different FLAGS, which presumably indicates "hey this is the metadata", which has stuff like the texture format and image size. both of them. I'm gonna have to modify the extractor I'm working on to do two searches and find the CFLAGS=64 version, get the metadata, then extract the other one separately. the datafile has 1938 matches for "CFLAGS 64", so... does this game have 1938 separate textures? maybe! fun fact: just about every other game and file format in the world solves this complex problem by JUST PUTTING A FUCKING HEADER IN THE FILE WHAT ARE YOU DOING okay having written an extractor for that format, I move onto the next format: GX_TF_RGBA8. OH GOD NOPE. So a 4x4 RGB8 chunk looks like this: ARARARAR ARARARAR my favorite part is that nintendo literally calls this RGBA when it's not in RGBA order. re-parsed. OH GOD THEY CHANGED THE BLOCK SIZE FOR GREYSCALE IMAGES NINTENDO IS JAPANESE FOR "I HATE THE VERY IDEA FOR MAKING ANY FUCKING SENSE" oh wow. I parsed IA8 correctly on the first try! (it is, of course, in AI byte-order) the final format I need to implement is GX_TF_CMPR, which is a variant of DXT1 texture compression, in 8x8 blocks. JUST KIDDING! it's implemented as four 4x4 sub-blocks. so for each subblock, there's 64 bits. so the two numbers are compared, and either way, c0 and c1 are RGB 5:6:5 colors. if c0 is bigger than c1, then: but if c1 is bigger than c0, then: so now you have 4 colors, c0 through c3. The final 32 bits of the subblock is an index into this palette, with two bits per pixel. so yeah. dxt1 works by having you define two colors, they get an extra bit of metadata by making the order of the colors important, then generate 2 more colors based on those colors + metadata. |
I'm gonna have to figure out how to dump these fonts out of RAM.
in an emulator with no scripting support.
ugh