Adding the send frame handling.

This commit is contained in:
Sergiotarxz 2023-03-13 00:06:19 +01:00
parent 0aaf6079b0
commit 91e7ff6d66
11 changed files with 209 additions and 12 deletions

View File

@ -14,6 +14,7 @@ struct msClientConnectionData {
size_t numberOfThread;
int clientFd;
struct msCoreController *coreController;
pthread_mutex_t *mutexSendPacket;
};
/**

View File

@ -30,4 +30,6 @@ void
msCoreControllerThreadStart (struct msCoreController *const core_controller);
void
msCoreControllerSetFrameCallback(struct msCoreController *const self, void(*callback)(struct mCoreThread *));
void
msCoreControllerSetStartCallback(struct msCoreController *const self, void(*callback)(struct mCoreThread *));
#endif

View File

@ -23,7 +23,7 @@ struct msPacket {
//! The size of the data contained in the packet.
size_t size;
//! The data as a byte array. (Not null terminated.)
char *raw_data;
unsigned char *raw_data;
};
/**
@ -32,6 +32,18 @@ struct msPacket {
bool
msPacketHandle(struct msPacket *packet, int client_fd, struct msClientConnectionData *const data);
/**
* Creates a new packet object.
*/
struct msPacket *
msPacketNew(const size_t id, const size_t size, unsigned char *raw_data);
/**
* Sends the packet to the client.
*/
bool
msPacketSend(const struct msPacket *const packet, struct msClientConnectionData *const data);
/**
* When done with a packet it must be destroyed using this method.
*/

View File

@ -0,0 +1,43 @@
#ifndef MS_PACKET_SEND_HELLO
#define MS_PACKET_SEND_HELLO
#include <msgba/core_controller.h>
#include <stddef.h>
struct msPacket;
/**
* Structure representing a video frame packet.
* The combination of these packets allow the video to be seen in the client.
*/
struct msPacketSendFrame {
//! The width
unsigned int stride;
//! The full size of the buffer.
size_t outputBufferSize;
//! The rgbx buffer.
color_t *outputBuffer;
};
/**
* Ends the life in memory of the send_frame packet.
* @param send_frame A reference to a pointer to a send_frame packet.
*/
void
msPacketSendFrameDestroy(struct msPacketSendFrame **send_frame);
/**
* Creates a new send_frame packet.
* @param stride The witdh
* @param outputBufferSize The size of the outputBuffer
* @param outputBuffer The rgbx array.
*/
struct msPacketSendFrame *
msPacketSendFrameNew(unsigned int stride, size_t outputBufferSize, color_t *const outputBuffer);
/**
* Converts the struct to a byte array with size len.
* @param send_frame The object
* @param len The returned byte array size.
*/
unsigned char *
msPacketSendFrameSerialize(struct msPacketSendFrame *const send_frame, size_t *len);
#endif

View File

@ -9,6 +9,7 @@ sources = [
'src/multiplayer_controller.c',
'src/packet.c',
'src/packet/hello.c',
'src/packet/send_frame.c',
'src/client_connection_data.c',
]

View File

@ -1,3 +1,5 @@
#include <pthread.h>
#include <msgba/core_controller.h>
#include <msgba/client_connection_data.h>
struct msClientConnectionData *
@ -6,6 +8,8 @@ msClientConnectionDataNew(size_t numberOfThread, int clientFd) {
data->numberOfThread = numberOfThread;
data->clientFd = clientFd;
data->coreController = NULL;
data->mutexSendPacket = malloc(sizeof *data->mutexSendPacket);
pthread_mutex_init(data->mutexSendPacket, NULL);
return data;
}
@ -14,6 +18,8 @@ msClientConnectionDataDestroy(struct msClientConnectionData **data) {
if ((*data)->coreController) {
msCoreControllerDestroy(&(*data)->coreController);
}
free((*data)->mutexSendPacket);
(*data)->mutexSendPacket = NULL;
free(*data);
*data = NULL;
}

View File

