I've made some updates. It contains linked lists now, and you can add/remove keys you want to search for. Working on to do something similar for mouse events.
There is an issue with this part of the code:
Code:
if (event.type == SDL_MOUSEBUTTONDOWN)
{
if (event.button.button = SDL_BUTTON_LEFT)
{
printf("Left Mouse Pressed\n");
buttonState[SDL_BUTTON_LEFT] = PRESSED;
{
}
I seem to be able to register both left and right clicks as left clicks.
Also I need to have a good way to check if a key/button was pressed during the previous game-loop cycle, but im not sure exactly how to do it.
Here is some of the code I have so far:
Code:
/** File: client.c
**/
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include "event_handler.h"
#include "renderer.h"
int main()
{
initSDL();
renderer();
addKeyToEventHandler(SDL_SCANCODE_W);
addKeyToEventHandler(SDL_SCANCODE_A);
addKeyToEventHandler(SDL_SCANCODE_S);
addKeyToEventHandler(SDL_SCANCODE_D);
addKeyToEventHandler(SDL_SCANCODE_ESCAPE);
addKeyToEventHandler(SDL_SCANCODE_RETURN);
addKeyToEventHandler(SDL_SCANCODE_RETURN2);
addKeyToEventHandler(SDL_SCANCODE_UP);
addKeyToEventHandler(SDL_SCANCODE_LEFT);
addKeyToEventHandler(SDL_SCANCODE_DOWN);
addKeyToEventHandler(SDL_SCANCODE_RIGHT);
SDL_Thread *t_event_handler = SDL_CreateThread(eventHandler, "eventHandler", (void *)NULL);
//removeKeyFromEventHandler(SDL_SCANCODE_ESCAPE);
int count = 0;
while (1)
{
int x, y;
SDL_GetMouseState(&x, &y);
if (isKeyBeingPressed(SDL_SCANCODE_W))
{
unsigned int i = SDL_GetTicks();
i /= 1000;
printf("%d: W is being pressed!\n", i);
if (i >= 3 && i < 4)
count++;
if (i == 5)
break;
}
if (isButtonBeingPressed(SDL_BUTTON_LEFT))
printf("LEFT BUTTON IS BEING PRESSED\n");
SDL_Delay(16);
}
printf("Count = %d", count);
}
int initSDL()
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf( "VIDEO could not initialize! SDL_Error: %s\n", SDL_GetError());
exit(1);
}
}
Code:
/** File: event_handler.c
**/
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include "event_handler.h"
#include "event_handler_list.h"
#define RELEASE_DELAY 50
#define MAX_FOUND_KEYS 40
#define PRESSED true
#define RELEASED false
#define MAX_KEYS 322
#define MAX_Buttons 5
int mouse_x;
int mouse_y;
bool buttonState[MAX_Buttons];
bool keyState[MAX_KEYS];
unsigned int keyTimeStamp[MAX_KEYS];
SDL_Thread *eventHandlerThread = NULL;
int getMouseX()
{
return mouse_x;
}
int getMouseY()
{
return mouse_y;
}
void addKeyToEventHandler(int key)
{
akAdd(key);
printf("Key added: %d\n", key);
}
void removeKeyFromEventHandler(int key)
{
akRemove(key);
printf("Key added: %d\n", key);
}
bool isKeyBeingPressed(int key)
{
return keyState[key] == PRESSED;
}
bool isButtonBeingPressed(int button)
{
return buttonState[button] == PRESSED;
}
void eventHandler()
{
const Uint8 *keys = SDL_GetKeyboardState(NULL);
unsigned int timeStamp;
for (int i = 0; i < MAX_KEYS; i++)
{
keyState[i] = RELEASED;
keyTimeStamp[i] = 0;
}
while (true)
{
timeStamp = SDL_GetTicks();
SDL_PumpEvents();
SDL_Event event;
while(SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
SDL_Quit(); // need to replaced with a client signa.
return;
}
if (event.type == SDL_MOUSEBUTTONDOWN)
{
if (event.button.button = SDL_BUTTON_LEFT)
{
printf("Left Mouse Pressed\n");
buttonState[SDL_BUTTON_LEFT] = PRESSED;
}
}
if (event.type == SDL_MOUSEBUTTONUP)
{
if (event.button.button = SDL_BUTTON_LEFT)
{
printf("Left Mouse Released\n");
buttonState[SDL_BUTTON_LEFT] = RELEASED;
}
}
}
SDL_GetMouseState(&mouse_x, &mouse_y); // Get current mouse position
checkForPressedKeys(keys); // Check for pressed Keys
checkForReleasedKeys(); // Check for released Keys
SDL_Delay(10); // Slows down the cycle
}
}
void checkForPressedKeys(Uint8 *keys)
{
if (!akIsEmpty())
{
struct node_ak *ptr = akGetHead();
unsigned int timeStamp = SDL_GetTicks();
int i = 0, foundKeycode[40];
while(ptr != NULL)
{
if (keys[ptr->keycode] == PRESSED)
{
keyTimeStamp[ptr->keycode] = timeStamp;
if (keyState[ptr->keycode] == RELEASED) {
keyState[ptr->keycode] = PRESSED;
printf("%d was pressed\n", ptr->keycode);
pkAdd(ptr->keycode);
}
}
ptr = ptr->next;
}
}
}
void checkForReleasedKeys()
{
if (!pkIsEmpty())
{
struct node_pk *ptr = pkGetHead();
unsigned int timeStamp = SDL_GetTicks() - RELEASE_DELAY;
int i = 0, foundKeycode[MAX_FOUND_KEYS];
while(ptr != NULL)
{
if (timeStamp > keyTimeStamp[ptr->keycode])
{
foundKeycode[i] = ptr->keycode;
i++;
}
ptr = ptr->next;
}
for (int j = 0; j < i; j++)
{
printf("%d was released\n", foundKeycode[j]);
keyState[foundKeycode[j]] = RELEASED;
pkRemove(foundKeycode[j]);
}
}
}
Code:
/** File: event_handler_list.c
**/
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include "event_handler_list.h"
//====================================================
// Double-linked list: Available Keys (PK)
//====================================================
struct node_ak *head_ak = NULL; //this link always point to first Link
struct node_ak *tail_ak = NULL; //this link always point to last Link
struct node_ak* akGetHead()
{
return head_ak;
}
struct node_ak* akGetTail()
{
return tail_ak;
}
bool akIsEmpty()
{
return head_ak == NULL;
}
int akGetNumber()
{
int length = 0;
struct node_ak *current_ak;
for(current_ak = head_ak; current_ak != NULL; current_ak = current_ak->next){
length++;
}
return length;
}
void akAdd(int key)
{
//create a link
struct node_ak *link = (struct node_ak*) malloc(sizeof(struct node_ak));
link->keycode = key;
if(akIsEmpty()) {
//make it the last link
tail_ak = link;
} else {
//update first prev link
head_ak->prev = link;
}
//point it to old first link
link->next = head_ak;
//point first to new first link
head_ak = link;
}
struct node_ak* akRemove(int key)
{
//start from the first link
struct node_ak* current_ak = head_ak;
struct node_ak* previous = NULL;
//if list is empty
if(head_ak == NULL) {
return NULL;
}
//navigate through list
while(current_ak->keycode != key) {
//if it is last node
if(current_ak->next == NULL) {
return NULL;
} else {
//store reference to current link
previous = current_ak;
//move to next link
current_ak = current_ak->next;
}
}
//found a match, update the link
if(current_ak == head_ak) {
//change first to point to next link
head_ak = head_ak->next;
} else {
//bypass the current link
current_ak->prev->next = current_ak->next;
}
if(current_ak == tail_ak) {
//change last to point to prev link
tail_ak = current_ak->prev;
} else {
current_ak->next->prev = current_ak->prev;
}
return current_ak;
}
//====================================================
// Double-linked list: Pressed Keys (PK)
//====================================================
struct node_pk *head_pk = NULL; //this link always point to first Link
struct node_pk *tail_pk = NULL; // //this link always point to last Link
struct node_pk* pkGetHead()
{
return head_pk;
}
struct node_pk* pkGetTail()
{
return tail_pk;
}
bool pkIsEmpty()
{
return head_pk == NULL;
}
int pkGetNumber()
{
int length = 0;
struct node_pk *current_pk;
for(current_pk = head_pk; current_pk != NULL; current_pk = current_pk->next){
length++;
}
return length;
}
void pkAdd(int key)
{
//create a link
struct node_pk *link = (struct node_pk*) malloc(sizeof(struct node_pk));
link->keycode = key;
if(pkIsEmpty()) {
//make it the last link
tail_pk = link;
} else {
//update first prev link
head_pk->prev = link;
}
//point it to old first link
link->next = head_pk;
//point first to new first link
head_pk = link;
}
struct node_pk* pkRemove(int key)
{
//start from the first link
struct node_pk* current_pk = head_pk;
struct node_pk* previous = NULL;
//if list is empty
if(head_pk == NULL) {
return NULL;
}
//navigate through list
while(current_pk->keycode != key) {
//if it is last node
if(current_pk->next == NULL) {
return NULL;
} else {
//store reference to current link
previous = current_pk;
//move to next link
current_pk = current_pk->next;
}
}
//found a match, update the link
if(current_pk == head_pk) {
//change first to point to next link
head_pk = head_pk->next;
} else {
//bypass the current link
current_pk->prev->next = current_pk->next;
}
if(current_pk == tail_pk) {
//change last to point to prev link
tail_pk = current_pk->prev;
} else {
current_pk->next->prev = current_pk->prev;
}
return current_pk;
}