Adding functional controls.

This commit is contained in:
Sergiotarxz 2023-03-25 15:21:27 +01:00
parent 52eb3e4266
commit 9a72365994
10 changed files with 193 additions and 30 deletions

View File

@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
struct msCoreController;
@ -11,10 +12,17 @@ struct msCoreController;
* Struct representing everything needed while a connection is established.
*/
struct msClientConnectionData {
//! The number of this thread.
size_t numberOfThread;
//! Where to receive and send packets.
int clientFd;
//! The core controller
struct msCoreController *coreController;
//! Mutex to avoid send multiple packets at once.
pthread_mutex_t *mutexSendPacket;
//! Mutex to avoid to do multiple key operations at once.
pthread_mutex_t *mutexPressKey;
//! The last time we sent a frame.
struct timespec *lastFrameDate;
};
@ -27,8 +35,10 @@ struct msClientConnectionData {
struct msClientConnectionData *
msClientConnectionDataNew(size_t numberOfThread, int clientFd);
/**
* Function to cleanup the session data.
* @param data A pointer to the pointer to msClientConnectionData.
*/
void
msClientConnectionDataDestroy(struct msClientConnectionData **data);
extern pthread_mutex_t mutexClientConnection;
#endif

View File

@ -11,6 +11,7 @@
enum {
PACKET_GET_HELLO, //! Packet id for get hello.
PACKET_SEND_FRAME, //! Packet id for send frame.
PACKET_GET_KEY_DOWN, //! Packet id for pressing a key.
PACKETS_NUMBER //! The number of recognized packets.
};

View File

@ -11,19 +11,45 @@
struct msPacket;
/**
* The first kind of packet that the client should send to the emulator.
*/
struct msPacketHello {
size_t size_rom;
//! The size of the following field.
size_t sizeRom;
//! The ROM containing the game.
unsigned char *rom;
size_t size_savestate;
//! The size of the following field.
size_t sizeSavestate;
//! The savestate from where to resume.
unsigned char *savestate;
};
/**
* Destroys the msPacketHello and deallocates the memory.
* @param hello The pointer to the pointer to hello to null it after this operation.
*/
void
msPacketHelloDestroy(struct msPacketHello **hello);
/**
* Handles msPacketHello.
* @param packet The packet containing this object in its raw_data.
* @param hello This object.
* @param data This session.
* @return The success status.
*/
bool
msPacketHelloHandle(const struct msPacket *packet, struct msPacketHello *hello,
struct msClientConnectionData *const data);
/**
* Retrieves the msPacketHello contained in the packet raw_data.
* @param packet The packet containing msPacketHello, should have PACKET_GET_HELLO as its id.
* @param client_fd The source of this packet.
* @param data This session.
* @return The success status.
*/
bool
msPacketHelloGet(const struct msPacket *packet, int client_fd,
struct msClientConnectionData *const data);

View File

@ -0,0 +1,50 @@
#ifndef MS_PACKET_KEY_DOWN
#define MS_PACKET_KEY_DOWN
#include <stdio.h>
#include <sys/un.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <msgba/client_connection_data.h>
struct msPacket;
/**
* The packet kind received when a key is pressed that should be handled by the emulator.
*/
struct msPacketKeyDown {
//! Determines if the key is pressed or un pressed.
char isPressed;
//! The key pressed.
int key;
};
/**
* Destroys the msPacketKeyDown
* @param keyDown The pointer to the pointer to keyDown to null it after this operation.
*/
void
msPacketKeyDownDestroy(struct msPacketKeyDown **keyDown);
/**
* Handles the msPacketKeyDown
* @param packet The packet containing msPacketKeyDown, should have PACKET_GET_KEY_DOWN as its id.
* @param keyDown This object.
* @param data The session data.
*/
bool
msPacketKeyDownHandle(const struct msPacket *packet, struct msPacketKeyDown *keyDown,
struct msClientConnectionData *const data);
/**
* Retrieves the msPacketKeyDown contained in the packet raw_data.
* @param packet The packet containing msPacketKeyDown, should have PACKET_GET_KEY_DOWN as its id.
* @param client_fd The source of this packet.
* @param data The session data.
*/
bool
msPacketKeyDownGet(const struct msPacket *packet, int client_fd,
struct msClientConnectionData *const data);
#endif

View File

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

View File

@ -3,8 +3,6 @@
#include <msgba/core_controller.h>
#include <msgba/client_connection_data.h>
pthread_mutex_t mutexClientConnection = PTHREAD_MUTEX_INITIALIZER;
struct msClientConnectionData *
msClientConnectionDataNew(size_t numberOfThread, int clientFd) {
struct msClientConnectionData *data = malloc (sizeof *data);
@ -12,8 +10,10 @@ msClientConnectionDataNew(size_t numberOfThread, int clientFd) {
data->clientFd = clientFd;
data->coreController = NULL;
data->mutexSendPacket = malloc(sizeof *data->mutexSendPacket);
data->mutexPressKey = malloc(sizeof *data->mutexPressKey);
data->lastFrameDate = calloc(sizeof *data->lastFrameDate, 1);
pthread_mutex_init(data->mutexSendPacket, NULL);
pthread_mutex_init(data->mutexPressKey, NULL);
return data;
}
@ -22,8 +22,12 @@ msClientConnectionDataDestroy(struct msClientConnectionData **data) {
if ((*data)->coreController) {
msCoreControllerDestroy(&(*data)->coreController);
}
pthread_mutex_destroy((*data)->mutexSendPacket);
pthread_mutex_destroy((*data)->mutexPressKey);
free((*data)->mutexSendPacket);
free((*data)->mutexPressKey);
(*data)->mutexSendPacket = NULL;
(*data)->mutexPressKey = NULL;
free(*data);
*data = NULL;
}

View File

@ -39,16 +39,16 @@ msCoreControllerLoadGame (const unsigned char *rom, size_t rom_len,
core->init(core);
mInputMapInit(&core->inputMap, &GBAInputInfo);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_A, GBA_KEY_A);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_B, GBA_KEY_B);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_L, GBA_KEY_L);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_R, GBA_KEY_R);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_START, GBA_KEY_START);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_SELECT, GBA_KEY_SELECT);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_UP, GBA_KEY_UP);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_DOWN, GBA_KEY_DOWN);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_LEFT, GBA_KEY_LEFT);
mInputBindKey(&core->inputMap, 0, MSGBA_KEY_RIGHT, GBA_KEY_RIGHT);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_A, GBA_KEY_A);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_B, GBA_KEY_B);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_L, GBA_KEY_L);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_R, GBA_KEY_R);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_START, GBA_KEY_START);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_SELECT, GBA_KEY_SELECT);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_UP, GBA_KEY_UP);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_DOWN, GBA_KEY_DOWN);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_LEFT, GBA_KEY_LEFT);
mInputBindKey(&core->inputMap, 80, MSGBA_KEY_RIGHT, GBA_KEY_RIGHT);
unsigned int width;
unsigned int height;