@ -38,7 +38,7 @@ msCoreControllerLoadGame (const unsigned char *rom, size_t rom_len,
unsigned int width;
unsigned int height;
mCoreInitConfig(core, NULL);
mCoreConfigSetIntValue(&core->config, "logLevel", mLOG_FATAL & mLOG_ERROR & mLOG_WARN);
mCoreConfigSetIntValue(&core->config, "logLevel", mLOG_FATAL);
core->desiredVideoDimensions(core, &width, &height);
color_t *outputBuffer = malloc((sizeof *outputBuffer) * width * height);
@ -58,6 +58,10 @@ void
msCoreControllerSetFrameCallback(struct msCoreController *const self, void(*callback)(struct mCoreThread *)) {
self->threadContext.frameCallback = callback;
}
void
msCoreControllerSetStartCallback(struct msCoreController *const self, void(*callback)(struct mCoreThread *)) {
self->threadContext.startCallback = callback;
}
void
msCoreControllerThreadStart (struct msCoreController *const core_controller) {

View File

@ -1,3 +1,4 @@
#include <pthread.h>
#include <endian.h>
#include <msgba/packet.h>
@ -5,6 +6,7 @@
#define PRINT_DEBUG(NAME, CLIENT_FD) \
printf ("Received packet %s from client fd %d\n", #NAME, CLIENT_FD);
bool
msPacketHandle(struct msPacket *packet, int client_fd,
struct msClientConnectionData *const data) {
@ -18,15 +20,49 @@ msPacketHandle(struct msPacket *packet, int client_fd,
return result;
}
void
msPacketSend(const struct msPacket *const packet, int fd) {
write(fd, (const void *)packet->id, sizeof packet->id);
write(fd, (const void *)packet->size, sizeof packet->size);
write(fd, (const void *)packet->raw_data, sizeof *packet->raw_data * packet->size);
static bool
msPacketWrite(int fd, const void *data, size_t len) {
bool result = false;
ssize_t written_bytes = 0;
const unsigned char *bytes = (const unsigned char *)data;
while (written_bytes < len) {
ssize_t wrote_in_this_write = write(fd, (const void *)&bytes[written_bytes], (sizeof *bytes * len) - written_bytes);
if (wrote_in_this_write == -1) {
goto return_ms_packet_write;
}
written_bytes += wrote_in_this_write;
}
result = true;
return_ms_packet_write:
return result;
}
bool
msPacketSend(const struct msPacket *const packet, struct msClientConnectionData *const data) {
pthread_mutex_lock(data->mutexSendPacket);
int fd = data->clientFd;
size_t id = packet->id;
size_t size = packet->size;
bool result = false;
id = htobe64(id);
size = htobe64(size);
if(!msPacketWrite(fd, (const void *)&id, sizeof packet->id)) {
goto return_ms_packet_send;
}
if (!msPacketWrite(fd, (const void *)&size, sizeof packet->size)) {
goto return_ms_packet_send;
}
if (!msPacketWrite(fd, (const void *)packet->raw_data, sizeof *packet->raw_data * packet->size)){
goto return_ms_packet_send;
}
result = true;
return_ms_packet_send:
pthread_mutex_unlock(data->mutexSendPacket);
return result;
}
struct msPacket *
msPacketNew(const size_t id, const size_t size, char *raw_data) {
msPacketNew(const size_t id, const size_t size, unsigned char *raw_data) {
struct msPacket *packet = malloc(sizeof *packet);
packet->id = id;
packet->size = size;
@ -50,7 +86,7 @@ msPacketRead(int client_fd) {
size_t id = 0;
size_t size = 0;
ssize_t result;
char *raw_data = NULL;
unsigned char *raw_data = NULL;
result = read(client_fd, &id, sizeof id);
if (result < sizeof id) {

View File

@ -1,6 +1,10 @@
#include <sys/signal.h>
#include <msgba/packet/send_frame.h>
#include <msgba/packet.h>
#include <msgba/packet/hello.h>
#include <msgba/core_controller.h>
void
msPacketHelloDestroy(struct msPacketHello **hello) {
if ((*hello)->rom) {
@ -15,15 +19,36 @@ msPacketHelloDestroy(struct msPacketHello **hello) {
*hello = NULL;
}
void
msThreadCallbackStart(struct mCoreThread *threadContext) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, NULL);
}
void
msThreadCallbackSetFrame(struct mCoreThread *threadContext) {
struct msClientConnectionData *data = (struct msClientConnectionData *)threadContext->userData;
unsigned int stride = data->coreController->stride;
int client_fd = data->clientFd;
color_t *outputBuffer = data->coreController->outputBuffer;
unsigned width, height;
unsigned char *raw_data;
size_t raw_data_len = 0;
struct msPacketSendFrame *send_frame;
struct msPacket *packet;
data->coreController->threadContext.core->desiredVideoDimensions(data->coreController->threadContext.core, &width, &height);
send_frame = msPacketSendFrameNew(stride, width * height, outputBuffer);
raw_data = msPacketSendFrameSerialize(send_frame, &raw_data_len);
packet = msPacketNew(PACKET_SEND_FRAME, raw_data_len, raw_data);
msPacketSend(packet, data);
msPacketSendFrameDestroy(&send_frame);
msPacketDestroy(&packet);
}
bool
@ -37,6 +62,7 @@ msPacketHelloHandle(const struct msPacket *packet, struct msPacketHello *hello,
printf("Loading game and save for client_fd %d\n", data->clientFd);
data->coreController = msCoreControllerLoadGame(hello->rom, hello->size_rom, hello->savestate, hello->size_savestate, data);
msCoreControllerSetFrameCallback(data->coreController, &msThreadCallbackSetFrame);
msCoreControllerSetStartCallback(data->coreController, &msThreadCallbackStart);
msCoreControllerThreadStart(data->coreController);
result = true;
return_ms_packet_hello_handle:

52
src/packet/send_frame.c Normal file
View File

@ -0,0 +1,52 @@
#include <endian.h>
#include <stdlib.h>
#include <msgba/packet/send_frame.h>
void
msPacketSendFrameDestroy(struct msPacketSendFrame **send_frame) {
free ((*send_frame)->outputBuffer);
(*send_frame)->outputBuffer = NULL;
free (*send_frame);
*send_frame = NULL;
}
struct msPacketSendFrame *
msPacketSendFrameNew(unsigned int stride, size_t outputBufferSize, color_t *const outputBuffer) {
struct msPacketSendFrame *self = malloc(sizeof *self);
color_t *outputBufferClone = malloc (sizeof *outputBufferClone * outputBufferSize);
for (size_t i = 0; i < outputBufferSize; i++) {
outputBufferClone[i] = outputBuffer[i];
}
self->outputBufferSize = outputBufferSize;
self->stride = stride;
self->outputBuffer = outputBufferClone;
return self;
}
unsigned char *
msPacketSendFrameSerialize(struct msPacketSendFrame *const self, size_t *len) {
unsigned char *bytes;
unsigned int stride = self->stride;
size_t outputBufferSizeBytes = self->outputBufferSize * sizeof *self->outputBuffer;
stride = htobe32(stride);
*len = (sizeof self->stride) + (sizeof self->outputBufferSize) + (outputBufferSizeBytes);
outputBufferSizeBytes = htobe64(outputBufferSizeBytes);
bytes = malloc(*len);
#define GOTO_END_SERIALIZE_FAIL() \
free(bytes); \
bytes = NULL;
goto return_ms_packet_send_frame_serialize;
FILE *fp = fmemopen(bytes, sizeof *bytes * *len, "w");
if (fwrite(&self->stride, sizeof self->stride, 1, fp) == -1) {
GOTO_END_SERIALIZE_FAIL();
}
if (fwrite(&outputBufferSizeBytes, sizeof outputBufferSizeBytes, 1, fp) == -1) {
GOTO_END_SERIALIZE_FAIL();
}
if (fwrite(self->outputBuffer, sizeof *self->outputBuffer, self->outputBufferSize, fp) == -1) {
GOTO_END_SERIALIZE_FAIL();
}
fclose(fp);
return_ms_packet_send_frame_serialize:
return bytes;
}

View File

@ -29,7 +29,21 @@ open my $fh_packet, '>', \$packet;
write_packet($fh_packet, $PACKET_HELLO, \$packet_hello);
close $fh_packet;
print $fh $packet;
sleep 1 while 1;
while (retrieve_packet($fh)) {
}
sub retrieve_packet {
my $fh = shift;
(read $fh, my $id, 8) or return 0;
$id = unpack('Q>', $id);
(read $fh, my $size, 8) or return 0;
$size = unpack('Q>', $size);
(read $fh, my $raw_data, $size) or return 0;
say $id;
say $size;
return 1;
}
sub write_packet {
my $fh = shift;