{"id":261,"date":"2023-12-30T15:42:36","date_gmt":"2023-12-30T15:42:36","guid":{"rendered":"https:\/\/wulinshu.com\/cms\/?p=261"},"modified":"2023-12-30T15:42:37","modified_gmt":"2023-12-30T15:42:37","slug":"vectorman-a-reverse-engineering-story","status":"publish","type":"post","link":"https:\/\/wulinshu.com\/test\/2023\/12\/30\/vectorman-a-reverse-engineering-story\/","title":{"rendered":"Vectorman: A Reverse Engineering Story"},"content":{"rendered":"\n

A couple of weeks ago I was contacted by Laurent (SEGA Dreamcast Info) who informed me he’d come in contact with some special betas which he’d like me to take a look at. What arrived next was 10 builds of Vectorman for PS2, a previously unreleased title by Pseudo Interactive. <\/p>\n\n\n\n

Pseudo Interactive had made their name in the early-2000s with the release of Cel Damage and were working on a Vectorman title just for the PS2. Unfortunately, it was never released and all we currently have is gameplay footage and various quotes around the Internet, so it was obvious that this needed some care to inspect what we have. <\/p>\n\n\n\n

In this post I’ll document the findings and research I encountered while going through these builds, but you can also find further information in the main release over on Sega Dreamcast Info’s website (which I’d definitely recommend!). <\/p>\n\n\n\n

Moreover, if you’re a beginner or are just interested in seeing how the more technical aspects of this sort of thing is done, then this first post as part of a series of future posts might also be worth reading, here.<\/p>\n\n\n\n

<\/p>\n\n\n\n

Again, many thanks to Comby Laurent for working with me on this!<\/p>\n\n\n\n

<\/p>\n\n\n\n

A Brief Analysis<\/h2>\n\n\n\n

As a software engineer and game programmer, I’m always drawn to searching for any logic that I can find, no matter where it is or what I’m looking at. So the first thing I did when receiving these prototypes was to extract each build and collate them into a neatly organised “working environment” and progressing onto the static analysis of the main executable. <\/p>\n\n\n\n

Picking the very first build sent to me, I booted it up using an emulator and sought to look out for anything that might be useful. At first glance, it seems like a debug\/QA build… some debug or placeholder info can be seen or toggled and the rest of the game seemed to be in a fairly complete state. <\/p>\n\n\n\n

After this brief 30-second test, it was time to open up the executable and take a look for anything interesting.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

hmm.. this seems interesting.. it seems as though the games initialisation procedure sets up a sort of “debugging level” which is used to log or enable various parts of the debug\/QA functionality, except here it seems to be turned off. Taking a further look, we can see that the initialisation procedure checks for certain conditions, and if only they are met, will it enable the appropriate debugging level. <\/p>\n\n\n\n

In this case, the game seemed to check for the existence of “ProView”, and if found, it would enable said functionality:<\/p>\n\n\n\n

  if ( sub_24C4C8(\"Found Proview\\n\") >= 0 )\n    *(v6 - 0x5E50) = 1;<\/code><\/pre>\n\n\n\n

From here, the value which is stored at *(v6 - 0x5E50)<\/code> is later tested against non-zero values, and then if non-zero, sets the real debugging level: “pitaDebug<\/code>“.<\/p>\n\n\n\n

However, if the Proview test fails, it will set pitaDebug<\/code> to zero. So in this case, we can simply reverse the operation, and instead change the instruction to set pitaDebug<\/code> to 1, when it fails, effectively forcing the debugging level to non-zero values, regardless of whether or not the test succeeded or not:<\/p>\n\n\n\n

sb           $zero, -0x733F($gp)<\/code><\/pre>\n\n\n\n

to:<\/p>\n\n\n\n

sb           $v0, -0x733F($gp)<\/code><\/pre>\n\n\n\n

With the patch in place, it works! Booting the game with the patch, you will now see extra debugging information you’d normally never see, and a plethora of in-game debugging utilities are at your disposal!
<\/p>\n\n\n\n

loadmodule: id 31, ret 0\nrandomSeed 373001396\nStarting piLaunch, pitaDebug = 2\ninitTime: 1.35\nLoad rtd\/dwVecpil.pix start\nLoad rtd\/dwVecpil.pix done\nLoadTime 0.67\nstartup 0.425\nTex 0.026\nWav 0.024\nPack 0.526\nBatch 0.000\nLevel 0.000\n\nLoading level dw_fact2\nLoad rtd\/dw_fact2.pix start\nLoad rtd\/dw_fact2.pix done\nLoadTime 1.82\nstartup 0.174\nTex 0.422\nWav 0.000\nPack 0.385\nBatch 0.009\nLevel 0.018\n\nLoading playerCars\nError: File mising piLaunch\/talkToMe.dat\nactivate level dw_fact2\nLevel0: 0\nLevel1: 7492048\nLevel2: 7492048\nRoom TreeSize: 0.049\nActivateLevelComplete\nGosJoysticks=4<\/code><\/pre>\n\n\n\n

<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n
\n
\"\"
Boom!<\/figcaption><\/figure><\/div>\n\n\n

Taking a look at some of the debug options:<\/p>\n\n\n\n