I have some good news and some bad news.
The good news is my launcher is pretty much ready. It's
available here (binaries can be downloaded from the "Actions" tab if you have a GitHub account). It only compiles for Windows, but runs well in Linux with Wine (use winetricks to install vcrun2019 and d3dcompiler_47). It (obviously) requires a copy of Burnout 3 for Xbox and the latest version of Cxbx-Reloaded.
It's a little clunky to get going right now, you'll probably need to launch Cxbx in advance so you can configure controls (and other settings), and then close Cxbx and run my launcher to actually start playing, but it does work, and you can indeed play around with what I've done up to this point. Having a launcher also opens the door for me to inject an effectively infinite amount of code by injecting my own DLL, rather than just making small patches on the original executable.
The bad news is, I've been looking a lot at the game's code, and the inlining is worse than I thought. My hope was to, at some point, start injecting librw (or even real RenderWare, though I obviously couldn't distribute that myself) to help facillitate porting the game to other platforms. But a lot of functions that I know
were RW functions have been aggressively inlined, to the point that much of it has been inlined
more than once, meaning the code that remains is all internal D3D stuff that the original source code never would have had any access to.
The result is code that's virtually hardcoded for Xboxes only, despite the fact that we know for a fact it was written to be portable (at least between Xbox and PS2). A lot of function calls have additionally been converted to fastcalls, which improve performance, but are harder to replicate in my code injections.
None of these are dealbreakers - rewriting code is rewriting code, you can ultimately get it to do whatever you want - but it does make things a lot harder, especially from a portability perspective. Injecting RW may be off the table, which is really unfortunate because injecting RW/librw was what I was counting on to give us quick access to other graphics APIs; not just Win/Mac/Linux, but also consoles like the Switch (or, with the original RW, potentially even the poor Gamecube that the Burnout series abandoned after 2). Again, it's not that any of this is
impossible the way the code is now, just that without the abstraction that RW provided, it all becomes much, much harder.
With this approach, we'll get a Windows port fairly quickly; I think that's clear at this point. But anything beyond that, I have no idea.
Ironically, for a console that's known to have weaker hardware, the PS2 version of B3 is
far less inlined. Before starting this project, I actually spent quite a bit of time using a linker map (that was accidentally left on the June 8, 2004 prototype of B3) to make a fully documented PS2 build (the "secret weapon" I mentioned in an earlier post), and I was hoping to use that documentation while injecting the Xbox version. But it's already proven extremely challenging, since a lot of the functions clearly laid out on the PS2 port have been ripped apart by the aggressive inlining.
I've long felt that this inadvertent documentation would make the PS2 the ideal candidate for decompilation, but this may be an even stronger reason. The PS2 version is just that much more readable. In some ways, it's tempting to jump straight to trying to do that rather than mess around with the Xbox spaghetti code, though I know in reality how much more of a time commitment that will be.
For now, I think we'll proceed with the launcher/injector approach, but I wouldn't be surprised in the distant future if we instead had a port sourced from a PS2 decomp instead.