How to make a communication protocol for the PC part considering a PC-console game played by two users?

c-language

(Maria-Elisabeta Diaconu) #1

I have to make the communication protocol for the PC part for a pong game that can be played both on console and PC by two players.My problem has to do with the PC side because when i want to move the paddle from the PC with left and right arrows,it won’t work.Can someone tell me what is the problem,please? This is the code:

/* Standard includes. */
#include <stdio.h>
#include <conio.h>
#include <Windows.h>

 /* Kernel includes. */
 #include "FreeRTOS.h"
 #include "task.h"
 #include "timers.h"
 #include "semphr.h"
 #include "queue.h"

/* Priorities at which the tasks are created. */
#define serial_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define input_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define receive_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )

/* Periode for the timer. The times are converted from
milliseconds to ticks using the pdMS_TO_TICKS() macro. */

#define mainTIMER_SEND_FREQUENCY_MS pdMS_TO_TICKS( 2000UL )
#define ESCCHAR 0x1B
#define FLAG 0x1A
#define CRC_POLYNOMIAL 263
#define KEYBORD_INPUT_OP_CODE 1
#define ACK_OP_CODE 2
#define NACK_OP_CODE 3

enum States {
IDLE, DATA, ESC
};
enum States state = IDLE;
static uint16_t seq_number = 0;
//static uint8_t answer[4];
HANDLE hSerial;

/-----------------------------------------------------------/

/*

  • The tasks as described in the comments at the top of this file.
    */
    static void serialTask(void *pvParameters);
    static void inputTask(void *pvParameters);
    static void receiveTask(void *pvParameters);

void open_port();
void prepare_for_sending(uint8_t *to_stuff, uint8_t length, uint8_t
op_code);
uint8_t byte_framing(uint8_t new_message[], uint8_t message[], uint8_t
size);
uint8_t getCRC(uint8_t message[], uint8_t length);
uint8_t format_message(uint8_t to_format_old[], uint8_t length, uint8_t
op_code);
uint8_t check_message(uint8_t message[], uint8_t length);

//uint8_t to_test[] = { 65, 26, 85, 27, 27,27 }; //used for testing only
uint8_t to_send[20];//Final message to send
uint8_t to_send_size;
uint8_t to_crc[5];

uint8_t to_format[20];//Formated message
uint8_t to_format_size;
uint8_t to_format_crc;

QueueHandle_t input_queue;
uint8_t input;

  /*-----------------------------------------------------------*/

 /*** SEE THE COMMENTS AT THE TOP OF THIS FILE ***/

void main_blinky(void)
{
const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;
//open_port();
printf(“In main\r\n”);

open_port();//Open COM Ports

xTaskCreate(serialTask, /* The function that implements the task. /
“Serial”, /
The text name assigned to the
task - for debug only as it is not used by the kernel. /
configMINIMAL_STACK_SIZE, /
The size of the stack to allocate to
the task. /
NULL, /
The parameter passed to the task -
not used in this simple case. /
serial_TASK_PRIORITY,/
The priority assigned to the task. /
NULL); /
The task handle is not required, so
NULL is passed. */

xTaskCreate(inputTask, /* The function that implements the task. /
“Input”, /
The text name assigned to the
task - for debug only as it is not used by the
kernel. /
configMINIMAL_STACK_SIZE, /
The size of the stack to allocate to
the task. /
NULL, /
The parameter passed to the task -
not used in this simple case. /
input_TASK_PRIORITY,/
The priority assigned to the task. /
NULL); /
The task handle is not required, so
NULL is passed. */

xTaskCreate(receiveTask, /* The function that implements the
task. /
“Receive”, /
The text name assigned to the
task - for debug only as it is not used by the kernel. /
configMINIMAL_STACK_SIZE, /
The size of the stack to allocate to
the task. /
NULL, /
The parameter passed to the task -
not used in this simple case. /
serial_TASK_PRIORITY,/
The priority assigned to the task. */
NULL);

input_queue = xQueueCreate(10, sizeof(int));

vTaskStartScheduler();
for (;; );

}
/-----------------------------------------------------------/
void open_port()
{

DCB dcbSerialParams = { 0 };
COMMTIMEOUTS timeouts = { 0 };

fprintf(stderr, “Opening serial port…”);

// In “Device Manager” find “Ports (COM & LPT)” and see which COM port the
game controller is using (here COM4)
hSerial = CreateFile(
“COM4”, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
fprintf(stderr, “Here Error\n”);
return;
}
else fprintf(stderr, “OK\n”);

// Set device parameters (115200 baud, 1 start bit,
// 1 stop bit, no parity)
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (GetCommState(hSerial, &dcbSerialParams) == 0)
{
fprintf(stderr, “Error getting device state\n”);
CloseHandle(hSerial);
return;
}

dcbSerialParams.BaudRate = CBR_115200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (SetCommState(hSerial, &dcbSerialParams) == 0)
{
fprintf(stderr, “Error setting device parameters\n”);
CloseHandle(hSerial);
return;
}

// Set COM port timeout settings
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hSerial, &timeouts) == 0)
{
fprintf(stderr, “Error setting timeouts\n”);
CloseHandle(hSerial);
return;
}
}

