I'm Reverse Engineering Crusader because I'm still obsessed about the game

That one was in that presentation about decompiling games, which I watched the other day, it was my first time seeing it.

Also refresh the site because I just pushed a cool update that adds proper bounding boxes to hover selection and allows you to press F to enable the global bounding boxes (sometines, it's still buggy, use the checkbox if it doesn't work lmao)


1774651940523.png



I want to figure out how to load unused map in the game eventually, map 248 is an early clone of the first level and I'm thrilled to find out that the werd part where the first bridge over the acid goes to the wall actually used to host a vent

1774652052315.png

Also these docks that can never be viewed on the left, they have an extra one with an open window
1774652167513.png
 
I DID IT!! I managed to hack the game to load into arbitrary maps!

I can play the unfinished beta map and potentially any other map, I'm going to upload a powershell script to do the patching to the repo soon

1774653597067.png

This map is a gift that keeps on giving, I think this is a deleted enemy whose AI is still in the game
1774654294059.png

Here it is: https://github.com/MaddoScientisto/crusader-decomp/blob/master/patch_crusader_map_load.ps1
Place this script in the same folder as crusader.exe and run it, select the option to change the map load number and then input the number of the map you want, I tested it with map 248.

You can also input an egg number or leave the default one but I haven't tested it, 250 should be the usual weapons room.
Once patched start the game and pick new game and select any difficulty, you will load to a black screen but will be able to hear audio, just pause and unpause the game and you will be able to see.

You start with no weapons, use cheats to obtain them and then get to exploring!


ONE sprite of that enemy survived, it's the floor cannon robot!
1774654927453.png

I just added a new feature: the eggs list
1774658138468.png

It's a filterable list of egg ids, useful for exploration through the map destination hack tool, this should make testing the unused maps so much easier

Just in time for easter!
 
Last edited:
@Keenan I was looking at old threads and stumbled into this one https://echosector.org/forum/threads/crusader-outside-of-dos-theres-a-chance.97/

It was an interesting effort to hack crusader into running on windows but it didn't go far at all because they didn't have access to a disassembler.

It sounds like a fun thing to try with my current tools, I tried to look for that ultima 8 win9x patch but it's impossible to find, would you have any idea where to find it? I could start trying to do this blind but maybe looking at the patch could be more illuminating.

Sure nowadays we have DOSBox and scummvm but I still kind of want the satisfaction of getting the game to run on windows natively
 
And here it is: my first successful modding attempt.

It was not possible to hackwarp into map 251 because it missed a teleport destination egg to warp to, well not anymore!
I added the ability to add new teleport destination eggs to the web app and then export a built map file. Another script extracts all the maps into separate files, allows for replacing the file and then rebuild a FIXED.DAT from each.

And there we go, we can add teleport destinations to the game now!

1774687503081.png1774687364446.png

1774687553453.png

The sky is really the limit now, I can turn the app into an editor able to add any shape and if I decode the various scripting objects properly then we'll be able to add npcs, items, events. When usecode decompilation is fully fledged we can modify scripts, maybe even create new ones!

I'm extremely excited about all of this


Yo map 251 has REMOVED ITEMS

But they don't do anything

1774689181511.png1774689196585.png1774689204501.png1774689237489.png
 
Last edited:
New discovery: No regret (and likely remorse too) has a built-in way to warp to arbitrary maps already and the script wasn't needed, it's just that I remembered Stauff's comment about not being able to warp to single maps and I didn't investigate further.

Turns out there's an undocumented command line parameter -mapoff that allows doing this, looks like it adds the specified number to the mission you are warping to through -warp so if you specify 0 as parameter for -warp you can warp to any map in the maps table as long there is a teleport destination egg in the map

-warp 0 -mapoff 44 -egg 250 brings you to this very interesting map, you immediately see Tony Zurovec and when you walk forward a bit the sound clip "I think I'm gonna fart" plays.




1774705779926.png

A button ahead shows the message "THUMPER WUZ HEAR"
1774706075150.png


