Formulas for mode 7 parameters

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Formulas for mode 7 parameters

Post by tepples »

NovaSquirrel made a JavaScript tool to preview the result of background mode 7. The user types in a formula to generate the rot/scale parameters for each scanline, and it emulates a PPU receiving those parameters through HDMA.
Live web version: http://t.novasquirrel.com/test/mode7/
Source code repository (GNU GPL version 3): https://github.com/NovaSquirrel/Mode7Preview

I used it to come up with the following generic formula for affine parameters, useful for games like Cameltry (aka On the Ball) where the background is parallel to the screen.

Code: Select all

// The S-PPU calculates (U, V) coordinates in the map 
// screen coordinates using this formula
// U = A * (X + HOFS - X0) + B * (Y + VOFS - Y0) + X0
// V = C * (X + HOFS - X0) + D * (Y + VOFS - Y0) + Y0
// Other input parameters: framecount and scanline

Tau = 2*Math.PI;  // radians per turn, about 6.283

// xpos and ypos scroll the map
// xcenter and ycenter control how far the camera is ahead of the player
// theta controls rotation, dist controls distance from the camera,
// and par controls pixel aspect ratio (which for NTSC is 1.143)
// animate it to drive home that this is the center of rotation
xpos = 0;
ypos = 0;
xcenter = 128;
ycenter = 112;
theta = framecount;
dist = 144 * (1 + .5 * Math.sin(framecount * Tau/512));
par = 1.143;

ctheta = Math.cos(theta * Tau/256);
stheta = Math.sin(theta * Tau/256);

m7a = Math.round(ctheta * dist);
m7b = Math.round(stheta * dist / par);
m7c = Math.round(-stheta * dist);
m7d = Math.round(ctheta * dist / par);
m7x = xpos;
m7y = ypos;
m7hofs = xpos-xcenter;
m7vofs = ypos-ycenter;
return [m7a, m7b, m7c, m7d, m7x, m7y, m7hofs, m7vofs];
What other useful formulas for parameters have you discovered? One for a flat plane receding to the horizon like in F-Zero? The inside of a cylinder like in Super Castlevania IV?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Formulas for mode 7 parameters

Post by tepples »

This one compensates for the half-scanline vertical offset in every second field of an interlaced signal.

Code: Select all

// If you thought 480i was just for Dreamcast and later, think again.
// bottomfield=1 moves everything up by half a scanline,
// adding precision for the bottom field of an interlaced signal

Tau = 2*Math.PI;  // radians per turn, about 6.283
xpos = 128;
ypos = 0;
xcenter = 128;
ycenter = 224;  // in interlace mode, we're effectively 256x448
theta = framecount;
dist = 144 * (1 + .5 * Math.sin(framecount * Tau/512));
par = 2.286;
bottomfield = framecount%2;

ctheta = Math.cos(theta * Tau/256);
stheta = Math.sin(theta * Tau/256);

m7a = Math.round(ctheta * dist);
m7b = Math.round(stheta * dist / par);
m7c = Math.round(-stheta * dist);
m7d = Math.round(ctheta * dist / par);
m7x = xpos;
m7y = ypos;
m7hofs = xpos-xcenter;
m7vofs = ypos-ycenter+scanline+bottomfield;
return [m7a, m7b, m7c, m7d, m7x, m7y, m7hofs, m7vofs];
User avatar
Nikku4211
Posts: 569
Joined: Sun Dec 15, 2019 1:28 pm
Location: Florida
Contact:

Re: Formulas for mode 7 parameters

Post by Nikku4211 »

I have made a revised version of Nova's tool (revised source) that allows you to change the aspect ratio of the screen easily, as well as toggling overscan(which doesn't affect the pixel aspect ratio value).

You can even automatically double the vertical resolution at the cost of the framerate. Unfortunately, I didn't have the skills to program in a real interlace simulator, so it looks more like 480p30 than 480i30.

And don't worry about the licence, the bottom link now links to the original source code, and you can view my source code modifications using the View Page Source function most browsers have, since there's no PHP or other server side scripting in my site.
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.
Post Reply