Double-Screen?

For anything related to VDP (plane, color, sprite, tiles)

Moderators: BigEvilCorporation, Mask of Destiny

Post Reply
Bitybity
Interested
Posts: 36
Joined: Wed Dec 07, 2011 2:09 am

Double-Screen?

Post by Bitybity » Thu Jan 12, 2012 10:45 pm

Hello.
I want to do something a double screen on MD, like the one at Sonic 2 and Sonic 3. I have studied that, and I think it's the interlaced mode screen. But when I enable it for my game, all the screen looks very glitched; I tried to search documents about this, without success.

Anyone knows how to do this, and how to work with it? And no, I don't necessarilly need it to be resized, I just need to split the screen (Like in Sonic 3)

Thanks

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Thu Jan 12, 2012 11:57 pm

Well, there's two parts involved in the splitscreen mode you see in Sonic 2 and 3.

The first part is yes, they do use interlacing, specifically interlace mode 2. Interlace mode 2 is what allows them to virtually double the screen resolution, and "squashes" the graphics data. Without this mode, both halves of the screen would be the same height as the normal 1 player mode, or in other words, each player would only be able to see half as much of the playfield as in single player mode.

The second part is unrelated to interlacing, and that's the use of a horizontal interrupt which is triggered partway through the screen. They respond to this interrupt by blanking the display, and adjusting the vscroll, hscroll, and layer mapping data during the blanked period. After this, the display is re-enabled, and the lower part of the screen is now showing a different part of the level than the top part of the screen. This is what gives the 2 player mode the split-screen feature.

Horizontal interrrupts are fairly easy to understand, and I'm sure there must be examples out there somewhere. As for interlace mode 2, there's a lot less information, however it is described in the official "Genesis Software Manual". The most critical part of interlace mode 2 for your 2 player mode, is the way in which it affects how patterns (tiles) are interpreted. In interlace mode 2, each tile is 8x16 pixels, not 8x8 pixels. When you specify a block number in your mapping data for each layer, you're specifying the number of an 8x16 pixel block, which is 0x40 bytes in size instead of 0x20 bytes (so in 8x16 mode, block 0 is at 0x00, block 1 is at 0x40, etc, while in 8x8 mode, block 1 would be at 0x20). If you look at the 2 player levels in Sonic 2 for example, you'll see that all the patterns in that level are actually designed to work as 8x16 tiles as well as 8x8 tiles. Here's an example from Emerald Hill Zone in Sonic 2:
ImageImage

The first image here is showing the tiles in 8x8 mode. The second one is showing the tiles in 8x16 mode. Notice how all these tiles form perfect tiles in 8x16 mode as well as 8x8 mode? You'll find the same is true of all the levels which work in 2 player mode in Sonic 2. For the ones that don't have a 2 player mode, the tiles won't line up like this in 8x16 mode. In order to support interlace mode 2, you need to design your tile sets so they display proper, complete tiles in 8x16 mode. Obviously this puts significant limitations on the way you design your artwork, which is why the more complex levels in Sonic 2 don't support 2 player mode. It's also why they chose to create completely separate, mini levels for 2 player mode in Sonic 3, so that they weren't limited in their level design in the single player mode.

Bitybity
Interested
Posts: 36
Joined: Wed Dec 07, 2011 2:09 am

Post by Bitybity » Fri Jan 13, 2012 12:23 am

Okay, and that of 8x16 applies for both Scroll and Sprite planes? Yes, I guess.

About the horizontal blanking, I did not understood very much, but of course I'll clear it with the examples

Thanks

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Fri Jan 13, 2012 12:50 am

Yes, the 8x16 tile mode is enabled for all layers, including sprites.

As for horizontal interrupts, the concept is that you can effectively say to the VDP, "when you've rendered X number of lines, call my interrupt function". Basically, it allows you to write some code which is automatically called when the VDP is about to render a given line on the screen. All you have to do is setup a horizontal interrupt line counter (VDP register 10), enable horizontal interrupts (reg 11), and at the start of each frame, the VDP will load the counter number you specified into an internal counter, which is decremented after each line. When the counter overflows (goes to -1), a level 4 interrupt is generated on the M68K, the counter is reloaded, and the VDP starts rendering the next line. If you set the counter data to 1, for example, an interrupt will be triggered every second line. You want to set it to a number like 110 or the like, to generate an interrupt around the middle of the screen.

