#ifndef PLAY96_HPP
#define PLAY96_HPP
#include "play96.h"
#include <stdexcept>
#include <string>
namespace play96 {
struct Color {
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha = 255;
};
class Session {
public:
Session(const char* core_path, const char* cartridge_path) {
check(play96_create(core_path, cartridge_path, &session_));
}
~Session() { play96_destroy(session_); }
Session(const Session&) = delete;
Session& operator=(const Session&) = delete;
Session(Session&& other) noexcept : session_(other.session_) { other.session_ = nullptr; }
Session& operator=(Session&& other) noexcept {
if (this != &other) {
play96_destroy(session_);
session_ = other.session_;
other.session_ = nullptr;
}
return *this;
}
void run_frame() { check(play96_run_frame(session_)); }
void run_frames(size_t frames) { check(play96_run_frames(session_, frames)); }
void set_button(unsigned port, unsigned button, bool pressed) { check(play96_set_button(session_, port, button, pressed)); }
void clear_buttons(unsigned port = 0) { check(play96_clear_buttons(session_, port)); }
unsigned width() const { return play96_framebuffer_width(session_); }
unsigned height() const { return play96_framebuffer_height(session_); }
uint32_t pixel_xrgb(unsigned x, unsigned y) const { return play96_pixel_xrgb(session_, x, y); }
void assert_pixel(unsigned x, unsigned y, Color color) const {
check(play96_assert_pixel(session_, x, y, {color.red, color.green, color.blue, color.alpha}));
}
void assert_pixel_xrgb(unsigned x, unsigned y, uint32_t color) const { check(play96_assert_pixel_xrgb(session_, x, y, color)); }
void save_state(const char* path) { check(play96_save_state(session_, path)); }
void load_state(const char* path) { check(play96_load_state(session_, path)); }
void write_png(const char* path) const { check(play96_write_png(session_, path)); }
private:
static void check(const char* error) {
if (error) throw std::runtime_error(error);
}
play96_session* session_ = nullptr;
};
}
#endif