Guitars! Guitars!! Guitars!!!

So we’re getting really close to the release of Guitar Hero II Deluxe, whose still-WIP site I’ve posted on here before. The disc is maybe a few days out from an RC, which is sweet, and yet somehow, we’re still finding shit to add to it. Case in point, the topic of additional guitars has come up a few times:

The GH2DX team discussing guitars

Aside from a few new ones people requested thrown in, I really wanted to bring back all of the guitar finishes from the first Guitar Hero that Harmonix neglected to bring to the second game. And there were a surprising few of them! Any of the custom finishes, stuff like a Cracked Ice Blue Flying V, a Psychedelic Firebird, a “Night Dragon” Moderne–gone from the second game. It’s always pissed me off that we lost the Skunk Baxter Copper Metallic Firebird, an absolute beauty of a guitar, for a really lame, crappy leopard print one. That all had to get fixed.

Now, I’ve had vague experience porting guitar skins over by pasting them over existing ones, so I knew that in a lot of cases, the finishes were interchangeable between the games. See, only for the really prominent guitars (Les Paul, SG, etc.) did Harmonix bother to shift anything in the UV map. For anything from the Firebird down, the UV maps are identical–meaning you just need to copy the texture maps over and they work. (Little less than that, even, but I’ll get back to that.)

I’ve posted about what a pain custom textures in GH2 used to be, but with superfreq converting between PNG and .tex, no muss no fuss, the process is way simpler. I dove in because the other guys were busy trying to get bass in quickplay working.

Now, the first thing I was reminded of is how godawful GH1 is internally. I mean, it’s a mess. You wouldn’t expect two games that came out in the span of a year from each other to be so different, but GH1 is far closer to Amplitude, from 2003, than GH2. (The T1 GEMS track for singleplayer notes bears that out; Amplitude has T1 DRUMS, T2, T3, etc tracks in its MIDI for the various instrument parts.) Naturally, all the textures were stored separate from the models and I had to dig out the old Image Converter to get them converted to BMP so I could make use of them.

But then I actually got to taking apart GH2’s milos, and I realized something: most of the skins that didn’t make it into the second game are still in its files:

Unused GH1 skins in GH2's files

Thus, the easiest part of the process was simply making the game look for these other skins. Now, there’s two components to getting a guitar to appear in-game, and that’s guitars.dta and store.dta. These are both purely data (read: no functions) kinds of DTAs, arrays stacked inside arrays (as that’s what parentheses means in Data Array). store.dta is the less important of the two, since it just allows the skin to be bought by the player, while guitars.dta is what makes the game actually recognize the new skin. I’m focusing on the latter here.

The first item in an array always defines the shortname the game uses to identify the array by, and then any other items in the array define the type (guitar or bass) and then any skins that go to that guitar. Looks a bit like this:

(firebird
   (type guitar)
   (skins
      (fb_burst
         (outfit firebird)
         (mat guitar_firebird.mat))
      (fb_blue
         (outfit firebird)
         (mat guitar_firebird_blue.mat))
      (fb_copper
         (outfit firebird)
         (mat guitar_firebird_copper.mat))
      (fb_hippie
         (outfit firebird)
         (mat guitar_firebird_hippie.mat))
      (fb_ebony
         (outfit fb_ebony)
         (mat fb_ebony.mat))
      (fb_leopard
         (outfit fb_leopard)
         (mat fb_leopard.mat))))

Literally, all you need to do to restore function in those extra skins? Is write a new item in the skins array, defining outfit (which is the .milo_ps2 model to use) and mat (which is the material in that model file to use). That’s it. Here’s what you get out of that.

The Psychedelic Finish Firebird, restored to GH2
The game doesn’t require localization strings to function in most cases, and naturally, there aren’t any for the unused skins. It’s a cinch to write new ones in, though.

This got me about 90% of the way there, but two of the skins actually did have slightly different UV maps, so those needed proper graphic touchups. (Thankfully, without a hitch.) A third, the Green Lightning Double Cutaway Les Paul, worked the same, but had to have its texture map copied over. And that brings us to the other bit of guitar stuff I did recently, that being adding new skins to a milo altogether. While GH2 puts its textures alongside the meshes, which makes sense, it still requires a bit of work to get them going.

You see, there’s actually two components to a guitar texture, the .mat file and the .tex file. This is roughly analogous to VTFs and VMTs in Source, where the game will look for the .mat file and the .mat file will refer to the .tex file. This is so it can actually refer to multiple textures if need be, like environmental maps for faked reflections.

Now, thankfully, you can just copy an existing .mat, rename it, and rework it in a hex editor, and when you rebuild the milo (and add it to guitars.dta), the game will recognize it fine. I ran into a small issue the first time I tried it, however:

A crash resulting from a malformed .mat file
Don’t let that innocent “press any button” message fool you, this was a proper crash. Something about memory corruption due to a bad string length. (Bless the debug ELF though.)

And as I soon learned, this was actually because there’s an integer in the file a few bytes before the string referring to the .tex that defines the length of that string in hex. I’d changed the name of the skin, but it was trying to read a few null bytes after the fact as part of the .tex name and thus crashing. You can see it in the few spaces after the texture name in that crash screen. (Protip: if you can’t easily convert between decimal and hexadecimal, use the Windows Calculator in Programmer mode. Very useful.)

Peeking at a .mat in a hex editor
I’ve highlighted the relevant byte so you don’t miss it. redoctane_cherry.tex is 20 characters, and 20 in decimal is 14 in hexadecimal. Thus, you fill in 14 for that byte.

After you’ve updated that with the proper length of the string, just rebuild the milo and tell the game to look for the new .mat in guitars.dta. If you’ve done it right, stuff should work:

A totally new skin in GH2
Replacing skins? What is this, 2007? You still using GHEx? Nah, fuck that. This is a brand new one.

In total, implementing new skins, reimplementing existing ones, writing new descriptions–about 9-10 hours of work total over last night and today? Here’s a video of all that work, coming soon to a copy of GH2DX near you:

Beyond that, I’m finishing up one more chart for the disc (a semi-secret one :marfpeek:) and getting the site done. Then I’m probably done with heavy lifting on GH2 for a bit. I was getting real into drawing last night, after like five months of fuckin nerves. Good thing I’m dating a girl who draws a like a motherfucker, yeah?

Leave a Comment