Thursday, 3 November 2022

One step forward, and 2 steps backward!

Now that I have enough of the high level code in place to coin up and start a game, I've gone back to fix up the background scrolling. The original issue is that I wasn't really emulating the scrolling hardware properly, but rather optimised it for the gameplay scrolling, and as a result it came unstuck when the game was either setting the scrolling offset arbitrarily, or writing non-map data to the background.

There are 3 components to the scrolling that need to be emulated; the software scroll_cntr variable, the video ram mapping, and the hardware scroll register. Ultimately the software modifies the software variable directly and the hardware scroll register value is calculated from that. And the video ram mapping is optimised for a rotated monitor. And I have to admit, I am having trouble wrapping my head around the algorithmic relationship between the three. Hence the initial optimised implementation which simplified the video memory mapping and - I have to say - fudged the hardware scroll variable somewhat.

In attempting to rectify this, I've actually taken a big step backwards and decided to re-think the entire architecture of the scrolling background layer. Not only the above-mentioned aspects, but also the Neo Geo-specific implementation (ie how it uses sprites).

First step was to preserve the original video RAM mapping and transcode the routines that handle map rendering more accurately. In the end it wasn't as painful as I thought, because I can forego the screen flipping considerations and 16-bit operations are a lot simpler on the 68K than the Z80. To give you an example, the routine to calculate the video RAM address from row & column is 22 instructions in the original Z80 code (albeit with flipping), and only 8 instructions on the 68K.

Reverting to my original (test) code to render the background layer, I not only see the map being rendered (correctly again), but I can also now see the Xevious logo that is written directly into the background layer video RAM.

We finally get to see the map again

Tiles written to the background layer are now rendered correctly

Note that because the routines for background and foreground layers share the same calculation routine, the foreground layer tiles are now incorrectly positioned. But that's simply a matter of updating the foreground tile layer access routine to use the original layout. That's what I plan to do next...

As I mentioned, I've re-thought the implementation of the background layer, and it will likely require a few nights and a bit of experimentation to get it right. But I am hoping it will simplify the scrolling and allow the physical display to sync up with the software scroll values used in the code.

One other thing that occurred to me too; the direction of the rotation. I'm not sure how or why I chose to rotate the screen to the right in Donkey Kong (and hence all my other projects since), but I thought I should check against the one (and only) "commercial" tate-mode Neo Geo game; Neo XYX.

As it turns out, Neo XYX rotates the monitor to the left. Programmatically there's little difference; you have to either reverse the X or Y coordinate depending on which way you rotate. The Neo Geo video RAM access mechanism lets you selectively increment or decrement the address after each access, so neither is more preferable to the other. But I do think it's a good idea to use the same orientation as Neo XYX, because people aren't going to want to rotate their monitor different ways for different (tate) games. And if/when Neo Geo tate mode is supported in MiSTer, they're likely to favour the orientation of Neo XYX.

So that's another modification I have to make to my code before I can progress.

[I've just checked my Neo Geo tiles; I've only got one rotation in the set (because you can always toggle the flip bits to rotate the other way) and they're actually rotated to the left. Looking at my code, it does in fact toggle the flip bits when rendering each tile. So I guess I'll save 1 instruction per sprite update now!]

No comments:

Post a Comment