View File

@ -3,6 +3,7 @@
#include <msgba/packet.h>
#include <msgba/packet/hello.h>
#include <msgba/packet/key_down.h>
#define PRINT_DEBUG(NAME, CLIENT_FD) \
printf ("Received packet %s from client fd %d\n", #NAME, CLIENT_FD);
@ -11,11 +12,16 @@ bool
msPacketHandle(struct msPacket *packet, int client_fd,
struct msClientConnectionData *const data) {
bool result = false;
printf("Received packet %lu\n", packet->id);
switch (packet->id) {
case PACKET_GET_HELLO:
PRINT_DEBUG(PACKET_HELLO, client_fd);
result = msPacketHelloGet(packet, client_fd, data);
break;
case PACKET_GET_KEY_DOWN:
PRINT_DEBUG(PACKET_KEY_DOWN, client_fd);
result = msPacketKeyDownGet(packet, client_fd, data);
break;
}
return result;
}
@ -96,6 +102,7 @@ msPacketRead(int client_fd) {
printf("Unable to read id\n");
goto return_read_packet;
}
id = be64toh(id);
result = read(client_fd, &size, sizeof size);
if (result < sizeof size) {
printf("Unable to read packet\n");

View File

@ -96,7 +96,7 @@ msPacketHelloHandle(const struct msPacket *packet, struct msPacketHello *hello,
goto return_ms_packet_hello_handle;
}
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);
data->coreController = msCoreControllerLoadGame(hello->rom, hello->sizeRom, hello->savestate, hello->sizeSavestate, data);
msCoreControllerSetFrameCallback(data->coreController, &msThreadCallbackSetFrame);
msCoreControllerSetStartCallback(data->coreController, &msThreadCallbackStart);
msCoreControllerThreadStart(data->coreController);
@ -118,8 +118,8 @@ msPacketHelloGet(const struct msPacket *packet, int client_fd,
printf("Unable to fmemopen\n");
goto return_get_packet_hello;
}
size_t size_rom = 0;
size_t size_savestate = 0;
size_t sizeRom = 0;
size_t sizeSavestate = 0;
size_t reads[4] = { 0,0,0,0 };
size_t total_read = 0;
size_t to_read_size;
@ -134,18 +134,17 @@ msPacketHelloGet(const struct msPacket *packet, int client_fd,
}
FREAD(&size_rom, sizeof size_rom, 1, fp, 0, return_get_packet_hello);
size_rom = be64toh(size_rom);
rom = malloc(sizeof *rom * size_rom);
FREAD(&sizeRom, sizeof sizeRom, 1, fp, 0, return_get_packet_hello);
sizeRom = be64toh(sizeRom);
rom = malloc(sizeof *rom * sizeRom);
FREAD(rom, sizeof *rom, size_rom, fp, 1, return_get_packet_hello);
FREAD(rom, sizeof *rom, sizeRom, fp, 1, return_get_packet_hello);
FREAD(&size_savestate, sizeof size_savestate, 1, fp, 2, return_get_packet_hello);
size_savestate = be64toh(size_savestate);
savestate = malloc(sizeof *savestate * size_savestate);
FREAD(&sizeSavestate, sizeof sizeSavestate, 1, fp, 2, return_get_packet_hello);
sizeSavestate = be64toh(sizeSavestate);
savestate = malloc(sizeof *savestate * sizeSavestate);
FREAD(savestate, sizeof *savestate, size_savestate, fp, 3, return_get_packet_hello);
fclose(fp);
FREAD(savestate, sizeof *savestate, sizeSavestate, fp, 3, return_get_packet_hello);
for (int i = 0; i<4; i++) {
total_read += reads[i];
@ -155,12 +154,13 @@ msPacketHelloGet(const struct msPacket *packet, int client_fd,
goto return_get_packet_hello;
}
hello = calloc(1, sizeof *hello);
hello->size_rom = size_rom;
hello->sizeRom = sizeRom;
hello->rom = rom;
hello->size_savestate = size_savestate;
hello->sizeSavestate = sizeSavestate;
hello->savestate = savestate;
result = true;
return_get_packet_hello:
fclose(fp);
if (!result) {
fprintf(stderr, "Unable to read the packet hello\n");
if (rom) {

64
src/packet/key_down.c Normal file
View File

@ -0,0 +1,64 @@
#include <pthread.h>
#include <unistd.h>
#include <mgba/core/input.h>
#include <msgba/packet.h>
#include <msgba/core_controller.h>
#include <msgba/packet/key_down.h>
bool
msPacketKeyDownGet(const struct msPacket *packet, int clientFd, struct msClientConnectionData *const data) {
bool result = false;
struct msPacketKeyDown *keyDown = NULL;
int key = 0;
char isPressed = 0;
FILE *fp = fmemopen(packet->raw_data, packet->size, "r");
if (1 != fread(&isPressed, sizeof isPressed, 1, fp)) {
goto return_ms_packet_key_down_get;
}
if (1 != fread(&key, sizeof key, 1, fp)) {
goto return_ms_packet_key_down_get;
}
key = be32toh(key);
keyDown = malloc(sizeof *keyDown);
keyDown->isPressed = isPressed;
keyDown->key = key;
result = true;
return_ms_packet_key_down_get:
fclose(fp);
if (!result) {
return false;
}
return msPacketKeyDownHandle(packet, keyDown, data);
}
bool
msPacketKeyDownHandle(const struct msPacket *packet, struct msPacketKeyDown *keyDown,
struct msClientConnectionData *const data) {
bool result = false;
struct msCoreController *coreController = data->coreController;
if (!coreController || !coreController->threadContext.core) {
goto return_ms_packet_key_down_handle;
}
struct mCore *core = coreController->threadContext.core;
int gbaKey = 1 << mInputMapKey(&core->inputMap, 80, keyDown->key);
printf("Keys received %d %x\n", keyDown->key, gbaKey);
pthread_mutex_lock(data->mutexPressKey);
if (keyDown->isPressed) {
core->addKeys(core, gbaKey);
} else {
core->clearKeys(core, gbaKey);
}
pthread_mutex_unlock(data->mutexPressKey);
result = true;
return_ms_packet_key_down_handle:
msPacketKeyDownDestroy(&keyDown);
return result;
}
void
msPacketKeyDownDestroy(struct msPacketKeyDown **keyDownPtr) {
free(*keyDownPtr);
*keyDownPtr = NULL;
}