#include "foot-emulator.h" #include #include #include namespace { std::vector read_file(std::istream& stream) { std::vector buf; std::streampos pos = stream.tellg(); stream.seekg(0, std::ios::end); pos = stream.tellg() - pos; buf.resize(pos / 2); stream.seekg(0, std::ios::beg); for (int i = 0; i < buf.size(); i++) { char value[2] = {0, 0}; stream.read(value, 2); buf[i] = (uint16_t(value[0]) << 8) | (uint16_t(value[1]) & 0xFF); } return buf; } class PrintDevice : public foot::Device { public: PrintDevice() : Device(1) { } bool update() override { uint16_t& value = memory(0); if (value != 0) { std::cout << char(value); value = 0; } return false; } }; class MemoryViewDevice : public foot::Device { public: MemoryViewDevice(SDL_Renderer* render, uint8_t width, uint8_t height) : Device(width * height / 2), render(render), texture(SDL_CreateTexture(render, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, width, height)), width(width), height(height) {} ~MemoryViewDevice() { SDL_DestroyTexture(texture); } bool update() override { int pitch; uint8_t* pixels; if (!SDL_LockTexture(texture, nullptr, (void**)&pixels, &pitch)) { std::cout << SDL_GetError() << std::endl; } int idx = 0; for (int i = 0; i < width / 2; i++) { for (int j = 0; j < height; j++) { const uint16_t mem = memory(i + j * width / 2); const uint8_t left = mem & 0xFF; const uint8_t right = mem >> 8; pixels[idx + 0] = left; pixels[idx + 1] = left; pixels[idx + 2] = left; pixels[idx + 3] = right; pixels[idx + 4] = right; pixels[idx + 5] = right; idx += 6; } } SDL_UnlockTexture(texture); SDL_RenderPresent(render); SDL_Event event; bool stop = false; while (SDL_PollEvent(&event)) { if (event.type == SDL_EVENT_QUIT) { stop = true; } } return stop; } private: SDL_Renderer* render; SDL_Texture* texture; uint8_t width; uint8_t height; }; } int main(int argc, char** argv) { if (argc > 1) { constexpr int WIDTH = 64; constexpr int HEIGHT = 64; std::ifstream file(argv[1], std::ios::binary); if (!file.is_open()) { std::cerr << "Failed to open file: " << argv[1] << std::endl; return 1; } SDL_Window* window; SDL_Renderer* render; SDL_Init(SDL_INIT_VIDEO); SDL_CreateWindowAndRenderer("foot emulator", WIDTH * 4, HEIGHT * 4, 0, &window, &render); foot::Emulator emu; emu.map_device(std::make_unique()); emu.map_device(std::make_unique(render, WIDTH, HEIGHT)); emu.run(read_file(file)); SDL_DestroyRenderer(render); SDL_DestroyWindow(window); SDL_Quit(); return 0; } else { std::cout << "Usage: " << argv[0] << " " << std::endl; } return 1; }