static void inputTask(void *pvParameters)
{
uint8_t *to_insert;
uint8_t value;

for (;:wink:
{
input = (uint8_t)getch();
value = input;
printf(" /n The value is: %d", value);

if (input == 72 || input == 75 || input == 77)
{

    to_insert = &input;
    prepare_for_sending(to_insert, 1, KEYBORD_INPUT_OP_CODE);
    to_insert = 0;
    //prepare_for_sending(to_test, 6);
    //xQueueSend(input_queue, (void*)&to_insert, portMAX_DELAY);
}

/*
if (input == 75)
{
to_send[0] = FLAG;
printf(" /n The FLAG value is: %d", to_send[0]);
to_send[1] = seq_number;
printf(" /n The seq number value is: %d", value);
to_crc[0] = seq_number;
printf(" /n The value is: %d", value);
to_send[2] = input;
printf(" /n The value is: %d", value);
to_crc[1] = input;
printf(" /n The value is: %d", value);
to_send[3] = getCRC(to_crc, 2);
printf(" /n The value is: %d", value);
to_send[4] = FLAG;
printf(" /n The value is: %d", value);
to_send_size = 5;

}
 if (input == 77)
{
    to_send[0] = FLAG;
    to_send[1] = seq_number;
    to_crc[0] = seq_number;
    to_send[2] = input;
    to_crc[1] = input;
    to_send[3] = getCRC(to_crc, 2);
    to_send[4] = FLAG;
    to_send_size = 5;

}
*/
vTaskDelay(300);

}
}

void prepare_for_sending(uint8_t *to_stuff, uint8_t length, uint8_t op_code)
{
to_format_size = format_message(to_stuff, length, op_code);
to_format_crc = getCRC(to_format, to_format_size);
to_send_size = byte_framing(to_send, to_format, to_format_size);
for (int i = 0; i < to_send_size; i++)
{
printf("\n %d \n", to_send[i]);
}
}

uint8_t format_message(uint8_t to_format_old[], uint8_t length, uint8_t
op_code)
{
to_format[0] = op_code;
to_format[1] = seq_number;
for (int i = 2; i < length + 2; i++)
{
to_format[i] = to_format_old[i - 2];
}
return length + 2;
}

uint8_t byte_framing(uint8_t new_message[], uint8_t message[], uint8_t
size)
{
uint8_t new_size = 1;

new_message[0] = FLAG;
for (int i = 0; i < size; i++)
{
if (message[i] == ESCCHAR || message[i] == FLAG)
{
new_message[new_size] = ESCCHAR;
new_size++;
new_message[new_size] = message[i];
new_size++;
}
else
{
new_message[new_size] = message[i];
new_size++;
}
}
new_message[new_size] = to_format_crc;
new_size++;
new_message[new_size] = FLAG;
new_size++;
return new_size;
}

uint8_t getCRC(uint8_t message[], uint8_t length)
{
uint8_t crc = 0;

for (int i = 0; i < length; i++)
{
crc ^= message[i];
for (int j = 0; j < 8; j++)
{
if (crc & 1)
crc ^= CRC_POLYNOMIAL;
crc >>= 1;
}
}
return crc;
}

static void serialTask(void *pvParameters)
{
(void)pvParameters;

uint8_t bytes_to_receive[6];

for (;; )
{

// Indicate read error(nothing read)
bytes_to_receive[0] = 'E';
bytes_to_receive[1] = 'R';
bytes_to_receive[2] = 'R';
bytes_to_receive[3] = 'O';
bytes_to_receive[4] = 'R';
bytes_to_receive[5] = '\0';

//to_send[4] = 5;
// Send specified text:  bytes_to_send
DWORD bytes_written, total_bytes_written = 0;
fprintf(stderr, "Sending bytes...");
if (to_send[0] == FLAG)
{
    if (!WriteFile(hSerial, to_send, to_send_size, &bytes_written, 
 NULL))
    {
        fprintf(stderr, "fdsfdsf Error\n");
        CloseHandle(hSerial);
        fprintf(stderr, "%d bytes written\n", bytes_written);

        for (int i = 0; i < to_send_size; i++)
        {
            printf("It will send: %d \n", to_send[i]);
        }
        //return 1;
    }
}
vTaskDelay(400);

}

// Close serial port
fprintf(stderr, “Closing serial port…”);
if (CloseHandle(hSerial) == 0)
{
fprintf(stderr, “Error\n”);
return 1;
}
}

static void receiveTask(void *pvParameters)
{
uint8_t i = 0;
uint8_t *byte_to_receive = &i;

uint8_t is_empty = 0;
uint8_t unpacked_message[5];
uint8_t index = 0;
uint8_t check = 1;

uint8_t bytes_to_receive[10];

/* Prevent the compiler warning about the unused parameter. */
(void)pvParameters;
for (;; )
{

//Read text 
DWORD bytes_read, total_bytes_read = 0;

ReadFile(hSerial, byte_to_receive, 1, &bytes_read, total_bytes_read);
fprintf(stderr, "%d bytes read\n", bytes_read);

fprintf(stderr, "Text read:  %d\n", *byte_to_receive);

fprintf(stderr, "End\n");

switch (state) {
case IDLE:

    is_empty = 0;
    if (*byte_to_receive == FLAG)
        state = DATA;
    break;

case DATA:

    if (*byte_to_receive == ESCCHAR)
    {
        state = ESC;

    }
    else if (*byte_to_receive == FLAG && is_empty != 0)
    {
        state = IDLE;
        check = check_message(unpacked_message, index);
        if (check == 0)
        {
            DWORD bytes_written, total_bytes_written = 0;
            fprintf(stderr, "Sending bytes...");

            if (!WriteFile(hSerial, to_send, to_send_size, 

&bytes_written, NULL))
{
fprintf(stderr, “Error\n”);
CloseHandle(hSerial);
return 1;
}
}
for (int i = 0; i < 20; i++)
{
to_send[0] = 0;
}
check = 1;
index = 0;
}
else if (*byte_to_receive == FLAG && is_empty == 0)
{
state = IDLE;
}
else
{
unpacked_message[index] = *byte_to_receive;
is_empty = 1;
index++;
}
break;

case ESC:
    unpacked_message[index] = *byte_to_receive;
    is_empty = 1;
    index++;
    state = DATA;
    break;


}
vTaskDelay(100);

}

// Close serial port
fprintf(stderr, “Closing serial port…”);
if (CloseHandle(hSerial) == 0)
{
fprintf(stderr, “Error\n”);
return 1;
}
}

uint8_t check_message(uint8_t message[], uint8_t length)
{
if (message[0] == ACK_OP_CODE)
{
seq_number++;
fprintf(stderr, “ALOOOOOOOOOOOOOO”);
return 1;
}
if (message[0] == NACK_OP_CODE)
{
fprintf(stderr, “NACK NAK NAK”);
return 0;
}
}