Adding functional controls.
This commit is contained in:
parent
52eb3e4266
commit
9a72365994
@ -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
|
||||
|
@ -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.
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
50
include/msgba/packet/key_down.h
Normal file
50
include/msgba/packet/key_down.h
Normal 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
|
@ -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',
|
||||
]
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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
64
src/packet/key_down.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user