/vga_9s12

vga adaptation for the 9s12c32 microcontroller

Primary LanguageC

Welcome to Super Smash Bros. Bitbang!

In this README we attempt to briefly explain some of the more
interesting concepts of the project in an organized manner.
Info on the VGA has yet to be added. If you have any ideas
you would like to contribute, feel free to fork and send a pull request. 

Contents:
    1. Directory Structure
    2. Screen Buffer
    3. Image Generation
    4. Physics Explained


#################################
# Directory Structure
#################################

The vga_9s12 directory is organized into (currently) eight
directories:

    doc     src     test       controller   images  ssb_orcad_schematic
    
    PLD_ChipRpt     xirq_hsync

## src:

The src directory contains the main source file, named
"smashbitbang.c". This file includes many of the .h files in the
"include" subdirectory. Most of the .h files are actually images.
The only non-image headers are the "character.h", "platform.h",
and "ourimages.h" files. The "character.h" file defines the
character structure and member functions and instantiates the players.
The "platform.h" file defines the platform structure used for
collision detection. The "ourimages.h" file includes all of the images
that are used in the game.

## doc:

The doc directory contains the report written for our project and
submitted for the class. It also contains a mapping of the 9s12
pin connections.

## images:

The images file contains many images. The character, level, and number
images are split into their own directories. Photos of our project are
in the photos subdirectory. There are three important scripts in this
directory that do the work of converting the images into hex values
that can be stored in flash on the target microcontroller. The
"convert.py" is a python script that converts one image given as an
argument to a ".h" file. The runall.sh bash script runs the python
script on all png files in the current directory. The update.sh
bash script only works from the directory it is currently in. It copies
all ".h" files in the current directory to the src/include folder.

## test

The test directory contains the "test_movement.c" file that was
written to run on a standard PC. It was used to test displaying
images to the screen and character movement while the VGA was
still under development.


#################################
# Screen Buffer
#################################

In the src/smashbitban.c file, there is a global variable named
"screen". This screen variable is 1152 bytes. The bytes correspond
to 48x48 pixels where every byte contains two pixels. Thus
48*24=1152. Storing two pixels in every byte saved us space and made
pushing pixels out on the port pins pretty fast, but also added
complexity to the image drawing and image erasing functions. When
drawing the menu, the character select screen, or the field select
screen, the screen buffer is only updated when a change is made.
During gameplay, the screen is update every tenth of a second. Each
character is first erased at their previous location and frame. Next,
each character is drawn at their new location and frame. Note that
when a character is erased, the background is simply drawn on top
of them.



#################################
# Image Generation
#################################

Most of the images were drawn using kolourpaint. Every image was
saved as a png to add compression, but avoid the image smudging
that a jpeg introduces. The PIL library in Python was used to
open the image and extract all of the pixels at once into a
giant 2-dimensional array of pixels. Each pixel is traversed
using a double for loop, and the hex data is assigned corresponding
to the color of the pixel. Valid C code is generated, and the
image information is written in hex. The color mappings are
as follows:

       rgb
white: 111
black: 000
blue:  001
green: 010
red:   100
pink:  101
yellow:110
brown: 011  // This would be cyan, but we remapped it in our circuit



#################################
# Physics Explained
#################################

Acceleration, velocity, and position are tracked for both characters
in the game. The acceleration and velocity are stored as 1/v and 1/a,
where "v" is velocity and "a" is acceleration. The reason for this
is that floating point arithmetic is ineffecient to implement on an
embedded device. This choice in storing velocity and acceleration also
worked well with the Timer interrupt. Each velocity and acceleration
value comes paired with a counter that keeps track of when the
velocity and position values should be updated. For example, if my
velocity is 500 miliseconds, then I update the players position by
one pixel every 500 miliseconds. In the case of the code implemented,
the Timer interrupt occurs every 10 milliseconds, so the corresponding
velocity value would not be 500, but 50. Every time the velocity counter
(incremented each time the timer is called) reaches 50, then the position
is updated. In the same manner, the velocity is affected by the
acceleration. The position is still stored in x and y coordinates (in
case you wondered).
While the position is updated by one every time, the velocity is updated
as a function of the acceleration value. The formula is as follows:

vnext = (vprev*acurr)/(vprev + acurr)

vnext: The updated velocity value
acurr: The current acceleration value (controlled by the analog joystick)
vprev: The previous/current velocity value

This formula works well on the microcontroller, because the division,
where round off errors occur, can be done last.

Given the above system, jumping was easy to implement. The player
is given an initial velocity "up", and a constant acceleration "down".