Further still you can see E---'s signature
1774706104355.png

And the final button shows the message "HI JELY TIMMY DIANE TRACY"
1774706131740.png

There is still a cluster of lines in a corner of the map but there's no button for it, there IS an unknown object but I don't know how to trigger it YET
1774706161891.png


The new discovery definitely makes map hunting more approachable but it's still not possible to warp to maps that have no eggs unless a new egg is hacked in

-warp 0 -mapoff 250 -egg 250
leads to a very busy test map with a lot of buttons and npcs

1774706345230.png

Ever wanted to spawn and massacre a bunch of office workers on command? Well now you can!

1774706390173.png

UPDATE:
I did some more disasembly and found out that -warp accepts X Y Z parameters! It's now possible to warp to ANY map if you know valid coordinates and guess what, if you use the map viewer you can just inspect any floor and grab its coordinates and they work!

-warp 0 4094 5630 0 -mapoff 254

Map 254 and all the other previously inaccessible maps are now playable without hacks!
regret_002.png
 
Last edited:
Amazing progress in such a short amount of time. Don't burn yourself out!

@Keenan I was looking at old threads and stumbled into this one https://echosector.org/forum/threads/crusader-outside-of-dos-theres-a-chance.97/

It was an interesting effort to hack crusader into running on windows but it didn't go far at all because they didn't have access to a disassembler.

It sounds like a fun thing to try with my current tools, I tried to look for that ultima 8 win9x patch but it's impossible to find, would you have any idea where to find it? I could start trying to do this blind but maybe looking at the patch could be more illuminating.

Sure nowadays we have DOSBox and scummvm but I still kind of want the satisfaction of getting the game to run on windows natively

I don't have the file and don't know where to get it, sadly.

However, I do have a Japanese version of Crusader that supposedly runs in Windows 95 with DirectX. I've never been able to confirm this is the case. I've set up a Japanese Windows 95, but I couldn't get it going in the first attempt. It's been a while since I tried. I've been meaning to get it properly preserved and archived online, but haven't got around to it.

20260328_104345_2.jpg

I've done a quick rip of the disc image in case you wanted to mess around with it: https://archive.org/details/crusader_no_remorse_jp
 
That's great, I do have a japanese no remorse executable from Stauff's ghidra project from his repo but I had no idea it had that capability, I'm going to analyze it and compare it to the one you just posted and try to report back, maybe I'll set up a win95 dosbox environment to test. Could you maybe take some quick pics of the manual instructions where it goes into the technical stuff? maybe we can use machine translation to figure out if it mentions win9x support.
I remember the original had a "gateway to dos" shortcut it would install to reboot the system in DOS and set up some system variables

In other news, thanks to the new discovery of the ability to warp to any map regardless of egg presence through mapoff and the xyz warp parameters I just pushed an update for the tool that adds a copypastable warp string you can paste in the terminal and immediately launch the game to that specific spot

1774714520513.pngcrusader_019.png
 
Great news @Keenan the preliminary analysis is in and it came back with very strong evidence!

Current static-analysis verdict: strongly supports the claim.
The loaded Japanese executable is not just a DOS executable with a small helper around it. It is a native flat Win32 image with Windows API startup, Windows registry configuration, DirectDraw/DirectSound initialization, and one explicit Win9x-aware compatibility branch.
What is proven from static analysis:
- the Japanese binary is a PE-style Win32 program loaded at `00400000`, with sections such as `BEGTEXT`, `DGROUP`, `.idata`, `.reloc`, and `.rsrc`
- it creates a real top-level Windows game window and runs through Win32 startup code
- it initializes DirectDraw and DirectSound directly
- it reads and writes settings in the Windows registry
- it contains Japanese/Win9x-facing support clues, including IME handling and a `GetVersion`-based compatibility branch
What is **not** proven by this pass:
- an actual runtime launch on real Windows 95 hardware or emulation
- whether extra runtime prerequisites such as the expected DirectX version are always present on a bare Windows 95 install
- whether every shipped JP build variant behaves the same way


