0
\$\begingroup\$

I've been studying mode7 from the SNES, and looking how to build it myself in C++.

I've found plenty of examples in SDL for rendering stuff like Mariokart levels, where the mode7 effect is applied by 'hovering' over a picture.

What I'm wondering is, is how difficult it would be to apply transformations like shown in this gif from 7th Saga: starting with a normal, top-down view on a image and then rotating, zooming and ending up in the 'mariokart-like' perspective.

Is this worthwile to build manually in pixel-by-pixel transformations, or should I be making this in a true 3D environment like OpenGL?

Or Maybe some kind of in-between solution, where I use SDL to transform/rotate textures, and then use manual pixel manipulation?

For reference, this is a project I've been studying for Mode7: https://github.com/jmermar/Mode7-SDL

enter image description here

New contributor
Oli is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Using full 3D, it's pretty easy. You're simply moving & rotating the camera relative to a textured quad or flat mesh.

Using pixels only, it's more challenging. The mapping formula is available on Wikipedia:

Mode 7 graphics are generated for each pixel by mapping screen coordinate \$r\$ to background coordinate \$r'\$ using an affine transformation and sampling the corresponding background color. The 2D affine transformation is specified for each scanline by 6 parameters; \$a,b,c, d\$ define the matrix \$M\$, while \$x_0\$ and \$y_0\$ define the vector \$r_0\$ locates the origin of the matrix transformation and is related to a translation vector. Specifically, screen coordinate \$r\$is translated to the origin coordinate system, the matrix is applied, and the result is translated back to the original coordinate system to obtain \$r'\$. In 2D matrix notation, this is written as: $$r'=M(r-r_0)+r_0 \\ \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix} ( \begin{bmatrix} x \\ y \end{bmatrix} - \begin{bmatrix} x_0 \\ y_0 \end{bmatrix}) + \begin{bmatrix} x_0 \\ y_0 \end{bmatrix} $$ All arithmetic is carried out on 16-bit signed fixed point numbers, while all offsets are limited to 13 bits. The radix point is between bits 7 and 8.

If you're looking at the historical, pixel manipulation method, it's worth mentioning that the original implementation had some rounding errors that resulted in visual artifacts - the output looked somewhat blocky & had visual artifacts:

comparison of mode 7 output with & with math corrections

The above was taken from this video clip.

As to which approach you should use - only you can answer that. That depends on your time, interest, skills, constraints and other things not covered in the question & beyond the scope of GDSE recommendations. My advice would be to consider the pros & cons of those factors & choose accordingly.

\$\endgroup\$
2
  • \$\begingroup\$ I think I'll dive into some of the matrix stuff, see where it gets me..thanks \$\endgroup\$
    – Oli
    Aug 6 at 6:42
  • \$\begingroup\$ @Oli Sounds good. It's interesting how they tackled problems with what they had (which why I've loosely keep tabs on some of it) & the resulting magic they squeezed out of that hardware was ahead of its time. Dev decisions should be a means to end & usually that means "which thing gets me closer to a finished/fun game". Going back to original works can be illuminating, but we also shouldn't feel unnecessarily beholden to them. It's equally valid to leverage modern APIs. Whatever your choice, good luck with your project. \$\endgroup\$
    – Pikalek
    Aug 6 at 15:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .