diff --git a/include/msgba/client_connection_data.h b/include/msgba/client_connection_data.h index 7bcbbb5..f055ca6 100644 --- a/include/msgba/client_connection_data.h +++ b/include/msgba/client_connection_data.h @@ -4,6 +4,7 @@ #include #include #include +#include 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 diff --git a/include/msgba/packet.h b/include/msgba/packet.h index d0301cf..e5f26f2 100644 --- a/include/msgba/packet.h +++ b/include/msgba/packet.h @@ -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. }; diff --git a/include/msgba/packet/hello.h b/include/msgba/packet/hello.h index 01bfa8a..e43ecd2 100644 --- a/include/msgba/packet/hello.h +++ b/include/msgba/packet/hello.h @@ -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); diff --git a/include/msgba/packet/key_down.h b/include/msgba/packet/key_down.h new file mode 100644 index 0000000..afd96a2 --- /dev/null +++ b/include/msgba/packet/key_down.h @@ -0,0 +1,50 @@ +#ifndef MS_PACKET_KEY_DOWN +#define MS_PACKET_KEY_DOWN +#include +#include +#include +#include +#include +#include + +#include + +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 diff --git a/meson.build b/meson.build index 8c3a133..bef275e 100644 --- a/meson.build +++ b/meson.build @@ -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', ] diff --git a/src/client_connection_data.c b/src/client_connection_data.c index 2a1628b..476cd81 100644 --- a/src/client_connection_data.c +++ b/src/client_connection_data.c @@ -3,8 +3,6 @@ #include #include -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; } diff --git a/src/core_controller.c b/src/core_controller.c index 3e193aa..d3d204e 100644 --- a/src/core_controller.c +++ b/src/core_controller.c @@ -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; diff --git a/src/packet.c b/src/packet.c index a20ba1b..7a24bf6 100644 --- a/src/packet.c +++ b/src/packet.c @@ -3,6 +3,7 @@ #include #include +#include #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"); diff --git a/src/packet/hello.c b/src/packet/hello.c index 21a0969..bd69bd5 100644 --- a/src/packet/hello.c +++ b/src/packet/hello.c @@ -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) { diff --git a/src/packet/key_down.c b/src/packet/key_down.c new file mode 100644 index 0000000..c8b9c70 --- /dev/null +++ b/src/packet/key_down.c @@ -0,0 +1,64 @@ +#include +#include + +#include + +#include +#include +#include + +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; +}