Ghidra reports the active program as `/ja/CRUSADER.EXE` with entry at `004729e0`.
Relevant image layout recovered from Ghidra:
- `Headers: 00400000 - 004003ff`
- `BEGTEXT: 00401000 - 0047afff`
- `DGROUP: 0047b000 - 00481bff`
- `.bss: 00482000 - 00495fff`
- `.idata: 00496000 - 00496dff`
- `.reloc: 00497000 - 0049e3ff`
- `.rsrc: 0049f000 - 004a03ff`
That is a normal PE/Win32 layout, not the segmented NE or DOS-extender layout used by the original DOS executable.
### 2. The import table is decisively Windows-native
Recovered imports include all the major Windows subsystems expected of a native Win9x game executable:
- process and OS: `GetVersion`, `CreateThread`, `ExitProcess`, `TlsAlloc`, `VirtualAlloc`, `GetCommandLineA`, `GetModuleHandleA`, `GetModuleFileNameA`
- window/UI: `CreateWindowExA`, `RegisterClassA`, `DefWindowProcA`, `DispatchMessageA`, `PeekMessageA`, `ShowWindow`, `RegisterWindowMessageA`, `MessageBoxA`
- graphics: `DirectDrawCreate`, `CreateBitmap`, `CreateCompatibleDC`, `CreatePalette`, `TextOutA`
- audio/timing/input: `DirectSoundCreate`, `DirectSoundEnumerateA/W`, `timeGetTime`, `joyGetDevCapsA`, `joyGetPosEx`
- configuration/storage: `RegCreateKeyExA`, `RegOpenKeyExA`, `RegQueryValueExA`, `RegSetValueExA`, `CreateFileA`, `ReadFile`, `WriteFile`
- Japanese text/input support: `IsDBCSLeadByte`, `GetCPInfo`, `WINNLSEnableIME`
This is not a DOS launcher plus one or two helper calls. It is a full Windows application stack.
### 3. The main window path is explicit and native
`00445f40` is now named `win32_create_main_window`.
Key behavior recovered from decompilation:
- registers a window class with `RegisterClassA`
- creates a fullscreen popup window with `CreateWindowExA`
- uses the title string `"Crusader: No Remorse"`
- calls `ShowWindow(..., 10)`
- calls `WINNLSEnableIME(0,0)` immediately after successful creation
- registers `"MSWHEEL_ROLLMSG"`
This is direct evidence of a native Windows UI path. The IME call is especially relevant in a Japanese build because it shows the executable is consciously managing Windows-side JP text/input behavior.
### 4. DirectDraw and DirectSound are initialized directly by the game
`004459b0` is now named `video_init_directdraw_and_directsound`.
Recovered behavior:
- calls `DirectDrawCreate()`
- sets cooperative level and display mode on the DirectDraw object
- creates the palette and primary surface
- calls `DirectSoundCreate()`
- hides the cursor with `ShowCursor(0)`
This is a classic Windows 9x era DirectX setup path. It strongly supports the idea that this build was intended to run as a native Windows game executable.
### 5. Registry-backed configuration is built in
String at `0047b178`:
- `Software\Electronic Arts\Crusader: No Remorse\J1.21`
`004138e8` is now named `config_load_registry_and_cfg`.
Recovered behavior:
- reads `installpath`, `cdpath`, and `flicpath` from `HKEY_LOCAL_MACHINE`
- reads user preferences such as `video`, `subtitles`, `limitblasts`, `animation`, `frameskip`, `musicvolume`, `soundvolume`, and `mousespeed` from `HKEY_CURRENT_USER`
- falls back to parsing `crusader.cfg`
`00413760` is now named `config_write_registry_string` and writes string values back into the same registry branch.
This is strong evidence of a normal Windows-installed configuration model rather than a DOS-only setup flow.
### 6. There is a real Win9x-specific compatibility branch
`00472c41` is now named `win32_runtime_capture_process_context`.
Recovered behavior:
- captures environment strings
- captures module filename and command line
- calls `GetVersion()`
- stores split version fields into globals at `0x47c09f`, `0x47c0a0`, and `0x47c0a1`
The more important follow-up is `00476616`, now named `win32_tls_alloc_with_win9x_guard`.
Recovered behavior:
- calls `TlsAlloc()`
- checks the saved `GetVersion()` word
- if the version word has the high `0x8000` bit set, it retries while the TLS slot is less than `3`
That is not generic Windows code. It is exactly the kind of branch you expect when a program needs to behave differently on the Win9x line, where `GetVersion()` reports the platform using the high bit and some low TLS slots are treated specially.
This is the strongest single code-level clue that the executable was designed with Win9x behavior in mind, not just NT-family Windows.
## Secondary Evidence
### Japanese-specific Windows integration
The import set and main-window path together show several JP-specific Windows integration points:
- `WINNLSEnableIME`
- `IsDBCSLeadByte`
- `GetCPInfo`
That does not by itself prove Windows 95 compatibility, but it does reinforce that this is a localized Windows build, not a DOS build being loosely wrapped.
### WinMM and joystick APIs
The import table also includes:
- `joyGetDevCapsA`
- `joyGetPosEx`
- `timeGetTime`
These are ordinary Windows multimedia/input APIs and fit the same native-executable picture.

