<< Newer Article #178 Older >>

Side-Effects

The problem with a project as huge as MAME is that you really can't change anything without breaking something else. Such is the case with the new feature I added late in the 0.106 cycle that lets you control the horizontal/vertical positioning and stretching of the screen. This feature is intended so that MAME can more accurately output video that corresponds to the real arcade screen.

On many real arcade PCBs (and especially on older PCBs), the video system actually generates signals beyond the immediate area of the screen where the gameplay is. What would happen is that arcade operators would use the horizontal and vertical scaling/positioning knobs to expand the gameplay area of the screen to fill the screen and thus cropping out anything that wasn't intended to be seen.

The way MAME has handled this in the past is to have a screen bitmap where pixels are placed (this is equivalent to the video signal), and then game drivers would provide a "visible area", which is the cropped area where the gameplay is focused. This generally works well, but doesn't allow you (the operator) to control the positioning and scaling of the image. When I decided to add these controls, it meant that I needed to dynamically adjust this "visible area" to display a different subset of the pixels in the screen bitmap.

This sounded pretty straightforward. But it appears to have some side effects.

The first issue is that some games are showing a pixel or two worth of garbage at the edges of the screen. If you bring up the sliders in the UI and adjust the horizontal or vertical scaling, you should see that this garbage is actually extra pixels that are right on the edge of the screen. The reason they are visible at all is thanks to bilinear filtering on your video card. Even though MAME is correctly computing how to position the screen so that those pixels aren't visible, the bilinear filter is grabbing color data from those pixels as it scales up the image. You can work around this by simply adjusting the horizontal/vertical scale and position controls until those pixels are gone.

The second issue is that some games got really slow as a result. Previously, MAME used to only copy the pixels from the visible area to your video card for rendering. But in order to have access to all of the video signal information, the current code will copy all of the screen bitmap pixels to your video card. For most games, the screen bitmap is only slightly larger than the visible area, so this didn't really hurt anything. But several drivers have huge screen bitmaps and small visible areas. robokid, for an extreme example, has a 2048x512 screen bitmap even though it is only displaying 256x192 pixels. Other games with this problem include games that switch resolutions, because the screen bitmap has to be big enough to accommodate the largest resolution that will ever be switched to, which is often much larger than the actual resolutions used in the game.

I'm trying to come up with a non-gross way of fixing both of these problems. The first problem probably needs the introduction of the concept of blanking areas. On a lot of actual PCBs, you won't actually see this garbage because they have set up a blanking signal that turns off the video signal after a certain point. The visible area used to sort of account for that, but didn't allow for the possibility of adjustment. By having support for a separate blanking area in addition to the visible area, some of these problems can be eliminated.

The second problem is more severe and in the end more straightforward to fix. The core is already computing the effective visible area of the screen and only asking the driver's video update to draw just those pixels. It just needs a way of communicating that information to the rendering code so that it doesn't waste time copying pixel data that will never be seen.