Skip to content

Commit

Permalink
Added input management for mouse and keyboard, basic camera controls,…
Browse files Browse the repository at this point in the history
… update texture function for components, and a cleanup function.
  • Loading branch information
gorbit99 committed Oct 15, 2019
1 parent 5e56ec8 commit 60a2df5
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 40 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
**/build
**/.vscode
**/.exe
**/.exe
**/cmake-build-debug
**/log.txt
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ find_package(SDL2 REQUIRED)
find_package(SDL2_TTF REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIR})

add_executable(${PROJECT_NAME} main.c Graphics.c Graphics.h debugmalloc.h debugmalloc-impl.h Component.c Component.h Utility.c Utility.h Window.c Window.h)
add_executable(${PROJECT_NAME} main.c Graphics.c Graphics.h debugmalloc.h debugmalloc-impl.h Component.c Component.h Utility.c Utility.h Window.c Window.h Input.c Input.h)

target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2_TTF_LIBRARIES})

Expand Down
9 changes: 8 additions & 1 deletion Component.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ SDL_Surface *component_load_graphic(const char *path, float size, float thicknes
float wf, hf;
fscanf(f, "%f %f", &wf, &hf);

int w = (int)ceil(wf * size), h = (int)ceil(hf * size);
int w = (int)ceilf(wf * size), h = (int)ceilf(hf * size);

SDL_Surface *component = get_rgba_surface(w, h);

Expand Down Expand Up @@ -64,6 +64,8 @@ SDL_Surface *component_load_graphic(const char *path, float size, float thicknes
}
}

fclose(f);

return component;
}

Expand All @@ -81,6 +83,11 @@ ComponentData component_create_data(float x, float y, SDL_Texture *texture, size
return dat;
}

void component_update_texture(ComponentData *dat, SDL_Texture *texture) {
SDL_QueryTexture(texture, NULL, NULL, &(dat->w), &(dat->h));
dat->texture = texture;
}

void component_free_data(ComponentData *dat) {
free(dat->out);
}
Expand Down
13 changes: 8 additions & 5 deletions Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
#include "Graphics.h"

typedef struct ComponentData {
float x, y;
int w, h;
SDL_Texture *texture;
size_t outCount;
bool *out;
float x, y;
int w, h;
SDL_Texture *texture;
size_t outCount;
bool *out;
} ComponentData;

SDL_Surface *component_load_graphic(const char *path, float size, float thickness, TTF_Font *font);

ComponentData component_create_data(float x, float y, SDL_Texture *texture, size_t outCount);

void component_update_texture(ComponentData *dat, SDL_Texture *texture);

void component_free_data(ComponentData *dat);

void component_render(ComponentData *dat, SDL_Renderer *renderer, Point camPos);
Expand Down
114 changes: 111 additions & 3 deletions Input.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,114 @@
#include "Input.h"
#include "debugmalloc.h"

void input_handle_event(SDL_Event &e) {

}
ButtonState buttons[SDL_NUM_SCANCODES];
ButtonState mouseButtons[5];
uint8_t mouseClicks[5];

int mouseDeltaX = 0, mouseDeltaY = 0;
int mouseX = 0, mouseY = 0;
int mouseWheelX = 0, mouseWheelY = 0;

void input_reset_events() {
for (int i = 0; i < SDL_NUM_SCANCODES; i++) {
buttons[i].isPressed = false;
buttons[i].isReleased = false;
}

for (int i = 0; i < 5; i++) {
mouseButtons[i].isReleased = false;
mouseButtons[i].isPressed = false;
mouseClicks[i] = 0;
}
mouseDeltaX = 0;
mouseDeltaY = 0;
mouseWheelX = 0;
mouseWheelY = 0;
}

