// Possible return values : // 0 : execution OK // 1 : Error loading SDL // 2 : Error loading rom file int main(int argc, char* argv[]) { log::add_file_log("chip8.log"); log::core::get()->set_filter(log::trivial::severity >= log::trivial::info); BOOST_LOG_TRIVIAL(info) << "Logging modules initialized, launching chip8++!"; cout << "Starting Chip8_PROGRAM_NAME v" << Chip8_VERSION_MAJOR << '.' << Chip8_VERSION_MINOR << endl; Chip8* context; try { Chip8Config* cfg = Chip8Config::parseCommandLineAndCfg(argc, argv); if(!cfg || !cfg->run()) return 0; context = new Chip8(cfg); BOOST_LOG_TRIVIAL(info) << "Chip8 emulator initialized successfully!"; context->run(); delete context; } catch(Chip8InitError const& e) { cerr << "Error initializing Chip8_PROGRAM_NAME." << endl; BOOST_LOG_TRIVIAL(fatal) << e.what(); return 1; } catch(std::exception e) { cerr << "An unknown exception occured, see log file for details." << endl; BOOST_LOG_TRIVIAL(fatal) << e.what(); throw; } catch(...) { cerr << "An unknown exception occured." << endl; BOOST_LOG_TRIVIAL(fatal) << "Unexpected exception."; throw; } return 0; }
int main(int argc, char* argv[]) { Chip8 cpu; cpu.initialize(); cpu.loadGame("data/TETRIS"); while(true) { cpu.emulateCircle(); cpu.render(); } return 0; }
int main(int argc, char* argv[]) { name = argv[0]; if (argc < 2) { usage(); abort(); } int c; while ((c = getopt(argc, argv, "i:s:m")) != -1) { switch (c) { case 'i': chip8.instructions_per_step = atoi(optarg); break; case 's': chip8.scaleFactor = atoi(optarg); break; case 'm': chip8.muted = true; break; default: usage(); abort(); } } if (optind != argc-1) { usage(); abort(); } char *rom = argv[optind]; chip8.loadProgram(rom); printf("Running at %d instructions per step\n", chip8.instructions_per_step); std::thread exec(run); chip8.initDisplay(); chip8.running = false; exec.join(); return 0; }
void run() { chip8.run(); }
int main() { if (!glfwInit()) { std::cerr << "[Main] Unable to initialize GLFW\n"; return 1; } glfwSetErrorCallback(error_callback); GLFWwindow* window = glfwCreateWindow(1024, 512, "CHIP8 Emulator", NULL, NULL); if (!window) { std::cerr << "[Main] Unable to create GLFW window.\n"; glfwTerminate(); return 1; } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, key_callback); // OpenGL Init glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, 1024, 512, 0); glMatrixMode(GL_MODELVIEW); glViewport(0, 0, 1024, 512); initTexture(); if (chip8.load_rom("PONG")) { std::string title = "CHIP8 - "; title += chip8.loaded_rom_name; glfwSetWindowTitle(window, title.c_str()); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); chip8.cycle(); if (chip8.draw_flag) { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); for (int y = 0; y < 32; ++y) { for (int x = 0; x < 64; ++x) { if (chip8.gfx[(y * 64) + x] == 0) { texture_data[y][x][0] = texture_data[y][x][1] = texture_data[y][x][2] = 33; } else { texture_data[y][x][0] = texture_data[y][x][1] = texture_data[y][x][2] = 204; } } } glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 64, 32, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)texture_data); glBegin(GL_QUADS); glTexCoord2d(0.0, 0.0); glVertex2d(0.0, 0.0); glTexCoord2d(1.0, 0.0); glVertex2d(1024.0, 0.0); glTexCoord2d(1.0, 1.0); glVertex2d(1024.0, 512.0); glTexCoord2d(0.0, 1.0); glVertex2d(0.0, 512.0); glEnd(); glfwSwapBuffers(window); chip8.draw_flag = false; } std::this_thread::sleep_for(std::chrono::microseconds(1200)); } } glfwDestroyWindow(window); glfwTerminate(); return 0; }
void Debugger::parse_line(Chip8 &cpu) { std::string line; std::getline(std::cin, line); if (line.compare("step") == 0 || line.compare("s") == 0 || (line.compare("") == 0 && last_command == STEP)) { cpu.update(true); last_command = STEP; } else if (line.compare(0, 5, "step ", 5) == 0) { line = line.substr(5, line.size()); int count = std::stoi(line); for (int i = 0; i < count; i++) { cpu.update(true); } last_command = STEP; } else if (line.compare(0, 2, "s ", 2) == 0) { line = line.substr(2, line.size()); int count = std::stoi(line); for (int i = 0; i < count; i++) { cpu.update(true); } last_command = STEP; } else if (line.compare("exit") == 0 || last_command == EXIT) { std::cout << "leaving Emulator at: " << std::setbase(16) << cpu.get_PC() << std::endl; exit(0); } else if (line.compare(0, 6, "print ", 6) == 0) { line = line.substr(6, line.size()); if (line.compare("PC") == 0) { std::cout << "PC: " << std::setbase(16) << cpu.get_PC() << std::endl; } else if (line.compare("SP") == 0) { std::cout << "SP: " << std::setbase(16) << cpu.get_SP() << std::endl; } else if (line.compare("I") == 0) { std::cout << "I: " << std::setbase(16) << cpu.get_I() << std::endl; } else if (line.compare("timer") == 0) { std::cout << "TIMER: " << std::setbase(16) << cpu.get_timer() << std::endl; } else if (line.compare("sound") == 0) { std::cout << "SOUND: " << std::setbase(16) << cpu.get_sound() << std::endl; } else if (line.find_first_of("[") != line.npos) { std::string addr = line.substr(line.find_first_of("[") + 1, line.find_last_of("]") - 1); unsigned int num = std::stoul(addr, 0, 16); std::cout << "memory@address[" << std::setbase(16) << num << "]: " << (int)cpu.get_mem(num) << std::endl; } else if (line.find("V(") != line.npos) { std::string addr = line.substr(line.find_first_of("(") + 1, line.find_last_of(")") - 1); unsigned int num = std::stoul(addr, 0, 16); std::cout << "register V(" << std::setbase(16) << num << "): " << (int)cpu.get_V_regs(num) << std::endl; } else if (line.compare("cpu") == 0) { cpu.print_state(); } } else if (line.compare("continue") == 0 || last_command == CONTINUE) { while (true) { cpu.update(); last_command = CONTINUE; } } else { std::cout << "Vigilant-Chip8> Command not recognized.\n"; last_command = INVALID; } }
int main(int argc, char **argv) { srand(time(NULL)); if (argc != 2) { cout << "Usage is : chipote [ROMFILE]" << endl; return EXIT_FAILURE; } // SFML init sf::RenderWindow window; window.create(sf::VideoMode(64 * SCALE, 32 * SCALE), "chipote"); window.setFramerateLimit(60); // display init sf::Image renderer; sf::Texture texture; sf::Sprite sprite; // help: the image is where the pixels are toggled. // the texture/sprite are just here to show the pixels // easily on the SFML window renderer.create(64, 32, sf::Color::Black); texture.loadFromImage(renderer); sprite.setTexture(texture); sprite.setScale(SCALE, SCALE); // chip8 init Chip8 interpreter; interpreter.load(argv[1]); // key bindings init map<int,int> binding_keys; binding_keys[sf::Keyboard::Num1] = uint8_t(0x1); binding_keys[sf::Keyboard::Num2] = uint8_t(0x2); binding_keys[sf::Keyboard::Num3] = uint8_t(0x3); binding_keys[sf::Keyboard::Num4] = uint8_t(0xC); binding_keys[sf::Keyboard::A] = uint8_t(0x4); binding_keys[sf::Keyboard::Z] = uint8_t(0x5); binding_keys[sf::Keyboard::E] = uint8_t(0x6); binding_keys[sf::Keyboard::R] = uint8_t(0xD); binding_keys[sf::Keyboard::Q] = uint8_t(0x7); binding_keys[sf::Keyboard::S] = uint8_t(0x8); binding_keys[sf::Keyboard::D] = uint8_t(0x9); binding_keys[sf::Keyboard::F] = uint8_t(0xE); binding_keys[sf::Keyboard::W] = uint8_t(0xA); binding_keys[sf::Keyboard::X] = uint8_t(0x0); binding_keys[sf::Keyboard::C] = uint8_t(0xB); binding_keys[sf::Keyboard::V] = uint8_t(0xF); sf::Event event; while (window.isOpen()) { // handle events while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) { window.close(); } if (event.type == sf::Event::KeyPressed) { interpreter.is_pressed(binding_keys[event.key.code], true); if (DEBUG && event.key.code == sf::Keyboard::Space) { interpreter.update(); } } if (event.type == sf::Event::KeyReleased) { interpreter.is_pressed(binding_keys[event.key.code], false); } } // update for (int i = 0; i < 7; i++) { if (!DEBUG) { interpreter.update(); // step the machine of 1 cycle } if (interpreter.draw_flag) { interpreter.draw_flag = false; for (int i = 0; i < 2048; i++) { int py = floor(i / 64); int px = floor(i - (py * 64)); if (interpreter.screen[i] == 0) { renderer.setPixel(px, py, sf::Color::Black); } else { renderer.setPixel(px, py, sf::Color::White); } } texture.loadFromImage(renderer); } } // draw window.clear(); window.draw(sprite); window.display(); } return EXIT_SUCCESS; }
int main (int argc, const char * argv[]) { std::printf(" --%s--\n", argv[0]); if (argc < 2) { std::fprintf(stderr, "Missing positional param: .c8 filepath.\n"); return 1; } // take third param to be random seed; or just use time now unsigned randSeed = 0; if (argc >= 4) randSeed = unsigned(atoi(argv[3])); if (randSeed == 0) randSeed = std::time(0); // initialize Chip8 c; c.Initialize(randSeed); // load program if (!c.LoadProgram(argv[1])) { std::fprintf(stderr, "Failed to load program {%s}.\n", argv[1]); return 1; } std::printf("Loaded program: %s\n", argv[1]); if (argc < 3) { std::fprintf(stderr, "Missing second positinal param: cycles to emulate.\n"); return 1; } // dump program head const unsigned lines = 10; for (unsigned i = 0; i < lines; ++i) { uint8_t * prog = c.m_memory + c.s_progRomRamBegin + i*4*2; std::printf(" 0x%02X%02X 0x%02X%02X 0x%02X%02X 0x%02X%02X\n", prog[0], prog[1], prog[2], prog[3], prog[4], prog[5], prog[6], prog[7] ); } // emulate const unsigned cycleCountTarget = unsigned(std::atoi(argv[2])); std::printf("Emulating %u cycles...\n", cycleCountTarget); for (unsigned cycle = 0; cycle < cycleCountTarget; ++cycle) { uint16_t pcPre = c.m_pc; c.EmulateCycle(); const char * format = nullptr; switch (cycle % 4) { case 0: format = " 0x%04X->0x%04X"; break; case 1: format = " 0x%04X->0x%04X"; break; case 2: format = " 0x%04X->0x%04X"; break; case 3: format = " 0x%04X->0x%04X\n"; break; } std::printf(format, pcPre, c.m_opcode); if (pcPre == c.m_pc) { std::printf( "\nHalted on opcode {0x%04X} at pc {0x%04X}.\n", c.m_opcode, c.m_pc ); return 1; } } std::printf("\n"); // just in case we were still printing a table return 0; }
int main(int argc, char* argv[]) { Chip8 chip; if (argc == 2) { string path(argv[1]); chip.loadProgram(path); sf::RenderWindow window(sf::VideoMode(1024, 512), "Chip8"); window.setFramerateLimit(60); window.setKeyRepeatEnabled(false); sf::Clock clock; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); else if (event.type == sf::Event::KeyPressed) { switch (event.key.code) { case sf::Keyboard::Num1: chip.pressKey(0); break; case sf::Keyboard::Num2: chip.pressKey(1); break; case sf::Keyboard::Num3: chip.pressKey(2); break; case sf::Keyboard::Num4: chip.pressKey(3); break; case sf::Keyboard::Q: chip.pressKey(4); break; case sf::Keyboard::W: chip.pressKey(5); break; case sf::Keyboard::E: chip.pressKey(6); break; case sf::Keyboard::R: chip.pressKey(7); break; case sf::Keyboard::A: chip.pressKey(8); break; case sf::Keyboard::S: chip.pressKey(9); break; case sf::Keyboard::D: chip.pressKey(10); break; case sf::Keyboard::F: chip.pressKey(11); break; case sf::Keyboard::Z: chip.pressKey(12); break; case sf::Keyboard::X: chip.pressKey(13); break; case sf::Keyboard::C: chip.pressKey(14); break; case sf::Keyboard::V: chip.pressKey(15); break; } } else if (event.type == sf::Event::KeyReleased) { switch (event.key.code) { case sf::Keyboard::Num1: chip.releaseKey(0); break; case sf::Keyboard::Num2: chip.releaseKey(1); break; case sf::Keyboard::Num3: chip.releaseKey(2); break; case sf::Keyboard::Num4: chip.releaseKey(3); break; case sf::Keyboard::Q: chip.releaseKey(4); break; case sf::Keyboard::W: chip.releaseKey(5); break; case sf::Keyboard::E: chip.releaseKey(6); break; case sf::Keyboard::R: chip.releaseKey(7); break; case sf::Keyboard::A: chip.releaseKey(8); break; case sf::Keyboard::S: chip.releaseKey(9); break; case sf::Keyboard::D: chip.releaseKey(10); break; case sf::Keyboard::F: chip.releaseKey(11); break; case sf::Keyboard::Z: chip.releaseKey(12); break; case sf::Keyboard::X: chip.releaseKey(13); break; case sf::Keyboard::C: chip.releaseKey(14); break; case sf::Keyboard::V: chip.releaseKey(15); break; } } } window.clear(sf::Color::Black); chip.update(clock.restart().asMilliseconds()); window.draw(chip); window.display(); } } return 0; }