Skip to content

Commit

Permalink
Accept link cable data via a TCP port
Browse files Browse the repository at this point in the history
  • Loading branch information
jgilchrist committed Apr 29, 2024
1 parent 6da0405 commit 0cdeb99
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 20 deletions.
26 changes: 13 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ add_warnings()
declare_library(gbemu-core src)

# SFML target
# find_package(SFML 2 COMPONENTS system window graphics)
find_package(SFML 2 COMPONENTS system window graphics network)

# if (SFML_FOUND)
# declare_executable(gbemu-sfml platforms/sfml)
# include_directories(SYSTEM ${SFML_INCLUDE_DIR})
# target_link_libraries(gbemu-sfml gbemu-core ${SFML_LIBRARIES})
# endif()
if (SFML_FOUND)
declare_executable(gbemu-sfml platforms/sfml)
include_directories(SYSTEM ${SFML_INCLUDE_DIR})
target_link_libraries(gbemu-sfml gbemu-core ${SFML_LIBRARIES})
endif()

# SDL target
find_package(SDL2)

if (SDL2_FOUND)
declare_executable(gbemu platforms/sdl)
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
target_link_libraries(gbemu gbemu-core ${SDL2_LIBRARIES})
endif()
# find_package(SDL2)
#
# if (SDL2_FOUND)
# declare_executable(gbemu platforms/sdl)
# include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
# target_link_libraries(gbemu gbemu-core ${SDL2_LIBRARIES})
# endif()

# Test target
declare_executable(gbemu-test platforms/test)
Expand Down
57 changes: 56 additions & 1 deletion platforms/sfml/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include "../cli/cli.h"

#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>

#include <fstream>
#include <iterator>
#include <chrono>

static uint pixel_size = 5;

Expand All @@ -16,6 +18,10 @@ static sf::Image image;
static sf::Texture texture;
static sf::Sprite sprite;

static sf::TcpListener listener;
static sf::TcpSocket client;
static long long last_serial_interaction_at;

static std::unique_ptr<Gameboy> gameboy;

static CliOptions cliOptions;
Expand Down Expand Up @@ -145,13 +151,62 @@ static void draw(const FrameBuffer& buffer) {
window->display();
}

static u8 get_serial_data() {
long long current_time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();

if (client.getRemoteAddress() == sf::IpAddress::None) {
if (listener.accept(client) != sf::Socket::Done) {
return 0xFF;
}

client.setBlocking(false);

log_info("Serial data connection made");
last_serial_interaction_at = current_time;
return 0xFF;
}

// Been too long since we last received data. Terminate the connection and allow something else to connect.
if (current_time - last_serial_interaction_at > 10) {
log_info("Nothing received on serial port for ~10 seconds - disconnecting.");
client.disconnect();
return last_serial_interaction_at;
}


char data[1];
std::size_t received;

if (client.receive(data, 1, received) != sf::Socket::Done)
{
return 0xFF;
}

u8 serial_data = data[0];
log_info("Received 0x%02X", serial_data);

last_serial_interaction_at = current_time;

return serial_data;
}

static bool is_closed() {
return !window->isOpen() || should_exit;
}

int main(int argc, char* argv[]) {
cliOptions = get_cli_options(argc, argv);

auto serial_data_port = 51234;
auto status = listener.listen(serial_data_port);
if (status != sf::Socket::Done)
{
fatal_error("Unable to listen");
}
listener.setBlocking(false);

log_info("Listening to port %d for serial data", serial_data_port);

window = std::make_unique<sf::RenderWindow>(sf::VideoMode(width, height), "gbemu", sf::Style::Titlebar | sf::Style::Close);
image.create(width, height);
window->setFramerateLimit(60);
Expand All @@ -166,6 +221,6 @@ int main(int argc, char* argv[]) {
log_info("");

gameboy = std::make_unique<Gameboy>(rom_data, cliOptions.options, save_data);
gameboy->run(&is_closed, &draw);
gameboy->run(&is_closed, &draw, &get_serial_data);
return 0;
}
6 changes: 5 additions & 1 deletion platforms/test/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ static bool is_closed() {
return false;
}

static u8 get_serial_data() {
return 0x0;
}

int main(int argc, char* argv[]) {
CliOptions cliOptions = get_cli_options(argc, argv);
auto rom_data = read_bytes(cliOptions.filename);
gameboy = std::make_unique<Gameboy>(rom_data, cliOptions.options);
gameboy->run(&is_closed, &draw);
gameboy->run(&is_closed, &draw, &get_serial_data);
}
4 changes: 3 additions & 1 deletion src/gameboy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ void Gameboy::debug_toggle_window() {

void Gameboy::run(
const should_close_callback_t& _should_close_callback,
const vblank_callback_t& _vblank_callback
const vblank_callback_t& _vblank_callback,
const get_serial_data_callback_t& _get_serial_data_callback
) {
should_close_callback = _should_close_callback;

video.register_vblank_callback(_vblank_callback);
serial.register_get_data_callback(_get_serial_data_callback);

while (!should_close_callback()) {
tick();
Expand Down
6 changes: 5 additions & 1 deletion src/gameboy.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

#include <memory>
#include <functional>
#include <optional>

using should_close_callback_t = std::function<bool()>;
using get_serial_data_callback_t = std::function<u8()>;

class Gameboy {
public:
Expand All @@ -21,7 +23,8 @@ class Gameboy {

void run(
const should_close_callback_t& _should_close_callback,
const vblank_callback_t& _vblank_callback
const vblank_callback_t& _vblank_callback,
const get_serial_data_callback_t& _get_serial_data_callback
);

void button_pressed(GbButton button);
Expand Down Expand Up @@ -57,4 +60,5 @@ class Gameboy {
uint elapsed_cycles = 0;

should_close_callback_t should_close_callback;
get_serial_data_callback_t get_serial_data_callback;
};
8 changes: 7 additions & 1 deletion src/serial.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@

#include <cstdio>

auto Serial::read() const -> u8 { return data; }
void Serial::register_get_data_callback(const get_serial_data_callback_t& _serial_data_callback) {
get_serial_data_callback = _serial_data_callback;
}

auto Serial::read() const -> u8 {
return get_serial_data_callback();
}

void Serial::write(const u8 byte) {
data = byte;
Expand Down
13 changes: 11 additions & 2 deletions src/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
#include "definitions.h"
#include "options.h"

#include <functional>

using get_serial_data_callback_t = std::function<u8()>;

class Serial {
public:
Serial(Options& inOptions) : options(inOptions) {}
Serial(
Options& inOptions
) : options(inOptions) {}

void register_get_data_callback(const get_serial_data_callback_t& _serial_data_callback);

auto read() const -> u8;
void write(u8 byte);
void write_control(u8 byte) const;

private:
Options& options;

u8 data;

get_serial_data_callback_t get_serial_data_callback;
};

0 comments on commit 0cdeb99

Please sign in to comment.