Although it's not just the simple hex hack I was hoping for, this is a fully recompiled version. The ultima 8 win9x patch would have allowed me to find what the patched offsets were, what they did and find similar ones for crusader in order to patch the DOS version into working on windows with minimal changes.

I kind of want to unleash this kind of analysis on the PSX version, including the crusader 2 prototype, but the file format was completely obscure to me and I think it may require more effort. It would be neat if I could figure out how to extract the PSX maps, maybe even the usecode for the extra gun they added. And who knows what's hiding in the Crusader 2 disk...

Very interestingly, the japanese version has an extra "-u" command that works as a startup usecode override
 
Last edited:
There's a readme.txt and readmedx.txt in the ISO that probably has the same information as the printed manual. But, here are some quick pics anyway. Again, I've been wanting to scan these documents properly, but I don't have access to the proper hardware right now.
 

Attachments

  • 20260328_113146.jpg
    20260328_113146.jpg
    836.5 KB · Views: 4
  • 20260328_113131.jpg
    20260328_113131.jpg
    876.8 KB · Views: 4
  • 20260328_113123.jpg
    20260328_113123.jpg
    761.7 KB · Views: 3
  • 20260328_113058.jpg
    20260328_113058.jpg
    748.5 KB · Views: 3
  • 20260328_113049.jpg
    20260328_113049.jpg
    770.5 KB · Views: 3
  • 20260328_113008.jpg
    20260328_113008.jpg
    850 KB · Views: 4
I can see why they had to make a proper win9x version for japan, over there they were using PC-98 instead of DOS before windows 95 released so a DOS game wouldn't have been popular at all.

Anyway what I'm working on right now: making a hex patch to enable visualization of editor items in the game, for fun.

And here we go! I made a patch for the executable to show the editor only objects ingame. There wasn't a debug option for it so I had to suppress an early return. It's in the map patcher powershell script

crusader_020.png

I've been researching NPCs more in depth and I found out that the little robot guy is called "Observer" and is present quite a lot even in the final maps, it's just set to never automatically spawn. I was able to see it in the prerelease maps because nobody bothered going back to disable the spawn on these. As we can see there is an observer right in the first level, just disabled.

By the way we have NPC spawner previews in the editor now

1774735683943.png
 
Last edited:
Today I added preview visualizations for items and thanks to these it's finally possible to see what the secret message in map 44 was:
"HI NIMAH LOVE YA"


1774791868596.png

I also started trying to disassemble the psx game and it's going pretty well, I managed to extract monochrome sprites


1774798687485.png

Who knows, maybe by the end of day I might have psx maps in the viewer app...

Second pass, getting closer...
1774799291907.png

Not going very well...
1774802889243.png
 
Last edited:
1774809996399.png

So here's a cool sprite from the psx version

