For education purposes only · no game files included · bring your own THUG2
Chapter 3
thug2 · 15614f7 · "Main menu wheel entries fix"

Wheel of Looogie

THUG2's main menu is a giant wheel, painted like a carnival game, that your skater grabs and spins. It's the best main menu in the series and nobody will convince me otherwise. In the port, the wheel spun beautifully. The words on it didn't. They sat flat, ignoring their spokes, while the wheel turned underneath them like it was somebody else's problem.

THUG2's main menu: the Wheel of Looogie with its labels along the spokes, STORY MODE highlighted, the skater standing next to it.
After: every label rides its own spoke. Before: the same words, flat, like they'd missed the memo.

1Turn anything, not just pictures

The wheel is built from screen elements: a container, and a label per spoke. Each label has a rot_angle. THUG1 only knew rotation on sprites, the picture elements, and THUG1's menus never turned anything else. So the labels' angles were read, nodded at, and ignored. Rotation moved up to the base class, where every element gets it:

diffCode/Gfx/2D/ScreenElement2.cpp · 15614f7

2Children go where the parent turns

Turning the label isn't enough: a label sits somewhere on the wheel, and when the wheel turns, that somewhere moves. THUG1 added a parent's position and scale to its children and stopped there. THUG2 also turns the child's anchor point around the parent's, and adds the angles up:

diffCode/Gfx/2D/ScreenElement2.cpp · 15614f7

Every 2D element in the game now inherits its parent's rotation. Every single one, including a balance meter that was already turning its arrow by hand. That one sends a bill in chapter 5.

3Text that tilts

Sprites could always be drawn turned. Text couldn't: in THUG1, a string is a row of glyphs marching left to right, forever horizontal. The text request got a rotation and a pivot, and each glyph quad gets turned about it before it's drawn, shadow included. One more THUG2 detail: internal_just, which centers each label on its spoke instead of hanging it from the top.

diffCode/Gfx/2D/TextElement.cpp · 15614f7

4Sixteen pixels of history

With everything turning, the labels turned around the wrong point: close to the wheel, but not on it, like a sticker slapped on by someone in a hurry. The 2D wheel and the 3D wheel model it sits on were 16 pixels apart, vertically. Sixteen is a suspicious number. The Xbox draws the 640×448 logical screen 16 lines down inside its 640×480 output (screen_conv_y_offset = 16), and THUG2's menus were laid out for that. The THUG1 port had dropped the offset because THUG1's menus never cared. THUG2's do.

diffCode/Core/macros.h · 15614f7

And the 3D-to-2D projection takes the offset back out, so things pinned to 3D objects stay pinned.

5Skip the intro, keep your sanity

Every test run started with the full set of intro movies. Dozens of runs a day means watching the Activision logo more often than anyone at Activision ever did. One environment variable fixed that:

diffWn32/Code/Plat/Gel/Movies/p_movies.cpp · 15614f7

Where it landed

The Wheel of Looogie, labels and all, lines up with its model at 4:3. In 16:9 the 2D layer is stretched to fit the screen (on purpose: screen options were still to come), so it's close, not perfect.