I never thought I'd say this, but Cxbx is finally going in-game with my favourite Xbox game, Azurik: Rize of Perathia! There are numerous reasons why I doubted this would happen, but read on to find out. These screens shows the result of going in-game. Looks pretty bad, but it's major progress considering that this game uses XDK 3911. There's lots of technical things to discuss about this update and it's going to take a while to explain it all; so grab a snack if you're going to read this update.
Just so you all know, I've been working on Cxbx for YEARS trying to get this game to do something. Why this game of all others? Well, not only is it my favourite Xbox game, but there are alot of unique features in this game that I would like to see emulated, and hopefully pave the way for more games to become playable. You may be thinking that since the graphics didn't look as good as Halo's or even Panzer's, that this game would be easier to emulate. No, that's definitely not true for this game. Let's look at it this way. Have you ever tried to play this on Xbox360 using it's backwards compatibility emulator? Didn't work, did it? The Microsoft devs never could get this game working to save their lives! Yup, that's right. An amateur programmer like me out performed the entire Microsoft Xbox 360 team! That means, if they can't do it, then there's really something about this game that makes it worth emulating. Not just to walk around and boast, but to benefit Cxbx as a whole. We still have a long way to go emulating this game, but Cxbx is making progress on games that Microsoft couldn't emulate... and they have the official hardware documentation! Why is that?
Overall, I had to add quite a bit of stuff to get this working as far as it does. Thank God for Caustik's [indirect] input, or else I'd never have gotten this far! When I first fired up Cxbx and tried to run this game, got a crash, as usual. Since I didn't have that XDK back then, I tried doing some dirty hacks instead of solving the problem. Yeah, I was rather lazy back then! Needless to say, that didn't work. The biggest thing that bothered me was the vertex shaders. The vertex shader declaration was large, but the vertex shader would always be empty! The only thing we had to go by was the "vs.1.1" header of the vertex shader, so I had to check for this scenario each time a vertex shader was being parsed. Since Azurik uses non-routine shader usage methods, we're going to have to use the vertex declaration to create a fixed pipeline shader. Yeah, that sounds very contradictory, but this is how you create vertex shaders without the use of any assembly shader code (which Cxbx still uses). The idea didn't occur to me until a few minutes ago, lol.
If you're going to try this for yourself, then I highly renaming or recommend putting and extra char somewhere in the name of the movies folder. Cxbx will play Azurik's movies (not perfectly), but for me, the videos will randomly cause Cxbx to freeze. If you do rename the folder, then upon loading Azurik, you will be automatically taken to the menu screen where you are asked to create a new game. Then, you know what to do :) "Why do the videos cause problems with Azurik?" TBH, I don't know. I tried using Vertek's idea of using the progressive flag in IDirect3DDevice8_GetDisplayFieldStatus, but that will cause Azurik to do nothing but show a black screen. IMO, I think it's related to threading issues. Cxbx has been having alot of problems dealing with threads lately (especially Halo and Panzer) so I think this is one of those instances.
"Okay, that's interesting... but why are the graphics so distorted?" That's a good question. Before I get to that, let me tell you something interesting about this game. Azurik's polygon counts can reach over 300,000 primitives per frame. Trust me, for an Xbox1 game, that is alot (yes, more than Halo). And yet, it still maintains a steady frame rate of 30 fps. Using your standard Draw[Indexed]Primitive/Vertices[UP] API calls weren't going to get you 30 fps rendering this many polygons, trust me on this. Instead, Adrenium (the company that made Azurik) decided to use PushBuffers instead. The PushBuffer (exposed by the IDirect3DPushBuffer8 interface exclusive to Xbox) was designed to take full advantage of the Xbox GPU (NV2A) hardware. All NV1x GPUs and later support PushBuffers internally (can't say for the Gxx series because I haven't looked into it yet) and the IDirect3DPushBuffer8 can be used to directly program the GPU. Cxbx does emulate PushBuffers (which requires a bit of low level emulation), but so far only Turok seems to have correct PushBuffer emulation (most of the time). Games such as Panzer also use it. I don't know what's required to fix the PushBuffer emulation for this game, but quite frankly, I've never actually used a PushBuffer myself, so now would be a good time to learn! When I get time, I'll write some code examples using PushBuffers and test them against my debug Xbox and Cxbx to make sure I get it right. It's going to be tough fixing the Gfx for this game, but someone's gotta do it!
Aside from that, there's another really annoying thing about this game... the pixel shaders! Okay, why would any professional programmer create a new pixel shader and release it each frame? What sense does that make? From what I was taught, that's bad programming practice! Maybe Adrenium had a good reason for it, but I sure can't think of any. I ended up disabling the code I used to dump the pixel shader definition each time a new pixel shader is created because I'd end up with 8,000 text files containing the same pixel shader in less than a minute! Cxbx already defaults to the basic passthrough shader anyway since pixel shaders aren't yet supported. Not that it's a major problem, but it's annoying!
So I think that it's safe to say that Azurik has undoubtedly the worst bugs I've ever seen in Cxbx; absolutely horrendus. In fact, it's worst than every partially/fully game functional with Cxbx combined, and the speed issues are much worse than Panzers (and Panzer is S-L-O-W). This game is definitely going to keep me busy for a while. It's bad enough that the problems Cxbx has with XDK 3911 are hard enough to fix and I knew that emulating this was going to be painfully hard, but wow, I never dreamed things would get this tough! Oh well, time to stop complaining. Things can't always be easy, can they? Beating the game was hard enough, now let's try fixing it. Wish me well everyone!
Shogun!
wow nice job liked that game so much! something off-topic: did you tested JSRF yet coz i really want to play the game :)
ReplyDeleteI get JSRF requests all the time. It doesn't work and I don't know how to fix it yet. I can't remember if I did a blog update about that or not.
ReplyDeleteTruly incredible work blueshogun. I have been following Cxbx since 2003 and it's really exciting to read these updates and see the progress you've made especially after the long hiatuses caustik took. I remember first seeing the Futurama update and grinning widely after a silent two years of Cxbx development. Any game you work on is great, what ever keeps you motivated to continue the project or you think would significantly add to the support.
ReplyDeleteYou are doing an amazing job. I can't thank you enough for your continued work on Cxbx and tantalizing blog updates.
i a´m very happy for friend. blueshogun i admire your advances in cxbx and now your favorites games shows something very nice, if you can put the link to download the svn , i can to compile it and i try with other games is very posible a new compatibility list i´m sure or that,thanks a big huge for you .saintseiya
ReplyDeleteI have this game i love it!
ReplyDeleteWOW!!
ReplyDeleteHey I was wondering if you had made any more progress with this game? Like you, this is my favourite xbox game of all time and I really want to play but I can't find an original xbox anywhere let alone a copy of this game. And to my knowledge there's no emulators that can run it or anything for xbox, really. Was hoping you might have some leads with this project? Please reply
ReplyDelete