I did a first pass extraction of PSX sprites: Not all palettes are correct yet but it's enough to build a map viewer

Little news: I had to nuke the public repo (and sadly the map viewer) because I accidentally committed some of the original files, it will be back once I fix it

It's back up at: https://maddoscientisto.github.io/Crusader-Map-Viewer/
 
Last edited:
Mission 7 has another E shaped Zurovec room, it's not in my known list of secrets and I don't see a teleporter leading to it, this might have been a cut secret, repeated in Mission 2 OR nobody has ever found it, time to dig

1774884694773.png

wait wait wait wtf is this?? A hidden Jely bathroom I've never seen in mission 7???
1774886005912.png
 
Last edited:
Starting with -warp 0 -mapoff 13 -egg 14 brings you to the E shaped room and taking the teleporter back brings you... here

And if I'm not mistaken there is a teleporter right under that ledge that leads back up, so... either the teleporter was redirected there making the E shaped room inaccessible or there is some way to switch the teleporter to take you to the room.

I'm currently modifying the map viewer to draw arrows between teleporters, once it's done we'll immediately see where the mischievous teleporter is

crusader_032.png

The updated viewer shows that there are two teleporters, one behind this wall
crusader_033.pngcrusader_035.png

And one under the floor
crusader_034.png

This is really weird, I have screenshots in my old secrets notes Here showing that if you fall down in that precise spot a teleporter brings you back up, however in the tests I'm doing right now this is not happening, but maybe it's because it's the result of some other triggers changing some behaviors

in the map viewer I can see that there is a spawner that spawns floor over the acid so you don't drown and there's a chemsuit guy spawner down there too.

There's also a secret room with items that's opened in an unknown way

crusader_031.raw1.png


I keep finding insane stuff in Misison 7, if you get on top of this pipe through creative jumping... you end up in the known secret room
crusader_037.pngcrusader_038.png
 
Last edited:
I need to check this out, but my GOG version is only in mission 5. Is there an easy way to use console commands for starting using the GOG version? If not I'll have to install DOSBox seperately and use my CDs
 
I need to check this out, but my GOG version is only in mission 5. Is there an easy way to use console commands for starting using the GOG version? If not I'll have to install DOSBox seperately and use my CDs
GOG version is already DOSBox, I'm using it regularly.
If you open dosboxCRUSADER_single.conf in a text editor you'll see a :game label, just add the warp parameters right after CRUSADER.EXE

To find warp parameters I made a neat helper in the map viewer at https://maddoscientisto.github.io/Crusader-Map-Viewer/

If you enable the "Inspect shapes under cursor" and you click anywhere then at the bottom of the tooltip you will see a warp string ready to copy and paste in the dosbox configuration, that allows you to start the game at that specific point.

If on the left you scroll down to the "Eggs" section you can click on any teleport destination to select the teleport egg and copy the warp string.

-warp 0 -mapoff 13 -egg 30
leads you straight to mission 7

-warp 0 -mapoff 13 -egg 3
puts you at the start of the floor where the secret is

If you want to have more fun with unused maps, I documented all the ones I found here https://tcrf.net/Crusader:_No_Remorse#Unused_Maps
 
I remembered a thread from long ago where somebody had an unpatched no remorse and reported that the weapons room in the first map looked different, so I wonder what if the patch altered some maps?

I do have my old CDs for remorse and regret, Keenan has the demos and the jp version and I already obtained them

Here's my roadmap:
  1. Find my old CD and dump it (turns out GOG has the 1.01 data in the embedded ISO)
  2. Compare the static files if they have differences ✅ (yep there are differences)
  3. Run the map files through the map viewer to physically see if there are map differences ✅ (yep, there are. It was already known that the weapons room in 1.01 didn't have the teleporter to te final level)
  4. Add a version selector to the map viewer so everyone can see and compare maps (it's in but I have to get back home so I can get the regret assets built)
  5. Add the Usecode decompiler to the viewer and allow comparing between versions
  6. Add the shapes viewer to the app
 
Last edited:
Back
Top