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

Dependencies:   mbed

Committer:
taylorza
Date:
Sun Feb 08 01:58:57 2015 +0000
Revision:
0:bc3f11b1b41f
Chip-8 Emulator

Who changed what in which revision?

UserRevisionLine numberNew contents of line
taylorza 0:bc3f11b1b41f 1 #include "mbed.h"
taylorza 0:bc3f11b1b41f 2 #include "LCD_ST7735.h"
taylorza 0:bc3f11b1b41f 3 #include "Color565.h"
taylorza 0:bc3f11b1b41f 4 #include "font_OEM.h"
taylorza 0:bc3f11b1b41f 5 #include "GameInput.h"
taylorza 0:bc3f11b1b41f 6 #include "Chip8Emulator.h"
taylorza 0:bc3f11b1b41f 7
taylorza 0:bc3f11b1b41f 8 #include "SpaceInvadersGame.h"
taylorza 0:bc3f11b1b41f 9 #include "BrixGame.h"
taylorza 0:bc3f11b1b41f 10 #include "BlinkyGame.h"
taylorza 0:bc3f11b1b41f 11 #include "PongGame.h"
taylorza 0:bc3f11b1b41f 12 #include "TetrisGame.h"
taylorza 0:bc3f11b1b41f 13 #include "MissileGame.h"
taylorza 0:bc3f11b1b41f 14 #include "UfoGame.h"
taylorza 0:bc3f11b1b41f 15
taylorza 0:bc3f11b1b41f 16 LCD_ST7735 screen(P0_19, P0_20, P0_7, P0_21, P0_22, P1_15, P0_2, LCD_ST7735::RGB);
taylorza 0:bc3f11b1b41f 17
taylorza 0:bc3f11b1b41f 18
taylorza 0:bc3f11b1b41f 19 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);
taylorza 0:bc3f11b1b41f 20 void drawString(const uint8_t *pFont, int y, const char *string);
taylorza 0:bc3f11b1b41f 21
taylorza 0:bc3f11b1b41f 22 main()
taylorza 0:bc3f11b1b41f 23 {
taylorza 0:bc3f11b1b41f 24 screen.setOrientation(LCD_ST7735::Rotate270, false);
taylorza 0:bc3f11b1b41f 25
taylorza 0:bc3f11b1b41f 26 const uint8_t *program;
taylorza 0:bc3f11b1b41f 27 uint16_t programSize;
taylorza 0:bc3f11b1b41f 28 uint8_t leftKey;
taylorza 0:bc3f11b1b41f 29 uint8_t rightKey;
taylorza 0:bc3f11b1b41f 30 uint8_t upKey;
taylorza 0:bc3f11b1b41f 31 uint8_t downKey;
taylorza 0:bc3f11b1b41f 32 uint8_t fireKey;
taylorza 0:bc3f11b1b41f 33 uint8_t startKey;
taylorza 0:bc3f11b1b41f 34
taylorza 0:bc3f11b1b41f 35 menu(&program, programSize, leftKey, rightKey, upKey, downKey, fireKey, startKey);
taylorza 0:bc3f11b1b41f 36 Chip8Emulator emulator(screen, program, programSize, leftKey, rightKey, upKey, downKey, fireKey, startKey);
taylorza 0:bc3f11b1b41f 37 emulator.run();
taylorza 0:bc3f11b1b41f 38 }
taylorza 0:bc3f11b1b41f 39
taylorza 0:bc3f11b1b41f 40 struct MenuItem
taylorza 0:bc3f11b1b41f 41 {
taylorza 0:bc3f11b1b41f 42 const char *Text;
taylorza 0:bc3f11b1b41f 43 const uint8_t *Program;
taylorza 0:bc3f11b1b41f 44 const uint16_t ProgramSize;
taylorza 0:bc3f11b1b41f 45 const uint8_t LeftKey;
taylorza 0:bc3f11b1b41f 46 const uint8_t RightKey;
taylorza 0:bc3f11b1b41f 47 const uint8_t UpKey;
taylorza 0:bc3f11b1b41f 48 const uint8_t DownKey;
taylorza 0:bc3f11b1b41f 49 const uint8_t FireKey;
taylorza 0:bc3f11b1b41f 50 const uint8_t StartKey;
taylorza 0:bc3f11b1b41f 51
taylorza 0:bc3f11b1b41f 52 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) :
taylorza 0:bc3f11b1b41f 53 Text(text),
taylorza 0:bc3f11b1b41f 54 Program(program),
taylorza 0:bc3f11b1b41f 55 ProgramSize(programSize),
taylorza 0:bc3f11b1b41f 56 LeftKey(leftKey),
taylorza 0:bc3f11b1b41f 57 RightKey(rightKey),
taylorza 0:bc3f11b1b41f 58 UpKey(upKey),
taylorza 0:bc3f11b1b41f 59 DownKey(downKey),
taylorza 0:bc3f11b1b41f 60 FireKey(fireKey),
taylorza 0:bc3f11b1b41f 61 StartKey(startKey)
taylorza 0:bc3f11b1b41f 62 {
taylorza 0:bc3f11b1b41f 63
taylorza 0:bc3f11b1b41f 64 }
taylorza 0:bc3f11b1b41f 65 };
taylorza 0:bc3f11b1b41f 66
taylorza 0:bc3f11b1b41f 67 MenuItem menuItems[] =
taylorza 0:bc3f11b1b41f 68 {
taylorza 0:bc3f11b1b41f 69 MenuItem("Invaders", SpaceInvadersGame, sizeof(SpaceInvadersGame), 4, 6, 2, 8, 5, 15),
taylorza 0:bc3f11b1b41f 70 MenuItem("Brix", BrixGame, sizeof(BrixGame), 4, 6, 2, 8, 5, 15),
taylorza 0:bc3f11b1b41f 71 MenuItem("Blinky", BlinkyGame, sizeof(BlinkyGame), 7, 8, 3, 6, 1, 15),
taylorza 0:bc3f11b1b41f 72 MenuItem("Tetris", TetrisGame, sizeof(TetrisGame), 5, 6, 4, 0, 0, 0),
taylorza 0:bc3f11b1b41f 73 MenuItem("Pong", PongGame, sizeof(PongGame), 0, 0, 1, 4, 0, 0),
taylorza 0:bc3f11b1b41f 74 MenuItem("Missile", MissileGame, sizeof(MissileGame), 8, 8, 8, 8, 8, 8),
taylorza 0:bc3f11b1b41f 75 MenuItem("UFO", UfoGame, sizeof(UfoGame), 4, 6, 5, 8, 5, 15),
taylorza 0:bc3f11b1b41f 76 };
taylorza 0:bc3f11b1b41f 77
taylorza 0:bc3f11b1b41f 78 void drawString(const uint8_t *pFont, int y, const char *string)
taylorza 0:bc3f11b1b41f 79 {
taylorza 0:bc3f11b1b41f 80 uint8_t w;
taylorza 0:bc3f11b1b41f 81 uint8_t h;
taylorza 0:bc3f11b1b41f 82 screen.measureString(pFont, string, w, h);
taylorza 0:bc3f11b1b41f 83 screen.drawString(pFont, (screen.getWidth() - w) / 2, y, string);
taylorza 0:bc3f11b1b41f 84 }
taylorza 0:bc3f11b1b41f 85
taylorza 0:bc3f11b1b41f 86 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)
taylorza 0:bc3f11b1b41f 87 {
taylorza 0:bc3f11b1b41f 88 screen.clearScreen();
taylorza 0:bc3f11b1b41f 89
taylorza 0:bc3f11b1b41f 90 drawString(font_oem, 0, "CHIP-8 Emulator");
taylorza 0:bc3f11b1b41f 91 drawString(font_oem, 120, "(c)2015 Chris Taylor");
taylorza 0:bc3f11b1b41f 92
taylorza 0:bc3f11b1b41f 93 int itemCount = sizeof(menuItems) / sizeof(menuItems[0]);
taylorza 0:bc3f11b1b41f 94 int selectedItem = 0;
taylorza 0:bc3f11b1b41f 95 int counter = 0;
taylorza 0:bc3f11b1b41f 96 while(true)
taylorza 0:bc3f11b1b41f 97 {
taylorza 0:bc3f11b1b41f 98 counter++;
taylorza 0:bc3f11b1b41f 99 for (int i = 0; i < itemCount; ++i)
taylorza 0:bc3f11b1b41f 100 {
taylorza 0:bc3f11b1b41f 101 if (selectedItem == i)
taylorza 0:bc3f11b1b41f 102 {
taylorza 0:bc3f11b1b41f 103 screen.setForegroundColor(Color565::Yellow);
taylorza 0:bc3f11b1b41f 104 screen.setBackgroundColor(Color565::Blue);
taylorza 0:bc3f11b1b41f 105 }
taylorza 0:bc3f11b1b41f 106 else
taylorza 0:bc3f11b1b41f 107 {
taylorza 0:bc3f11b1b41f 108 screen.setForegroundColor(Color565::Yellow);
taylorza 0:bc3f11b1b41f 109 screen.setBackgroundColor(Color565::Black);
taylorza 0:bc3f11b1b41f 110 }
taylorza 0:bc3f11b1b41f 111
taylorza 0:bc3f11b1b41f 112 int menuTop = (screen.getHeight() - (itemCount * 10)) / 2;
taylorza 0:bc3f11b1b41f 113 drawString(font_oem, menuTop + (i * 10), menuItems[i].Text);
taylorza 0:bc3f11b1b41f 114 }
taylorza 0:bc3f11b1b41f 115
taylorza 0:bc3f11b1b41f 116 if (GameInput::isUpPressed())
taylorza 0:bc3f11b1b41f 117 {
taylorza 0:bc3f11b1b41f 118 --selectedItem;
taylorza 0:bc3f11b1b41f 119 if (selectedItem < 0) selectedItem = itemCount - 1;
taylorza 0:bc3f11b1b41f 120 wait_ms(200);
taylorza 0:bc3f11b1b41f 121 }
taylorza 0:bc3f11b1b41f 122 else if (GameInput::isDownPressed())
taylorza 0:bc3f11b1b41f 123 {
taylorza 0:bc3f11b1b41f 124 ++selectedItem;
taylorza 0:bc3f11b1b41f 125 if (selectedItem >= itemCount) selectedItem = 0;
taylorza 0:bc3f11b1b41f 126 wait_ms(200);
taylorza 0:bc3f11b1b41f 127 }
taylorza 0:bc3f11b1b41f 128 else if (GameInput::isCirclePressed())
taylorza 0:bc3f11b1b41f 129 {
taylorza 0:bc3f11b1b41f 130 *program = menuItems[selectedItem].Program;
taylorza 0:bc3f11b1b41f 131 programSize = menuItems[selectedItem].ProgramSize;
taylorza 0:bc3f11b1b41f 132 leftKey = menuItems[selectedItem].LeftKey;
taylorza 0:bc3f11b1b41f 133 rightKey = menuItems[selectedItem].RightKey;
taylorza 0:bc3f11b1b41f 134 upKey = menuItems[selectedItem].UpKey;
taylorza 0:bc3f11b1b41f 135 downKey = menuItems[selectedItem].DownKey;
taylorza 0:bc3f11b1b41f 136 fireKey = menuItems[selectedItem].FireKey;
taylorza 0:bc3f11b1b41f 137 startKey = menuItems[selectedItem].StartKey;
taylorza 0:bc3f11b1b41f 138
taylorza 0:bc3f11b1b41f 139 wait_ms(200);
taylorza 0:bc3f11b1b41f 140 srand(counter);
taylorza 0:bc3f11b1b41f 141 return;
taylorza 0:bc3f11b1b41f 142 }
taylorza 0:bc3f11b1b41f 143 }
taylorza 0:bc3f11b1b41f 144 }