|
|
|
|
@ -7,9 +7,64 @@ |
|
|
|
|
#include <SFML/System.hpp> |
|
|
|
|
#include <SFML/Audio.hpp> |
|
|
|
|
#include <SFML/Window/Event.hpp> |
|
|
|
|
#include <SFML/Graphics/RectangleShape.hpp> |
|
|
|
|
#include "dbc.hpp" |
|
|
|
|
#include "chip8.hpp" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Display { |
|
|
|
|
sf::RenderWindow& window; |
|
|
|
|
sf::Texture texture{sf::Vector2u{64,32}}; |
|
|
|
|
sf::Sprite texture_sprite{texture}; |
|
|
|
|
sf::RectangleShape border; |
|
|
|
|
|
|
|
|
|
Display(sf::RenderWindow& window, sf::Vector2f pos, sf::Vector2f size) : |
|
|
|
|
window(window) |
|
|
|
|
{ |
|
|
|
|
float border_width = 2.0f; |
|
|
|
|
texture.setSmooth(false); |
|
|
|
|
|
|
|
|
|
float ratio = (size.x - border_width * 2) / 64.0f; |
|
|
|
|
// rectangle position doesn't include the border because everyone hates humans
|
|
|
|
|
sf::Vector2f border_pos{pos.x + border_width, pos.y + border_width}; |
|
|
|
|
|
|
|
|
|
sf::Vector2f scale{ratio, ratio}; |
|
|
|
|
// have to move in one more time for the border we just moved in for the border
|
|
|
|
|
texture_sprite.setPosition({border_pos.x + border_width, border_pos.y + border_width}); |
|
|
|
|
texture_sprite.setScale(scale); |
|
|
|
|
|
|
|
|
|
border.setPosition(border_pos); |
|
|
|
|
border.setSize({64 * ratio, 32 * ratio}); |
|
|
|
|
border.setOutlineColor({30,20,50,255}); |
|
|
|
|
border.setOutlineThickness(border_width); |
|
|
|
|
border.setFillColor({0,0,0,255}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handle_inputs(Chip8& vm) { |
|
|
|
|
while (const auto event = window.pollEvent()) { |
|
|
|
|
if(event->is<sf::Event::Closed>()) { |
|
|
|
|
window.close(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void update(Chip8& vm) { |
|
|
|
|
handle_inputs(vm); |
|
|
|
|
texture.update((uint8_t *)(vm.video)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void render() { |
|
|
|
|
window.draw(border); |
|
|
|
|
window.draw(texture_sprite); |
|
|
|
|
window.display(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool active() { |
|
|
|
|
return window.isOpen(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]) { |
|
|
|
|
if(argc != 4) { |
|
|
|
|
fmt::print("ERROR!"); |
|
|
|
|
@ -20,22 +75,19 @@ int main(int argc, char* argv[]) { |
|
|
|
|
int cycleDelay = std::stoi(argv[2]); |
|
|
|
|
std::string romFilename{argv[3]}; |
|
|
|
|
|
|
|
|
|
sf::RenderWindow window(sf::VideoMode({1280, 720}), "Simple Game Demo"); |
|
|
|
|
window.setFramerateLimit(60); |
|
|
|
|
window.setVerticalSyncEnabled(true); |
|
|
|
|
|
|
|
|
|
sf::Clock deltaClock; |
|
|
|
|
sf::Clock clock; |
|
|
|
|
sf::Time tick = clock.getElapsedTime(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Chip8 chip8; |
|
|
|
|
chip8.LoadROM(romFilename); |
|
|
|
|
|
|
|
|
|
int videoPitch = sizeof(chip8.video[0]) * VIDEO_WIDTH; |
|
|
|
|
auto lastCycleTime = std::chrono::high_resolution_clock::now(); |
|
|
|
|
|
|
|
|
|
while (window.isOpen()) { |
|
|
|
|
sf::RenderWindow window{sf::VideoMode({1280, 720}), "Chip8 Emulator"}; |
|
|
|
|
window.setFramerateLimit(60); |
|
|
|
|
window.setVerticalSyncEnabled(true); |
|
|
|
|
|
|
|
|
|
Display display{window, {0, 0}, {1000, 1000}}; |
|
|
|
|
|
|
|
|
|
while (display.active()) { |
|
|
|
|
auto currentTime = std::chrono::high_resolution_clock::now(); |
|
|
|
|
float dt = std::chrono::duration<float, std::chrono::milliseconds::period>(currentTime - lastCycleTime).count(); |
|
|
|
|
|
|
|
|
|
@ -45,7 +97,7 @@ int main(int argc, char* argv[]) { |
|
|
|
|
chip8.Cycle(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
window.clear(); |
|
|
|
|
window.display(); |
|
|
|
|
display.update(chip8); |
|
|
|
|
display.render(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|