void input_handle_event(SDL_Event *e) {
if (e->type == SDL_KEYDOWN) {
if (!buttons[e->key.keysym.scancode].isHeld) {
buttons[e->key.keysym.scancode].isHeld = true;
buttons[e->key.keysym.scancode].isPressed = true;
}
} else if (e->type == SDL_KEYUP) {
if (buttons[e->key.keysym.scancode].isHeld) {
buttons[e->key.keysym.scancode].isHeld = false;
buttons[e->key.keysym.scancode].isReleased = true;
}
}
switch (e->type) {
case SDL_KEYDOWN:
if (!buttons[e->key.keysym.scancode].isHeld) {
buttons[e->key.keysym.scancode].isHeld = true;
buttons[e->key.keysym.scancode].isPressed = true;
}
break;
case SDL_KEYUP:
if (buttons[e->key.keysym.scancode].isHeld) {
buttons[e->key.keysym.scancode].isHeld = false;
buttons[e->key.keysym.scancode].isReleased = true;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (!mouseButtons[e->button.button].isHeld) {
mouseButtons[e->button.button].isHeld = true;
mouseButtons[e->button.button].isPressed = true;
mouseClicks[e->button.button] = e->button.clicks;
}
break;
case SDL_MOUSEBUTTONUP:
if (mouseButtons[e->button.button].isHeld) {
mouseButtons[e->button.button].isHeld = false;
mouseButtons[e->button.button].isReleased = true;
}
break;
case SDL_MOUSEMOTION:
mouseDeltaX = e->motion.xrel;
mouseDeltaY = e->motion.yrel;
mouseX = e->motion.x;
mouseY = e->motion.y;
break;
case SDL_MOUSEWHEEL:
mouseWheelX = e->wheel.x;
mouseWheelY = e->wheel.y;
if (e->wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
mouseWheelX *= -1;
mouseWheelY *= -1;
}
break;
}
}

ButtonState input_get_key(SDL_Scancode code) {
return buttons[code];
}

ButtonState input_get_mouse_button(int id) {
return mouseButtons[id];
}

int input_get_mouse_x() {
return mouseX;
}

int input_get_mouse_y() {
return mouseY;
}

int input_get_mouse_delta_x() {
return mouseDeltaX;
}

int input_get_mouse_delta_y() {
return mouseDeltaY;
}

int input_get_mouse_wheel_x() {
return mouseWheelX;
}

int input_get_mouse_wheel_y() {
return mouseWheelY;
}
18 changes: 17 additions & 1 deletion Input.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,23 @@
#define HOMEWORK_INPUT_H

#include <SDL.h>
#include <stdbool.h>

void input_handle_event(SDL_Event &e);
typedef struct ButtonState {
bool isPressed;
bool isHeld;
bool isReleased;
} ButtonState;

void input_reset_events();
void input_handle_event(SDL_Event *e);
ButtonState input_get_key(SDL_Scancode code);
ButtonState input_get_mouse_button(int id);
int input_get_mouse_x();
int input_get_mouse_y();
int input_get_mouse_delta_x();
int input_get_mouse_delta_y();
int input_get_mouse_wheel_x();
int input_get_mouse_wheel_y();

#endif //HOMEWORK_INPUT_H
14 changes: 12 additions & 2 deletions Window.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ bool window_init(SDL_Window **window, SDL_Renderer **renderer, const char *title

SDL_LogSetOutputFunction(__log_output_function, NULL);

log_error("Test %s", "Hello");

if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
log_error("Couldn't initialize SDL:\nError: %s\n", SDL_GetError());
return false;
}

if (TTF_Init() != 0) {
log_error("Couldn't initialize SDL_TTF:\nError: %s\n", SDL_GetError());
return false;
}

*window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
w, h, windowFlags);
if (!*window) {
Expand All @@ -41,3 +44,10 @@ bool window_init(SDL_Window **window, SDL_Renderer **renderer, const char *title

return true;
}

void window_cleanup(SDL_Window *window, SDL_Renderer *renderer) {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
}
2 changes: 2 additions & 0 deletions Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
#define HOMEWORK_WINDOW_H

#include <SDL.h>
#include <SDL_ttf.h>
#include <stdbool.h>
#include <time.h>
#include "Utility.h"

bool window_init(SDL_Window **window, SDL_Renderer **renderer, const char *title, int w, int h, int windowFlags, int rendererFlags);
void window_cleanup(SDL_Window *window, SDL_Renderer *renderer);

#endif //HOMEWORK_WINDOW_H
4 changes: 0 additions & 4 deletions log.txt

This file was deleted.

73 changes: 51 additions & 22 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "Graphics.h"
#include "Component.h"
#include "Window.h"
#include "Input.h"

int main(int argc, char **argv) {

Expand All @@ -17,52 +18,80 @@ int main(int argc, char **argv) {
SDL_Window *window;
SDL_Renderer *renderer;

window_init(&window, &renderer, "Logic Simulator", 640, 480, SDL_WINDOW_SHOWN, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
window_init(&window, &renderer, "Logic Simulator", 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);

TTF_Init();

TTF_Font *font = TTF_OpenFont("res/SourceCodePro-Regular.ttf", 50);
TTF_Font *font = TTF_OpenFont("res/SourceCodePro-Regular.ttf", 25);
SDL_Texture *testT;
SDL_Surface *test = component_load_graphic("res/XNOR.cmp", 200, 5, font);
SDL_Surface *test = component_load_graphic("res/XNOR.cmp", 100, 3, font);
testT = SDL_CreateTextureFromSurface(renderer, test);
SDL_FreeSurface(test);

ComponentData data = component_create_data(50, 50, testT, 0);

SDL_Cursor *cursor = SDL_GetCursor();
Point cameraPos = {0, 0};
float zoom = 1;

bool quit = false;
SDL_Event e;
while (!quit) {
input_reset_events();
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_KEYDOWN: {
if (e.key.keysym.sym == SDLK_SPACE) {
SDL_DestroyTexture(testT);
test = component_load_graphic("res/BUF.cmp", 200, 5, font);
testT = SDL_CreateTextureFromSurface(renderer, test);
SDL_FreeSurface(test);
}
}
case SDL_WINDOWEVENT_FOCUS_GAINED:
SDL_CaptureMouse(true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
SDL_CaptureMouse(false);
break;
}
input_handle_event(&e);
}

SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);

int x, y;
SDL_GetMouseState(&x, &y);
int w, h;
SDL_QueryTexture(testT, NULL, NULL, &w, &h);
SDL_Rect r = {x, y, w, h};
SDL_RenderDrawLine(renderer, 0, 0, 639, 479);
SDL_RenderCopy(renderer, testT, NULL, &r);
component_render(&data, renderer, cameraPos);

if (input_get_mouse_button(SDL_BUTTON_MIDDLE).isHeld) {
cameraPos.x -= (float) input_get_mouse_delta_x();
cameraPos.y -= (float) input_get_mouse_delta_y();
}

if (input_get_mouse_button(SDL_BUTTON_MIDDLE).isPressed) {
SDL_FreeCursor(cursor);
cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
SDL_SetCursor(cursor);
}
if (input_get_mouse_button(SDL_BUTTON_MIDDLE).isReleased) {
SDL_FreeCursor(cursor);
cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
SDL_SetCursor(cursor);
}

zoom *= powf(0.9f, -(float)input_get_mouse_wheel_y());
if (zoom < 0.45) zoom = 0.45f;
if (zoom > 5) zoom = 5;

if (input_get_mouse_wheel_y() != 0 || input_get_key(SDL_SCANCODE_SPACE).isPressed) {
SDL_DestroyTexture(testT);
TTF_CloseFont(font);
font = TTF_OpenFont("res/SourceCodePro-Regular.ttf", (int)(25 * zoom));
SDL_Surface *surf = component_load_graphic("res/XNOR.cmp", 100 * zoom, 3 * zoom, font);
testT = SDL_CreateTextureFromSurface(renderer, surf);
SDL_FreeSurface(surf);
component_update_texture(&data,testT);
}

SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();

window_cleanup(window, renderer);

return 0;
}

0 comments on commit 60a2df5

Please sign in to comment.