Emulation of the 1970's Chip-8 machine. The emulator has 7 games that are unmodified from the original Chip-8 format.

Dependencies:   mbed

main.cpp

Committer:
taylorza
Date:
2015-02-08
Revision:
0:bc3f11b1b41f

File content as of revision 0:bc3f11b1b41f:

#include "mbed.h"
#include "LCD_ST7735.h"
#include "Color565.h"
#include "font_OEM.h"
#include "GameInput.h"
#include "Chip8Emulator.h"

#include "SpaceInvadersGame.h"
#include "BrixGame.h"
#include "BlinkyGame.h"
#include "PongGame.h"
#include "TetrisGame.h"
#include "MissileGame.h"
#include "UfoGame.h"

LCD_ST7735 screen(P0_19, P0_20, P0_7, P0_21, P0_22, P1_15, P0_2, LCD_ST7735::RGB);


void menu(const uint8_t **program, uint16_t &programSize, uint8_t &leftKey, uint8_t &rightKey, uint8_t &upKey, uint8_t &downKey, uint8_t &fireKey, uint8_t &startKey);
void drawString(const uint8_t *pFont, int y, const char *string);

main()
{    
    screen.setOrientation(LCD_ST7735::Rotate270, false);
    
    const uint8_t *program;
    uint16_t programSize;
    uint8_t leftKey;
    uint8_t rightKey;
    uint8_t upKey;
    uint8_t downKey;
    uint8_t fireKey;
    uint8_t startKey;
    
    menu(&program, programSize, leftKey, rightKey, upKey, downKey, fireKey, startKey);
    Chip8Emulator emulator(screen, program, programSize, leftKey, rightKey, upKey, downKey, fireKey, startKey);
    emulator.run();
}

struct MenuItem
{
    const char *Text;
    const uint8_t *Program;
    const uint16_t ProgramSize;
    const uint8_t LeftKey;
    const uint8_t RightKey;
    const uint8_t UpKey;
    const uint8_t DownKey;
    const uint8_t FireKey;
    const uint8_t StartKey;
    
    MenuItem(const char *text, const uint8_t *program, const uint16_t programSize, uint8_t leftKey, uint8_t rightKey, uint8_t upKey, uint8_t downKey, uint8_t fireKey, uint8_t startKey) :
        Text(text),
        Program(program),
        ProgramSize(programSize),
        LeftKey(leftKey),
        RightKey(rightKey),
        UpKey(upKey),
        DownKey(downKey),
        FireKey(fireKey),
        StartKey(startKey)
    {
        
    }
};

MenuItem menuItems[] = 
{
    MenuItem("Invaders", SpaceInvadersGame, sizeof(SpaceInvadersGame), 4, 6, 2, 8, 5, 15),
    MenuItem("Brix", BrixGame, sizeof(BrixGame), 4, 6, 2, 8, 5, 15),    
    MenuItem("Blinky", BlinkyGame, sizeof(BlinkyGame), 7, 8, 3, 6, 1, 15),    
    MenuItem("Tetris", TetrisGame, sizeof(TetrisGame), 5, 6, 4, 0, 0, 0),
    MenuItem("Pong", PongGame, sizeof(PongGame), 0, 0, 1, 4, 0, 0),
    MenuItem("Missile", MissileGame, sizeof(MissileGame), 8, 8, 8, 8, 8, 8),
    MenuItem("UFO", UfoGame, sizeof(UfoGame), 4, 6, 5, 8, 5, 15),    
};

void drawString(const uint8_t *pFont, int y, const char *string)
{
    uint8_t w;
    uint8_t h;
    screen.measureString(pFont, string, w, h);
    screen.drawString(pFont, (screen.getWidth() - w) / 2, y, string);    
}

void menu(const uint8_t **program, uint16_t &programSize, uint8_t &leftKey, uint8_t &rightKey, uint8_t &upKey, uint8_t &downKey, uint8_t &fireKey, uint8_t &startKey)
{
    screen.clearScreen();
    
    drawString(font_oem, 0, "CHIP-8 Emulator");
    drawString(font_oem, 120, "(c)2015 Chris Taylor");
    
    int itemCount = sizeof(menuItems) / sizeof(menuItems[0]);
    int selectedItem = 0;
    int counter = 0;
    while(true)
    {    
        counter++;
        for (int i = 0; i < itemCount; ++i)
        {
            if (selectedItem == i)
            {
                screen.setForegroundColor(Color565::Yellow);
                screen.setBackgroundColor(Color565::Blue);
            }
            else
            {
                screen.setForegroundColor(Color565::Yellow);
                screen.setBackgroundColor(Color565::Black);
            }
                        
            int menuTop = (screen.getHeight() - (itemCount * 10)) / 2;
            drawString(font_oem, menuTop + (i * 10), menuItems[i].Text);
        }
        
        if (GameInput::isUpPressed()) 
        {
            --selectedItem;
            if (selectedItem < 0) selectedItem = itemCount - 1;            
            wait_ms(200);
        }
        else if (GameInput::isDownPressed()) 
        {
            ++selectedItem;
            if (selectedItem >= itemCount) selectedItem = 0;            
            wait_ms(200);
        }        
        else if (GameInput::isCirclePressed())
        {
            *program = menuItems[selectedItem].Program;
            programSize = menuItems[selectedItem].ProgramSize;
            leftKey = menuItems[selectedItem].LeftKey;
            rightKey = menuItems[selectedItem].RightKey;
            upKey = menuItems[selectedItem].UpKey;
            downKey = menuItems[selectedItem].DownKey;
            fireKey = menuItems[selectedItem].FireKey;
            startKey = menuItems[selectedItem].StartKey;
            
            wait_ms(200);
            srand(counter);
            return;
        }
    }
}