Swyter / poptools

Reverse enginering and notes for the PC version of «Prince of Persia: The Sands of Time» and «Prince of Persia: Warrior Within».
3 stars 0 forks source link

poptools

Reverse enginering and notes for the PC version of «Prince of Persia: The Sands of Time» and «Prince of Persia: Warrior Within».

Launch without the PrinceOfPersia.exe launcher

The Warrior Within launcher creates two global named mutexes; POP5Launcher and POP_Watchdog, and then launches POP2.EXE -007, which is the actual game binary. PrinceOfPersia.exe stays in the background and seems to monitor POP_Watchdog, for handling crashes and showing a window.

If the POP5Launcher mutex is not found it will error out with a «You must start the game with PrinceOfPersia.exe» message box and close. The -007 parameter doesn't seem to matter.

You can easily fake this by creating your own named mutexes via PowerShell and leaving it open. The game will start normally:

# PrinceOfPersia.EXE -> POP2.EXE -007
New-Object System.Threading.Mutex($false, "POP5Launcher")
New-Object System.Threading.Mutex($false, "POP_Watchdog")
./POP2.EXE

You can also avoid all this PowerShell stuff by replacing/hex-editing the POP5Launcher string in the game binary with some other short-enough mutex name that is guaranteed to always exist, like the POP_Game one the game creates just before to check that only a single instance is running at a time.

For the original Sands of Time the launcher is called with the -uplay_steam_mode parameter, and the mutex name is POP_Launcher:

# PrinceOfPersia.EXE -uplay_steam_mode -> POP.EXE -007
New-Object System.Threading.Mutex($false, "POP_Launcher")
./POP.EXE

For The Two Thrones the mutex is called POP3Launcher, back from the 5 of Warrior Within, funny:

# PrinceOfPersia.EXE -uplay_steam_mode -> POP3.EXE -007
New-Object System.Threading.Mutex($false, "POP3Launcher")
./POP3.EXE

Natively launch the games in windowed mode

The three games use your Profile.DAT to store the video settings, resolution and fullscreen mode. You can use the 010 Editor template and script in this repository to edit the file yourself, change the field and recompute the checksum... or just use these handy premade profiles:

Make a copy of the original one, you will lose your existing options (remapped keys included) and the progress for your unlocked extras.

It will take another restart for the game to start windowed from the beginning; as on start-up the game loads the video and sound settings from DefaultProfile.DAT. When you exit the game, the settings for that last profile overwrite the default one.

Show the close, minimize and maximize buttons in windowed mode

Open your POP.exe, POP2.exe or POP3.exe in some hex editor, depending on the game. Search for the 05 00 00 c0 00 byte pattern, replace that c0 with cb, and save.

This changes the original window style that gets supplied to CreateWindowEx() to include the WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX bits/window-styles.

i.e. Goes from 0xc00000 to 0xcb0000, the constant appears reversed due to the x86 CPU architecture being little-endian.

Unlocking the level-selector menu

The easiest way is to replace the P_StartNewGame string in POP2.EXE with P_SpecialLoad. Make sure to keep the zero-padding and add a NULL terminator at the end. i.e. Don't mess with the alignment.

Unlocking the hidden game options

Swapping the names of the P_Options and P_GameOptions pages in POP5Common.MGM makes the game skip the blacklist that hides the secret Setup menu ON/OFF, Cheats ON/OFF, Interface ON/OFF, Show motion camera ON/OFF, Interface ON/OFF and Work in progress ON/OFF entries under Options > Game.

One of the (still unidentified) options causes the Tab and C keys to pause the game, another one takes raw .BMP screenshots. These debug options seem to be stored as part of the profile data.

Unlocking the hidden advanced video options

Replace P_SoundsMenu with P_VideoAdvanced by hex-editing the string in the game's binary without affecting the other string's positions and ensuring it ends with 00; a NULL terminator.

It needs to be called from the Options menu itself, does not seem to work from the main menu. Options > Sounds will lead to it.

Internal names

Here is a list of the project names that seem to be used internally for each of these games: Year Game Codename Game engine Frameworks + Middleware Audio engine Symbols Team
2003 Prince of Persia: The Sands of Time POP4 Jade, BIG file v37 Vorbis, libpng 1.0.5 + zlib, libjpeg 6b, lzo DARE Montréal
2004 Prince of Persia: Warrior Within POP5 Jade, BIG file v38 Vorbis, libpng 1.0.5 + zlib, libjpeg 6b, lzo DARE Montréal
2005 Prince of Persia: The Two Thrones POP3 Jade, BIG file v38 GEAR, Vorbis, libpng 1.0.5 + zlib, libjpeg 6b, lzo DARE Montréal
2008 Prince of Persia (2008) POP0, POP09 Scimitar Havok 4.6.1-r1, GEAR, Vorbis, lzo DARE Montréal
2010 Prince of Persia: The Forgotten Sands POPTM Scimitar Havok 6.5.0-r1, GEAR, Quazal Net-Z and Rendez-Vous 2008.9 SP1, Vorbis, lzo DARE Montréal
2010 Prince of Persia: The Forgotten Sands (Wii variant) Djinn Jade, BIG file v42 Scaleform GFx + zlib, GEAR, Vorbis, libjpeg 6, lzo DARE 34.0.21 Québec

Libraries internal to Ubisoft's Technology Group:

Glossary