Blog

Game Dev: Mode7 Demo in HTML5

I recently got interested in remaking some classic console games using modern tools. I decided to try emulating the old Mode7 type games in a browser using HTML5 canvas tools. Since I have never actually developed a Mode7 game for the old consoles, my knowledge here might be a bit lacking. However, the gist of what I was able to glean was that Mode7 was a hardware accelerated way to quickly transform and draw background images to give the illusion of perspective. The background was scaled and rotated on a scanline by scanline basis to allow for this illusion.

The Maths

To emulate Mode7 we will need to use software techniques to simulate the scaling and rotating of scanlines. My ultimate goal was to simulate a kart racing type of game using this technique and HTML5 canvas. In this type of a game, the player is followed closely by a camera that shows the player along with the race track in a three-dimensional perspective. As with most 3D rendering, this perspective, or viewport, has many properties such as the viewing angle, field of view, height, etc. For my purposes, the viewport has six, relatively static, properties that affect the look and feel of the viewport. They are as follows:

  • Horizontal Field-of-View Angle = Fh
  • Vertical Field-of-View Angle = Fv
  • Camera z Location = Cz
  • Camera Tilt Angle = Cθ
  • Viewport Height = Vh
  • Viewport Width = Vw


Additionally, there are three properties that are dynamic and related to the movement of the player in the game:

  • Player (cart) x Location = Px
  • Player (cart) y Location = Py
  • Player (cart) Angle = Pθ

Since we are starting with a flat racing track and fixing the cart only to the surface of the track, we only need to know the location of the cart and it's orientation.

Let's take a closer look at each of the viewport properties and what they mean. The Field-of-View properties might be thought of as the lens of the camera. Some lenses are wide-angle and allow us to capture images at very extreme angles, other lenses are narrow and only show what is directly in front of the lens (like a microscope). The Field-of-View properties have a very close relationship with the Viewport size and are typically directly proportional to the size of the viewport, otherwise some distortion of the image would occur. Most 3D libraries abstract these angle values away from the developer using ratios and multipliers to modify the Field-of-View. Since we are implementing the rendering directly we will need the actual angles to calculate what pixels to draw.

As mentioned before, this algorithm will focus on scanline rendering, this means that we will be drawing the scene one row at a time. The drawing operation will really just be grabbing a set of pixels and then transforming them to a single scanline. We therefore need a few more variables, the number of scanlines and their height. For the sake of simplicity, we are also going to require that the viewport height be a multiple of the number of scanlines times their height. If we let the number of scanlines be S, and the set of scanlines be sl(0) to sl(S-1). Each scanline should correspond to a trapezoidal shape that represents the visible region for that scanline. To find this trapezoidal area, we will need to identify the starting and ending vertical Field-of-View angles we will be using for each scanline.

Demo Time!

WANT TO TALK SHOP ?

I enjoy speaking to anyone who has a question or a thought about me or my projects. Or maybe you have a project of your own you would like to share?
Feel free to reach out on social media or contact me privately using my contact form.
I am looking forward to hearing from you!

Contact Me