To handle the interrupt, you just have to define an interrupt handler for a level 4 interrupt, in much the same way you would for a vertical interrupt (level 6 interrupt). When your interrupt function is called, you can then make the changes you want to make to the VDP state, eg, disable the display, modify the settings you need to change, then enable it again.

Bitybity
Interested
Posts: 36
Joined: Wed Dec 07, 2011 2:09 am

Post by Bitybity » Mon Jan 30, 2012 8:18 pm

I'm very sorry for this bump, but I have something to tell.

I tried to make an experiment: an section of the screen at different positions, and the other stuck at position $0000; but without any success.

Let me show my code:

In the main program loop:
move.w #$8014,($C00004).l
move.w #$8A6B,($FFFF7E60).l
move.b #1,($FFFF7E67).l
In VBlank:
move.w ($FFFF7E60).l,($C00004).l
(Yes, pure mess)

And finally, in the HBlank:
tst.b ($FFFF7E67).l
beq @exit
move.w #$8134,($C00004).l
move.l #$40000010,($C00004).l
move.l #0,($C00000).l
move.w #$8174,($C00004).l
@exit: rte
What am I doing wrong there?

Gigasoft
Very interested
Posts: 95
Joined: Fri Jan 01, 2010 2:24 am

Post by Gigasoft » Mon Jan 30, 2012 10:18 pm

What is the value of SR?

Bitybity
Interested
Posts: 36
Joined: Wed Dec 07, 2011 2:09 am

Post by Bitybity » Mon Jan 30, 2012 10:54 pm

Gigasoft wrote:What is the value of SR?
0x2300 - 0x2305

Gigasoft
Very interested
Posts: 95
Joined: Fri Jan 01, 2010 2:24 am

Post by Gigasoft » Mon Jan 30, 2012 11:14 pm

Then it should work correctly. How does the picture you get differ from what you intended?

Bitybity
Interested
Posts: 36
Joined: Wed Dec 07, 2011 2:09 am

Post by Bitybity » Mon Jan 30, 2012 11:38 pm

Gigasoft wrote:Then it should work correctly. How does the picture you get differ from what you intended?
The upper part of the screen with normal VScroll, and the other in vertical position $0000.

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch » Wed Jun 06, 2012 1:46 am

Is sprite clipping handled automatically? If a sprite on the top half moves down towards the middle of the screen, does the bottom of the sprite get clipped off or does it also overlap part of the bottom half of the screen?

Are there any other examples of games doing split screen?

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jun 06, 2012 2:00 am

Sprite rendering is done line-by-line along with the display. If you define a sprite which is 16 pixels high, but change the properties of the sprite when only the upper 6 lines of it have been rendered for example, the new properties will be used for the remaining 10 lines of the sprite. For this splitscreen effect, this means if there's a sprite in the upper half of the playfield, but when only part of that sprite has been displayed, the horizontal interrupt fires and clears or modifies the sprite list, any sprites that were only partially drawn at that point will effectively be clipped.

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch » Wed Jun 06, 2012 1:19 pm

I don't suppose there's a lot of time during the horizontal interrupt to modify a lot of sprites, is there?

Did the Sonic 2 split-screen levels keep everything very basic?

Huge
Very interested
Posts: 197
Joined: Sat Dec 13, 2008 11:50 pm

Post by Huge » Wed Jun 06, 2012 1:39 pm

It has 5-6 lines of blank color between two screens, I imagine that could be there for a reason (other than aesthetics).

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jun 06, 2012 10:56 pm

Yeah, the game disables the display mid-screen to make the necessary modifications. Those blank lines acting as the border between the top and bottom regions are where the display is disabled. That's plenty of time to do a DMA transfer to update the sprite table, switch the layer A "name table" base address and hscroll table address to another location for player 2, and modify the vscroll data.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Jun 06, 2012 10:59 pm

Oh, I should point out that the sprite table would actually have to be reloaded, not just have its base address changed, due to the internal sprite table which caches the first 4 bytes of each sprite attribute. This cache isn't reloaded when the base address changes, so you'd have to rewrite the sprite table for the changes to fully take effect. There's other posts on this forum which talk about this I'm sure. Just wanted to point that out in case you try and change the sprite table base address and can't figure out why it doesn't work.

Post Reply