Show older

anyway, this is only vaguely related, but there needs to be a tool that helps tie dynamic debugging with static debugging.

like, use the dynamic debugging traces to do things like annotate functions with records of how often they get called from different sources

or click a function and see what arguments it has been called with in traces

sadly the wii balance board support classes in the engine are just leftovers from the engine's use in other games, and not proof that the developers of Wheel of Fortune (2010, Wii) were far ahead of their time in avant-garde gaming

although given my reverse engineering work, it's possible that I may one day reverse this wrong

man I'm used to weird padding in structures and strange gaps, but 14 kilobytes? Why?

the struct WiiControllerPack has, at offset 1480, an array of 4 KPADStatus structures.
Each of those is 250 bytes. So this array is over by byte 2440.
So where does the next member start? offset 16888.

that's 14,448 bytes of nothin'.

or maybe, given that it's left out of the debugging info, 3612 separate vtable pointers!

(this is a joke. it can't possibly be that)

wait. the revolution SDK defines KPADStatus about how I'd expect but then it defines KPADUnifiedWpadStatus which is a union of various things. I wonder if my debugging info is eliding some weird union nonsense going on which explains why everything is so big

this is the worst thing about reverse engineering.
you pretty much never can assume "well something weird happened randomly"

no, there is A Reason why the compiler did this, and you are going to have to find out what it was

me "well at least I have a bunch of types from the debug files, so I can finally figure out the types of a bunch of these untyped globals! goodbye, undefined1 PrimDrawer::bPrimBuffer[6144], let's see what you really are!"

Dumped DWARF debugging info: "unsigned char PrimDrawer::bPrimBuffer[6144]"


I'm pretty sure this game had two programmers who each compiled 50% of the game's code.

Programmer A had their compiler set to output every bit of debug information it could, short of just shipping the .cpp files

Programmer B had their compiler set to aggressively optimize and never output any debugging info

at the end of the development, the object files from these two developers were linked together, then that binary was shipped to the customer

seriously. I have complete info telling me that void WorldObject::updateVisRes(const WClipFrust &, CCheckResults); was defined on line 335 of E:\Build\WheelJeopardy\World\/WorldObjectBase.h

what's a WClipFrust? that information is not in the debugging info. Go fuck yourself.

I think the only thing this compiler has ever inlined is vector.push_back()

which is great because it really aids clarity of reverse engineering that every time they call vector.push_back() there's 20 lines of support code for it

just after I say this, guess what I find, plain as day, in the disassembly?

MVectorBase<WStaticMesh*,WStaticMesh*,4>::push_back((MVectorBase<WStaticMesh*,WStaticMesh*,4> *)&this->static_meshes,local_20);


it's inlined earlier in this same function

what the fuck

either they REALLY wanted to specify that this class initializes all the floats to 340282349999999991754788743781432688640, or they accidentally included a little-endian NaN when they meant a big-endian NaN.

I'm not really sure how you accidently code a floating point number to have the wrong endianness.

yeah after some dynamic testing, I think the reason this particular WStaticMesh and WSector and WPortal and WOccluder is extra cursed, with missing debug info and incorrect-invalid-floats?

It's never called. Why would it be? This is a game that basically takes place in one big room, plus a menu. Why would your map need to be split up into sectors?

it probably got left in because
1. codewarrior is terrible at dead code elimination (and all other optimizations)
2. they have an advanced scripting engine, making dead code elimination even harder

there is not much gore in Wheel of Fortune.

they meant Ignore


a pointer to the Target, in World coordinates?

or the best fun park in all of Qo'noS?

arg. how is WTrackCam perfectly documented in the debug data, but the surrounding class of WCinematicCamera is not? it's not even mentioned once, not even in arguments! and it's definitely used, I found it by dynamic tracing.

oh because it's only created by the fucking scripting language!


(I'm going to have to write it. Well, finish writing it)

the nice thing about having a scripting language is sometimes I'll see that they bind a method called "setSkippable" to ID 116 and in callMember they switch on the id and case 116 reads:

this->camera->field08 = getArgument(1);


this is like 90% of what I've been doing for the last three months.

I'm tracking down lots of obvious clues scattered in a million places to the silliest murder mystery

in ResourceLoadPacket::finalize, they have two for() loops nested in each other, each of which declares their variable as "i".

Because it's a separate scope, this means that these are two separate variables, so it works, but it's NAUGHTY

if (this->nVersion == 262) {
if (this != (PropertyBook *)0x0) {
// do some stuff with this

someone got their checks in the wrong order. and their compiler didn't notice.

love to spend a while looking through the code to try and understand how a variable is used, then I check the trace logs and the answer is "it isn't"

PFuncSymbol takes a final boolean parameter. What does it do? We don't really need to know, because every time PFuncSymbol is called, it's false.

DW_OP_regx 0xffff?
the variable is stored in numbered register 65535? something's gone fucky.


@foone In C, I like to use negative indeces. With a pointer to the end of a buffer, you can count from -n to 0, data[i] will work as expected, and you always know how many elemwnts you can look ahead (-i) without having to do n-i every time.

· · Web · 0 · 0 · 0
Sign in to participate in the conversation
Awoo Space is a Mastodon instance where members can rely on a team of moderators to help resolve conflict, and limits federation with other instances using a specific access list to minimize abuse.

While mature content is allowed here, we strongly believe in being able to choose to engage with content on your own terms, so please make sure to put mature and potentially sensitive content behind the CW feature with enough description that people know what it's about.

Before signing up, please read our community guidelines. While it's a very broad swath of topics it covers, please do your best! We believe that as long as you're putting forth genuine effort to limit harm you might cause – even if you haven't read the document – you'll be okay!