Completely separates input handling and game logic.
This commit disables mouse support in menus. This needs to be rethought to be more stable.
This commit is contained in:
parent
186cc7b514
commit
821cac2fbd
|
@ -157,7 +157,7 @@ add_executable(breakhack
|
|||
src/menu
|
||||
src/collisions
|
||||
src/keyboard
|
||||
src/keyboardinput
|
||||
src/input
|
||||
src/mixer
|
||||
src/io_util
|
||||
src/physfsrwops
|
||||
|
@ -221,15 +221,15 @@ IF (CMOCKA_FOUND AND NOT OSX AND NOT CLANG)
|
|||
target_link_libraries(test_hashtable ${CMOCKA_LIBRARY})
|
||||
add_test(test_hashtable test_hashtable)
|
||||
|
||||
add_executable(test_keyboardinput test/test_keyboardinput src/keyboardinput src/keyboard)
|
||||
target_link_libraries(test_keyboardinput
|
||||
add_executable(test_input test/test_input src/input src/keyboard)
|
||||
target_link_libraries(test_input
|
||||
${CMOCKA_LIBRARY}
|
||||
${SDL2_LIBRARY}
|
||||
${SDL2MAIN_LIBRARY}
|
||||
)
|
||||
set_target_properties(test_keyboardinput PROPERTIES
|
||||
LINK_FLAGS "-Wl,--wrap,keyboard_direction_press -Wl,--wrap,keyboard_press")
|
||||
add_test(test_keyboardinput test_keyboardinput)
|
||||
#set_target_properties(test_input PROPERTIES
|
||||
#LINK_FLAGS "-Wl,--wrap,keyboard_direction_press -Wl,--wrap,keyboard_press")
|
||||
add_test(test_input test_input)
|
||||
ENDIF ()
|
||||
|
||||
# LINT:
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "timer.h"
|
||||
#include "vector2d.h"
|
||||
|
||||
struct UpdateData_t;
|
||||
struct UpdateData;
|
||||
|
||||
typedef struct {
|
||||
Position pos;
|
||||
|
@ -40,7 +40,7 @@ typedef struct {
|
|||
|
||||
ActionText* actiontext_create(Sprite*);
|
||||
|
||||
void actiontext_update(ActionText*, struct UpdateData_t*);
|
||||
void actiontext_update(ActionText*, struct UpdateData*);
|
||||
|
||||
void actiontext_render(ActionText*, Camera*);
|
||||
|
||||
|
|
|
@ -40,20 +40,14 @@ gui_button_check_pointer(GuiButton *button, Pointer *pointer)
|
|||
}
|
||||
|
||||
void
|
||||
gui_button_handle_event(GuiButton *button, SDL_Event *event)
|
||||
gui_button_update(GuiButton *button, Input *input)
|
||||
{
|
||||
if (event->type == SDL_MOUSEBUTTONDOWN) {
|
||||
Position p = { input->mouseX, input->mouseY };
|
||||
button->hover = position_in_rect(&p, &button->area);
|
||||
|
||||
if (event->button.button != SDL_BUTTON_LEFT)
|
||||
return;
|
||||
|
||||
Position p = { event->button.x, event->button.y };
|
||||
if (input_mousebutton_is_pressed(input, MBUTTON_LEFT)) {
|
||||
if (position_in_rect(&p, &button->area) && button->event)
|
||||
button->event(button->usrdata);
|
||||
|
||||
} else if (event->type == SDL_MOUSEMOTION) {
|
||||
Position p = { event->motion.x, event->motion.y };
|
||||
button->hover = position_in_rect(&p, &button->area);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
#include "sprite.h"
|
||||
#include "linkedlist.h"
|
||||
#include "camera.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef struct GuiButton_t {
|
||||
typedef struct GuiButton {
|
||||
SDL_Rect area;
|
||||
bool hover;
|
||||
void *usrdata;
|
||||
|
@ -39,7 +40,7 @@ void
|
|||
gui_button_check_pointer(GuiButton*, Pointer*);
|
||||
|
||||
void
|
||||
gui_button_handle_event(GuiButton*, SDL_Event*);
|
||||
gui_button_update(GuiButton*, Input*);
|
||||
|
||||
void
|
||||
gui_button_destroy(GuiButton*);
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "input.h"
|
||||
#include "vector2d.h"
|
||||
|
||||
void
|
||||
input_init(Input *input)
|
||||
{
|
||||
input->keyState = 0;
|
||||
input->lastKeyState = 0;
|
||||
input->mouseButtonState = 0;
|
||||
input->lastMouseButtonState = 0;
|
||||
input->mouseX = 0;
|
||||
input->mouseY = 0;
|
||||
}
|
||||
|
||||
void input_reset(Input *input)
|
||||
{
|
||||
input->lastKeyState = input->keyState;
|
||||
input->lastMouseButtonState = input->mouseButtonState;
|
||||
input->keyState = 0;
|
||||
input->mouseButtonState = 0;
|
||||
}
|
||||
|
||||
static Uint64
|
||||
get_event_key(SDL_Event *event)
|
||||
{
|
||||
switch (event->key.keysym.sym) {
|
||||
case SDLK_UP:
|
||||
case SDLK_k:
|
||||
case SDLK_w:
|
||||
return KEY_UP;
|
||||
case SDLK_DOWN:
|
||||
case SDLK_j:
|
||||
return KEY_DOWN;
|
||||
case SDLK_s:
|
||||
return KEY_DOWN | KEY_S;
|
||||
case SDLK_LEFT:
|
||||
case SDLK_h:
|
||||
case SDLK_a:
|
||||
return KEY_LEFT;
|
||||
case SDLK_RIGHT:
|
||||
case SDLK_l:
|
||||
case SDLK_d:
|
||||
return KEY_RIGHT;
|
||||
case SDLK_0:
|
||||
return KEY_NUM0;
|
||||
case SDLK_1:
|
||||
return KEY_NUM1;
|
||||
case SDLK_2:
|
||||
return KEY_NUM2;
|
||||
case SDLK_3:
|
||||
return KEY_NUM3;
|
||||
case SDLK_4:
|
||||
return KEY_NUM4;
|
||||
case SDLK_5:
|
||||
return KEY_NUM5;
|
||||
case SDLK_6:
|
||||
return KEY_NUM6;
|
||||
case SDLK_7:
|
||||
return KEY_NUM7;
|
||||
case SDLK_8:
|
||||
return KEY_NUM8;
|
||||
case SDLK_9:
|
||||
return KEY_NUM9;
|
||||
case SDLK_ESCAPE:
|
||||
return KEY_ESC;
|
||||
case SDLK_RETURN:
|
||||
return KEY_ENTER;
|
||||
case SDLK_LALT:
|
||||
case SDLK_RALT:
|
||||
return KEY_ALT;
|
||||
case SDLK_LCTRL:
|
||||
case SDLK_RCTRL:
|
||||
return KEY_CTRL;
|
||||
case SDLK_m:
|
||||
return KEY_M;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32
|
||||
get_event_mousebutton(SDL_Event *event)
|
||||
{
|
||||
switch (event->button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
return MBUTTON_LEFT;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
return MBUTTON_MIDDLE;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
return MBUTTON_RIGHT;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
input_handle_event(Input *input, SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_KEYDOWN)
|
||||
input->keyState |= get_event_key(event);
|
||||
else if (event->type == SDL_KEYUP)
|
||||
input->keyState &= ~get_event_key(event);
|
||||
else if (event->type == SDL_MOUSEBUTTONDOWN)
|
||||
input->mouseButtonState |= get_event_mousebutton(event);
|
||||
else if (event->type == SDL_MOUSEBUTTONUP)
|
||||
input->mouseButtonState &= ~get_event_mousebutton(event);
|
||||
else if (event->type == SDL_MOUSEMOTION) {
|
||||
input->mouseX = event->motion.x;
|
||||
input->mouseY = event->motion.y;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
input_key_is_pressed(Input *input, Uint64 key)
|
||||
{
|
||||
return (input->keyState & key) && !(input->lastKeyState & key);
|
||||
}
|
||||
|
||||
bool
|
||||
input_key_is_released(Input *input, Uint64 key)
|
||||
{
|
||||
return (input->lastKeyState & key) && !(input->keyState & key);
|
||||
}
|
||||
|
||||
bool
|
||||
input_key_is_down(Input *input, Uint64 key)
|
||||
{
|
||||
return input->keyState & key;
|
||||
}
|
||||
|
||||
bool
|
||||
input_mousebutton_is_pressed(Input *input, Uint8 button)
|
||||
{
|
||||
return (input->mouseButtonState & button)
|
||||
&& !(input->lastMouseButtonState & button);
|
||||
}
|
|
@ -16,8 +16,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEYBOARDINPUT_H_
|
||||
#define KEYBOARDINPUT_H_
|
||||
#ifndef INPUT_H_
|
||||
#define INPUT_H_
|
||||
|
||||
#include <SDL.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -36,33 +36,46 @@
|
|||
#define KEY_NUM7 2048
|
||||
#define KEY_NUM8 4096
|
||||
#define KEY_NUM9 8192
|
||||
#define KEY_ESC 16384
|
||||
#define KEY_ENTER 32768
|
||||
#define KEY_CTRL 65536
|
||||
#define KEY_ALT 131072
|
||||
#define KEY_M 262144
|
||||
#define KEY_S 524288
|
||||
|
||||
typedef struct KeyboardState {
|
||||
bool dir_left;
|
||||
bool dir_right;
|
||||
bool dir_up;
|
||||
bool dir_down;
|
||||
} KeyboardState;
|
||||
#define MBUTTON_LEFT 1
|
||||
#define MBUTTON_MIDDLE 2
|
||||
#define MBUTTON_RIGHT 4
|
||||
|
||||
typedef struct KeyboardInput {
|
||||
Uint64 currentState;
|
||||
Uint64 lastState;
|
||||
} KeyboardInput;
|
||||
typedef struct Input {
|
||||
Uint64 keyState;
|
||||
Uint64 lastKeyState;
|
||||
Uint32 mouseButtonState;
|
||||
Uint32 lastMouseButtonState;
|
||||
Uint32 mouseX;
|
||||
Uint32 mouseY;
|
||||
} Input;
|
||||
|
||||
void
|
||||
keyboardinput_init(KeyboardInput *);
|
||||
input_init(Input *);
|
||||
|
||||
void
|
||||
keyboardinput_handle_event(KeyboardInput *, SDL_Event*);
|
||||
input_reset(Input *);
|
||||
|
||||
void
|
||||
input_handle_event(Input *, SDL_Event*);
|
||||
|
||||
bool
|
||||
key_is_pressed(KeyboardInput *, Uint64 key);
|
||||
input_key_is_pressed(Input *, Uint64 key);
|
||||
|
||||
bool
|
||||
key_is_released(KeyboardInput *, Uint64 key);
|
||||
input_key_is_released(Input *, Uint64 key);
|
||||
|
||||
bool
|
||||
key_is_down(KeyboardInput *, Uint64 key);
|
||||
input_key_is_down(Input *, Uint64 key);
|
||||
|
||||
#endif // KEYBOARDINPUT_H_
|
||||
bool
|
||||
input_mousebutton_is_pressed(Input *, Uint8 button);
|
||||
|
||||
#endif // INPUT_H_
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "keyboardinput.h"
|
||||
#include "keyboard.h"
|
||||
#include "vector2d.h"
|
||||
|
||||
void
|
||||
keyboardinput_init(KeyboardInput *input)
|
||||
{
|
||||
input->currentState = 0;
|
||||
input->lastState = 0;
|
||||
}
|
||||
|
||||
void
|
||||
keyboardinput_handle_event(KeyboardInput *input, SDL_Event *event)
|
||||
{
|
||||
if (keyboard_direction_press(UP, event)) {
|
||||
input->currentState |= KEY_UP;
|
||||
} else if (keyboard_direction_press(DOWN, event)) {
|
||||
input->currentState |= KEY_DOWN;
|
||||
} else if (keyboard_direction_press(LEFT, event)) {
|
||||
input->currentState |= KEY_LEFT;
|
||||
} else if (keyboard_direction_press(RIGHT, event)) {
|
||||
input->currentState |= KEY_RIGHT;
|
||||
} else if (keyboard_press(SDLK_0, event)) {
|
||||
input->currentState |= KEY_NUM1;
|
||||
}
|
||||
for (int i = SDLK_0; i <= SDLK_9; ++i) {
|
||||
if (keyboard_press(i, event))
|
||||
input->currentState |= (KEY_NUM0 << (i - SDLK_0));
|
||||
}
|
||||
|
||||
if (keyboard_direction_release(UP, event)) {
|
||||
input->currentState &= ~KEY_UP;
|
||||
} else if (keyboard_direction_release(DOWN, event)) {
|
||||
input->currentState &= ~KEY_DOWN;
|
||||
} else if (keyboard_direction_release(LEFT, event)) {
|
||||
input->currentState &= ~KEY_LEFT;
|
||||
} else if (keyboard_direction_release(RIGHT, event)) {
|
||||
input->currentState &= ~KEY_RIGHT;
|
||||
} else if (keyboard_release(SDLK_0, event)) {
|
||||
input->currentState &= ~KEY_NUM1;
|
||||
}
|
||||
for (int i = SDLK_0; i <= SDLK_9; ++i) {
|
||||
if (keyboard_release(i, event))
|
||||
input->currentState &= ~(KEY_NUM0 << (i - SDLK_0));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
key_is_pressed(KeyboardInput *input, Uint64 key)
|
||||
{
|
||||
return (input->currentState & key) && !(input->lastState & key);
|
||||
}
|
||||
|
||||
bool
|
||||
key_is_released(KeyboardInput *input, Uint64 key)
|
||||
{
|
||||
return (input->lastState & key) && !(input->currentState & key);
|
||||
}
|
||||
|
||||
bool
|
||||
key_is_down(KeyboardInput *input, Uint64 key)
|
||||
{
|
||||
return input->currentState & key;
|
||||
}
|
||||
|
62
src/main.c
62
src/main.c
|
@ -48,6 +48,7 @@
|
|||
#include "update_data.h"
|
||||
#include "settings.h"
|
||||
#include "actiontextbuilder.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef enum Turn_t {
|
||||
PLAYER,
|
||||
|
@ -61,7 +62,6 @@ static Map *gMap = NULL;
|
|||
static RoomMatrix *gRoomMatrix = NULL;
|
||||
static Gui *gGui = NULL;
|
||||
static SkillBar *gSkillBar = NULL;
|
||||
static Pointer *gPointer = NULL;
|
||||
static unsigned int cLevel = 1;
|
||||
static float deltaTime = 1.0;
|
||||
static double renderScale = 1.0;
|
||||
|
@ -76,6 +76,7 @@ static SDL_Rect bottomGuiViewport;
|
|||
static SDL_Rect rightGuiViewport;
|
||||
static SDL_Rect menuViewport;
|
||||
static Turn currentTurn = PLAYER;
|
||||
static Input input;
|
||||
|
||||
static SDL_Color C_MENU_DEFAULT = { 255, 255, 0, 255 };
|
||||
static SDL_Color C_MENU_OUTLINE_DEFAULT = { 0, 0, 0, 255 };
|
||||
|
@ -189,13 +190,13 @@ static bool
|
|||
initGame(void)
|
||||
{
|
||||
initViewports();
|
||||
input_init(&input);
|
||||
texturecache_init(gRenderer);
|
||||
gCamera = camera_create(gRenderer);
|
||||
gRoomMatrix = roommatrix_create();
|
||||
gGui = gui_create(gCamera);
|
||||
gSkillBar = skillbar_create(gRenderer);
|
||||
item_builder_init(gRenderer);
|
||||
gPointer = pointer_create(gRenderer);
|
||||
particle_engine_init();
|
||||
menuTimer = timer_create();
|
||||
actiontextbuilder_init(gRenderer);
|
||||
|
@ -360,19 +361,20 @@ init(void)
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_main_events(SDL_Event *event)
|
||||
handle_main_input(void)
|
||||
{
|
||||
if (gGameState == PLAYING
|
||||
|| gGameState == IN_GAME_MENU
|
||||
|| gGameState == GAME_OVER)
|
||||
{
|
||||
if (keyboard_press(SDLK_ESCAPE, event)) {
|
||||
if (input_key_is_pressed(&input, KEY_ESC)) {
|
||||
toggleInGameMenu(NULL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyboard_mod_press(SDLK_m, KMOD_CTRL, event)) {
|
||||
if (input_key_is_down(&input, KEY_CTRL)
|
||||
&& input_key_is_pressed(&input, SDLK_m)) {
|
||||
if (mixer_toggle_music(&gGameState))
|
||||
gui_log("Music enabled");
|
||||
else
|
||||
|
@ -380,7 +382,8 @@ handle_main_events(SDL_Event *event)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (keyboard_mod_press(SDLK_s, KMOD_CTRL, event)) {
|
||||
if (input_key_is_down(&input, KEY_CTRL)
|
||||
&& input_key_is_pressed(&input, SDLK_s)) {
|
||||
if (mixer_toggle_sound())
|
||||
gui_log("Sound enabled");
|
||||
else
|
||||
|
@ -398,31 +401,17 @@ handle_events(void)
|
|||
bool quit = false;
|
||||
int handleCount = 0;
|
||||
|
||||
input_reset(&input);
|
||||
while (SDL_PollEvent(&event) != 0) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
quit = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handle_main_events(&event))
|
||||
continue;
|
||||
|
||||
if (gGameState == PLAYING) {
|
||||
if (currentTurn == PLAYER && !player_turn_over(gPlayer))
|
||||
gPlayer->handle_event(gPlayer,
|
||||
gRoomMatrix,
|
||||
&event);
|
||||
roommatrix_handle_event(gRoomMatrix, &event);
|
||||
skillbar_handle_event(gSkillBar, &event);
|
||||
} else if (gGameState == MENU) {
|
||||
menu_handle_event(mainMenu, &event);
|
||||
} else if (gGameState == IN_GAME_MENU) {
|
||||
menu_handle_event(inGameMenu, &event);
|
||||
}
|
||||
pointer_handle_event(gPointer, &event);
|
||||
input_handle_event(&input, &event);
|
||||
|
||||
handleCount++;
|
||||
if (handleCount >= 5) {
|
||||
if (handleCount >= 20) {
|
||||
debug("Flushing event queue");
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
|
||||
|
@ -467,6 +456,7 @@ populateUpdateData(UpdateData *data, float deltatime)
|
|||
data->player = gPlayer;
|
||||
data->map = gMap;
|
||||
data->matrix = gRoomMatrix;
|
||||
data->input = &input;
|
||||
data->deltatime = deltatime;
|
||||
}
|
||||
|
||||
|
@ -476,6 +466,11 @@ run_game(void)
|
|||
static UpdateData updateData;
|
||||
static unsigned int playerLevel = 1;
|
||||
|
||||
if (gGameState == IN_GAME_MENU)
|
||||
menu_update(inGameMenu, &input);
|
||||
if (gGameState != PLAYING && gGameState != IN_GAME_MENU)
|
||||
return;
|
||||
|
||||
map_clear_dead_monsters(gMap, gPlayer);
|
||||
map_clear_collected_items(gMap);
|
||||
roommatrix_populate_from_map(gRoomMatrix, gMap);
|
||||
|
@ -489,17 +484,20 @@ run_game(void)
|
|||
playerLevel = gPlayer->stats.lvl;
|
||||
skillbar_check_skill_activation(gSkillBar, gPlayer);
|
||||
}
|
||||
|
||||
if (gGameState == PLAYING && currentTurn == PLAYER)
|
||||
player_update(&updateData);
|
||||
|
||||
gui_update_player_stats(gGui, gPlayer, gMap, gRenderer);
|
||||
camera_update(gCamera, updateData.deltatime);
|
||||
particle_engine_update(deltaTime);
|
||||
|
||||
roommatrix_update(&updateData);
|
||||
actiontextbuilder_update(&updateData);
|
||||
player_update(&updateData);
|
||||
skillbar_update(gSkillBar, &updateData);
|
||||
camera_follow_position(gCamera, &gPlayer->sprite->pos);
|
||||
map_set_current_room(gMap, &gPlayer->sprite->pos);
|
||||
map_update(&updateData);
|
||||
|
||||
roommatrix_update_with_player(gRoomMatrix, gPlayer);
|
||||
if (currentTurn == PLAYER) {
|
||||
if (player_turn_over(gPlayer)) {
|
||||
currentTurn = MONSTER;
|
||||
|
@ -541,16 +539,13 @@ run_game(void)
|
|||
|
||||
SDL_RenderSetViewport(gRenderer, NULL);
|
||||
particle_engine_render_global(gCamera);
|
||||
|
||||
if (gGameState == IN_GAME_MENU) {
|
||||
SDL_Rect dimmer = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
|
||||
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 150);
|
||||
SDL_RenderFillRect(gRenderer, &dimmer);
|
||||
menu_render(inGameMenu, gCamera);
|
||||
}
|
||||
if (gGameState == GAME_OVER) {
|
||||
// TODO(Linus): Render game over?
|
||||
}
|
||||
pointer_render(gPointer, gCamera);
|
||||
|
||||
SDL_RenderPresent(gRenderer);
|
||||
|
||||
|
@ -579,6 +574,10 @@ run_menu(void)
|
|||
map_move_monsters(gMap, gRoomMatrix);
|
||||
}
|
||||
|
||||
menu_update(mainMenu, &input);
|
||||
if (gGameState != MENU)
|
||||
return;
|
||||
|
||||
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(gRenderer);
|
||||
SDL_RenderSetViewport(gRenderer, &menuViewport);
|
||||
|
@ -587,7 +586,6 @@ run_menu(void)
|
|||
|
||||
SDL_RenderSetViewport(gRenderer, NULL);
|
||||
menu_render(mainMenu, gCamera);
|
||||
pointer_render(gPointer, gCamera);
|
||||
|
||||
SDL_RenderPresent(gRenderer);
|
||||
}
|
||||
|
@ -606,6 +604,7 @@ void run(void)
|
|||
timer_start(fpsTimer);
|
||||
|
||||
quit = handle_events();
|
||||
handle_main_input();
|
||||
|
||||
switch (gGameState) {
|
||||
case PLAYING:
|
||||
|
@ -656,7 +655,6 @@ void close(void)
|
|||
roommatrix_destroy(gRoomMatrix);
|
||||
gui_destroy(gGui);
|
||||
skillbar_destroy(gSkillBar);
|
||||
pointer_destroy(gPointer);
|
||||
actiontextbuilder_close();
|
||||
item_builder_close();
|
||||
particle_engine_close();
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "player.h"
|
||||
#include "map_room_modifiers.h"
|
||||
|
||||
struct UpdateData_t;
|
||||
struct UpdateData;
|
||||
|
||||
typedef struct MapTile_t {
|
||||
int textureIndex0;
|
||||
|
@ -89,7 +89,7 @@ void
|
|||
map_clear_collected_items(Map*);
|
||||
|
||||
void
|
||||
map_update(struct UpdateData_t*);
|
||||
map_update(struct UpdateData*);
|
||||
|
||||
void
|
||||
map_render(Map*, Camera*);
|
||||
|
|
57
src/menu.c
57
src/menu.c
|
@ -42,17 +42,17 @@ menu_create(void)
|
|||
}
|
||||
|
||||
static void
|
||||
handle_keyboard_event(Menu *m, SDL_Event *event)
|
||||
handle_keyboard_input(Menu *m, Input *input)
|
||||
{
|
||||
int lastSelect = -1;
|
||||
|
||||
if (keyboard_direction_press(UP, event)) {
|
||||
if (input_key_is_pressed(input, KEY_UP)) {
|
||||
lastSelect = m->selected;
|
||||
m->selected--;
|
||||
} else if (keyboard_direction_press(DOWN, event)) {
|
||||
} else if (input_key_is_pressed(input, KEY_DOWN)) {
|
||||
lastSelect = m->selected;
|
||||
m->selected++;
|
||||
} else if (keyboard_press(SDLK_RETURN, event)) {
|
||||
} else if (input_key_is_pressed(input, KEY_ENTER)) {
|
||||
MenuItem *item = linkedlist_get(&m->items, m->selected);
|
||||
if (item->button->event)
|
||||
item->button->event(item->button->usrdata);
|
||||
|
@ -69,55 +69,10 @@ handle_keyboard_event(Menu *m, SDL_Event *event)
|
|||
((MenuItem*) linkedlist_get(&m->items, m->selected))->button->hover = true;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_mouse_motion_event(Menu *m, SDL_Event *event)
|
||||
{
|
||||
LinkedList *items;
|
||||
int current_select;
|
||||
bool activeItemFound = false;
|
||||
|
||||
items = m->items;
|
||||
current_select = 0;
|
||||
while (items) {
|
||||
MenuItem *item = items->data;
|
||||
items = items->next;
|
||||
|
||||
item->button->hover = false;
|
||||
gui_button_handle_event(item->button, event);
|
||||
if (item->button->hover) {
|
||||
if (current_select != m->selected) {
|
||||
mixer_play_effect(CLICK);
|
||||
m->selected = current_select;
|
||||
}
|
||||
activeItemFound = true;
|
||||
}
|
||||
current_select++;
|
||||
}
|
||||
|
||||
if (!activeItemFound)
|
||||
((MenuItem*) linkedlist_get(&m->items, m->selected))->button->hover = true;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_mouse_button_event(Menu *m, SDL_Event *event)
|
||||
{
|
||||
/* NOTE: In some cases the button/item is destroyed by the click action
|
||||
* make sure you don't 'use' items after a click event has fired. It
|
||||
* might break. */
|
||||
|
||||
MenuItem *item = linkedlist_get(&m->items, m->selected);
|
||||
gui_button_handle_event(item->button, event);
|
||||
}
|
||||
|
||||
void
|
||||
menu_handle_event(Menu *m, SDL_Event *event)
|
||||
menu_update(Menu *m, Input *input)
|
||||
{
|
||||
if (event->type == SDL_KEYDOWN)
|
||||
handle_keyboard_event(m, event);
|
||||
else if (event->type == SDL_MOUSEMOTION)
|
||||
handle_mouse_motion_event(m, event);
|
||||
else if (event->type == SDL_MOUSEBUTTONDOWN)
|
||||
handle_mouse_button_event(m, event);
|
||||
handle_keyboard_input(m, input);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -34,7 +34,7 @@ Menu *
|
|||
menu_create(void);
|
||||
|
||||
void
|
||||
menu_handle_event(Menu*, SDL_Event*);
|
||||
menu_update(Menu*, Input*);
|
||||
|
||||
void
|
||||
menu_item_add(Menu*, Sprite*, Sprite*, void (*)(void*));
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "player.h"
|
||||
#include "linkedlist.h"
|
||||
|
||||
struct UpdateData_t;
|
||||
struct UpdateData;
|
||||
|
||||
typedef enum {
|
||||
PACIFIST,
|
||||
|
@ -83,13 +83,13 @@ void
|
|||
monster_update_stats_for_level(Monster*, unsigned int level);
|
||||
|
||||
void
|
||||
monster_update(Monster*, struct UpdateData_t*);
|
||||
monster_update(Monster*, struct UpdateData*);
|
||||
|
||||
void
|
||||
monster_drop_loot(Monster*, Map*, Player*);
|
||||
|
||||
void
|
||||
monster_set_behaviour(Monster *, MonsterBehaviour m);
|
||||
monster_set_behaviour(Monster *, MonsterBehaviour behaviour);
|
||||
|
||||
void
|
||||
monster_destroy(Monster*);
|
||||
|
|
106
src/player.c
106
src/player.c
|
@ -208,22 +208,39 @@ player_sip_health(Player *player)
|
|||
}
|
||||
}
|
||||
|
||||
static Vector2d
|
||||
read_direction_from(Input *input)
|
||||
{
|
||||
if (input_key_is_pressed(input, KEY_LEFT))
|
||||
return VECTOR2D_LEFT;
|
||||
else if (input_key_is_pressed(input, KEY_RIGHT))
|
||||
return VECTOR2D_RIGHT;
|
||||
else if (input_key_is_pressed(input, KEY_UP))
|
||||
return VECTOR2D_UP;
|
||||
else if (input_key_is_pressed(input, KEY_DOWN))
|
||||
return VECTOR2D_DOWN;
|
||||
else
|
||||
return VECTOR2D_NODIR;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_next_move(Player *player, RoomMatrix *matrix)
|
||||
handle_next_move(UpdateData *data)
|
||||
{
|
||||
static unsigned int step = 1;
|
||||
if (!vector2d_equals(player->nextDirection, VECTOR2D_NODIR))
|
||||
move(player, matrix, player->nextDirection);
|
||||
|
||||
map_room_modifier_player_effect(player, matrix, &player->nextDirection, move);
|
||||
Player *player = data->player;
|
||||
RoomMatrix *matrix = data->matrix;
|
||||
Vector2d nextDir = read_direction_from(data->input);
|
||||
if (!vector2d_equals(nextDir, VECTOR2D_NODIR))
|
||||
move(player, matrix, nextDir);
|
||||
|
||||
if (!vector2d_equals(VECTOR2D_NODIR, player->nextDirection)) {
|
||||
map_room_modifier_player_effect(player, matrix, &nextDir, move);
|
||||
|
||||
if (!vector2d_equals(VECTOR2D_NODIR, nextDir)) {
|
||||
player->sprite->clip.x = 16*step;
|
||||
++step;
|
||||
step = step % 4;
|
||||
}
|
||||
|
||||
player->nextDirection = VECTOR2D_NODIR;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -237,19 +254,23 @@ use_skill(Skill *skill, SkillData *skillData)
|
|||
}
|
||||
|
||||
static void
|
||||
check_skill_activation(Player *player, RoomMatrix *matrix, SDL_Event *event)
|
||||
check_skill_activation(UpdateData *data)
|
||||
{
|
||||
// TODO(Linus): This could be "smarter"
|
||||
Player *player = data->player;
|
||||
Input *input = data->input;
|
||||
RoomMatrix *matrix = data->matrix;
|
||||
|
||||
unsigned int selected = 0;
|
||||
if (keyboard_press(SDLK_1, event)) {
|
||||
if (input_key_is_pressed(input, KEY_NUM1)) {
|
||||
selected = 1;
|
||||
} else if (keyboard_press(SDLK_2, event)) {
|
||||
} else if (input_key_is_pressed(input, KEY_NUM2)) {
|
||||
selected = 2;
|
||||
} else if (keyboard_press(SDLK_3, event)) {
|
||||
} else if (input_key_is_pressed(input, KEY_NUM3)) {
|
||||
selected = 3;
|
||||
} else if (keyboard_press(SDLK_4, event)) {
|
||||
} else if (input_key_is_pressed(input, KEY_NUM4)) {
|
||||
selected = 4;
|
||||
} else if (keyboard_press(SDLK_5, event)) {
|
||||
} else if (input_key_is_pressed(input, KEY_NUM5)) {
|
||||
selected = 5;
|
||||
}
|
||||
|
||||
|
@ -273,9 +294,13 @@ check_skill_activation(Player *player, RoomMatrix *matrix, SDL_Event *event)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check_skill_trigger(Player *player, RoomMatrix *matrix)
|
||||
static bool
|
||||
check_skill_trigger(UpdateData *data)
|
||||
{
|
||||
Player *player = data->player;
|
||||
RoomMatrix *matrix = data->matrix;
|
||||
Input *input = data->input;
|
||||
|
||||
int activeSkill = -1;
|
||||
for (int i = 0; i < PLAYER_SKILL_COUNT; ++i) {
|
||||
if (player->skills[i] && player->skills[i]->active) {
|
||||
|
@ -285,48 +310,16 @@ check_skill_trigger(Player *player, RoomMatrix *matrix)
|
|||
}
|
||||
|
||||
if (activeSkill < 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
Vector2d nextDir = read_direction_from(input);
|
||||
if (vector2d_equals(nextDir, VECTOR2D_NODIR))
|
||||
return false;
|
||||
|
||||
if (vector2d_equals(player->nextDirection, VECTOR2D_NODIR))
|
||||
return;
|
||||
|
||||
SkillData skillData = { player, matrix, player->nextDirection };
|
||||
SkillData skillData = { player, matrix, nextDir };
|
||||
use_skill(player->skills[activeSkill], &skillData);
|
||||
|
||||
player->nextDirection = VECTOR2D_NODIR;
|
||||
}
|
||||
|
||||
static void
|
||||
read_player_next_direction(Player *player, SDL_Event *event)
|
||||
{
|
||||
player->nextDirection = VECTOR2D_NODIR;
|
||||
|
||||
if (keyboard_direction_press(LEFT, event))
|
||||
player->nextDirection = VECTOR2D_LEFT;
|
||||
if (keyboard_direction_press(RIGHT, event))
|
||||
player->nextDirection = VECTOR2D_RIGHT;
|
||||
if (keyboard_direction_press(UP, event))
|
||||
player->nextDirection = VECTOR2D_UP;
|
||||
if (keyboard_direction_press(DOWN, event))
|
||||
player->nextDirection = VECTOR2D_DOWN;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handle_player_input(Player *player, RoomMatrix *matrix, SDL_Event *event)
|
||||
{
|
||||
if (player->state != ALIVE)
|
||||
return;
|
||||
|
||||
if (event->type != SDL_KEYDOWN)
|
||||
return;
|
||||
|
||||
if (player->projectiles)
|
||||
return;
|
||||
|
||||
check_skill_activation(player, matrix, event);
|
||||
read_player_next_direction(player, event);
|
||||
return true;
|
||||
}
|
||||
|
||||
Player*
|
||||
|
@ -347,7 +340,6 @@ player_create(class_t class, SDL_Renderer *renderer)
|
|||
player->state = ALIVE;
|
||||
player->projectiles = linkedlist_create();
|
||||
player->animationTimer = timer_create();
|
||||
player->nextDirection = VECTOR2D_NODIR;
|
||||
|
||||
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {
|
||||
player->skills[i] = NULL;
|
||||
|
@ -386,7 +378,6 @@ player_create(class_t class, SDL_Renderer *renderer)
|
|||
player->sprite->pos = (Position) { TILE_DIMENSION, TILE_DIMENSION };
|
||||
player->sprite->dim = GAME_DIMENSION;
|
||||
player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
|
||||
player->handle_event = &handle_player_input;
|
||||
|
||||
return player;
|
||||
}
|
||||
|
@ -465,8 +456,9 @@ void player_update(UpdateData *data)
|
|||
{
|
||||
Player *player = data->player;
|
||||
|
||||
check_skill_trigger(player, data->matrix);
|
||||
handle_next_move(player, data->matrix);
|
||||
check_skill_activation(data);
|
||||
if (!check_skill_trigger(data))
|
||||
handle_next_move(data);
|
||||
|
||||
if (player->state == FALLING && player->stats.hp > 0) {
|
||||
if (!timer_started(player->animationTimer)) {
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
#include "camera.h"
|
||||
#include "skill.h"
|
||||
#include "linkedlist.h"
|
||||
#include "input.h"
|
||||
|
||||
#define PLAYER_SKILL_COUNT 5
|
||||
|
||||
// Foward declare
|
||||
struct UpdateData_t;
|
||||
struct UpdateData;
|
||||
|
||||
typedef enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR } class_t;
|
||||
typedef enum PlayerState { ALIVE, DEAD, FALLING } state_t;
|
||||
|
@ -63,8 +64,6 @@ typedef struct Player_t {
|
|||
state_t state;
|
||||
Skill *skills[PLAYER_SKILL_COUNT];
|
||||
Timer *animationTimer;
|
||||
Vector2d nextDirection;
|
||||
void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*);
|
||||
} Player;
|
||||
|
||||
Player*
|
||||
|
@ -86,7 +85,7 @@ void
|
|||
player_reset_steps(Player*);
|
||||
|
||||
void
|
||||
player_update(struct UpdateData_t *);
|
||||
player_update(struct UpdateData *);
|
||||
|
||||
void
|
||||
player_render(Player*, Camera*);
|
||||
|
|
|
@ -38,13 +38,11 @@ pointer_create(SDL_Renderer *renderer)
|
|||
}
|
||||
|
||||
void
|
||||
pointer_handle_event(Pointer *p, SDL_Event *event)
|
||||
pointer_handle_input(Pointer *p, Input *input)
|
||||
{
|
||||
if (event->type == SDL_MOUSEMOTION) {
|
||||
// Compensate for a small offset in the sprite
|
||||
p->sprite->pos.x = event->motion.x - 6;
|
||||
p->sprite->pos.y = event->motion.y - 6;
|
||||
}
|
||||
p->sprite->pos.x = input->mouseX - 6;
|
||||
p->sprite->pos.y = input->mouseY - 6;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <SDL.h>
|
||||
#include "sprite.h"
|
||||
#include "camera.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef struct Pointer_t {
|
||||
Sprite *sprite;
|
||||
|
@ -31,7 +32,7 @@ Pointer *
|
|||
pointer_create(SDL_Renderer *renderer);
|
||||
|
||||
void
|
||||
pointer_handle_event(Pointer*, SDL_Event *event);
|
||||
pointer_handle_input(Pointer*, Input *);
|
||||
|
||||
void
|
||||
pointer_toggle_clickable_pointer(Pointer *, bool clickable);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "map.h"
|
||||
#include "player.h"
|
||||
#include "item.h"
|
||||
#include "update_data.h"
|
||||
|
||||
RoomMatrix* roommatrix_create(void)
|
||||
{
|
||||
|
@ -37,18 +38,28 @@ RoomMatrix* roommatrix_create(void)
|
|||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
roommatrix_handle_event(RoomMatrix *matrix, SDL_Event *event)
|
||||
static void
|
||||
roommatrix_update_with_player(RoomMatrix *rm, Player *p)
|
||||
{
|
||||
if (event->type != SDL_MOUSEMOTION)
|
||||
return;
|
||||
Position rp = position_to_matrix_coords(&p->sprite->pos);
|
||||
rm->spaces[rp.x][rp.y].occupied = true;
|
||||
rm->spaces[rp.x][rp.y].player = p;
|
||||
rm->playerRoomPos = rp;
|
||||
}
|
||||
|
||||
if (event->motion.x < GAME_VIEW_WIDTH
|
||||
&& event->motion.y < GAME_VIEW_HEIGHT)
|
||||
void
|
||||
roommatrix_update(UpdateData *data)
|
||||
{
|
||||
RoomMatrix *matrix = data->matrix;
|
||||
Input *input = data->input;
|
||||
|
||||
if (input->mouseX < GAME_VIEW_WIDTH
|
||||
&& input->mouseY < GAME_VIEW_HEIGHT)
|
||||
{
|
||||
matrix->mousePos.x = event->motion.x;
|
||||
matrix->mousePos.y = event->motion.y;
|
||||
matrix->mousePos.x = input->mouseX;
|
||||
matrix->mousePos.y = input->mouseY;
|
||||
}
|
||||
roommatrix_update_with_player(matrix, data->player);
|
||||
}
|
||||
|
||||
void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
|
||||
|
@ -136,15 +147,6 @@ max(int a, int b)
|
|||
}
|
||||
#endif // max
|
||||
|
||||
void
|
||||
roommatrix_update_with_player(RoomMatrix *rm, Player *p)
|
||||
{
|
||||
Position rp = position_to_matrix_coords(&p->sprite->pos);
|
||||
rm->spaces[rp.x][rp.y].occupied = true;
|
||||
rm->spaces[rp.x][rp.y].player = p;
|
||||
rm->playerRoomPos = rp;
|
||||
}
|
||||
|
||||
void
|
||||
roommatrix_add_lightsource(RoomMatrix *matrix, Position *pos)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "position.h"
|
||||
#include "camera.h"
|
||||
#include "map_room_modifiers.h"
|
||||
#include "input.h"
|
||||
|
||||
typedef struct Sprite_t Sprite;
|
||||
typedef struct Map_t Map;
|
||||
|
@ -32,6 +33,8 @@ typedef struct Player_t Player;
|
|||
typedef struct Item_t Item;
|
||||
typedef struct Node LinkedList;
|
||||
|
||||
struct UpdateData;
|
||||
|
||||
typedef struct {
|
||||
bool occupied;
|
||||
bool lethal;
|
||||
|
@ -52,12 +55,10 @@ typedef struct RoomMatrix_t {
|
|||
|
||||
RoomMatrix* roommatrix_create(void);
|
||||
|
||||
void roommatrix_handle_event(RoomMatrix*, SDL_Event*);
|
||||
void roommatrix_update(struct UpdateData*);
|
||||
|
||||
void roommatrix_populate_from_map(RoomMatrix*, Map*);
|
||||
|
||||
void roommatrix_update_with_player(RoomMatrix*, Player*);
|
||||
|
||||
void roommatrix_add_lightsource(RoomMatrix*, Position*);
|
||||
|
||||
void roommatrix_build_lightmap(RoomMatrix*);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "keyboard.h"
|
||||
#include "texturecache.h"
|
||||
#include "particle_engine.h"
|
||||
#include "update_data.h"
|
||||
|
||||
static void
|
||||
load_texture(SkillBar *bar, const char *path, SDL_Renderer *renderer)
|
||||
|
@ -250,17 +251,15 @@ skillbar_render(SkillBar *bar, Player *player, Camera *cam)
|
|||
}
|
||||
|
||||
void
|
||||
skillbar_handle_event(SkillBar *bar, SDL_Event *event)
|
||||
skillbar_update(SkillBar *bar, UpdateData *data)
|
||||
{
|
||||
if (event->type != SDL_KEYDOWN)
|
||||
return;
|
||||
Input *input = data->input;
|
||||
|
||||
unsigned int key = 0;
|
||||
for (SDL_Keycode keysym = SDLK_0; keysym <= SDLK_9; ++keysym) {
|
||||
if (!keyboard_press(keysym, event))
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if (!input_key_is_pressed(input, KEY_NUM0 << i))
|
||||
continue;
|
||||
key = (int)(keysym - SDLK_0);
|
||||
if (key == 0) key = 10;
|
||||
key = i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include "camera.h"
|
||||
#include "timer.h"
|
||||
#include "player.h"
|
||||
#include "input.h"
|
||||
|
||||
struct UpdateData;
|
||||
|
||||
typedef struct SkillBar_t {
|
||||
LinkedList *sprites;
|
||||
|
@ -43,7 +46,7 @@ void
|
|||
skillbar_render(SkillBar*, Player*, Camera*);
|
||||
|
||||
void
|
||||
skillbar_handle_event(SkillBar*, SDL_Event*);
|
||||
skillbar_update(SkillBar*, struct UpdateData*);
|
||||
|
||||
void
|
||||
skillbar_destroy(SkillBar*);
|
||||
|
|
|
@ -23,10 +23,11 @@
|
|||
#include "map.h"
|
||||
#include "roommatrix.h"
|
||||
|
||||
typedef struct UpdateData_t {
|
||||
typedef struct UpdateData {
|
||||
Player *player;
|
||||
Map *map;
|
||||
RoomMatrix *matrix;
|
||||
Input *input;
|
||||
float deltatime;
|
||||
} UpdateData;
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
#include "../src/input.h"
|
||||
|
||||
static void
|
||||
test_event_parse(void **state)
|
||||
{
|
||||
(void) state;
|
||||
Input input;
|
||||
input_init(&input);
|
||||
|
||||
SDL_KeyboardEvent event;
|
||||
event.type = SDL_KEYDOWN;
|
||||
event.keysym = (SDL_Keysym) { SDL_SCANCODE_W, SDLK_w, KMOD_NONE, 0 };
|
||||
|
||||
input_handle_event(&input, (SDL_Event*) &event);
|
||||
event.keysym = (SDL_Keysym) { SDL_SCANCODE_0, SDLK_0, KMOD_NONE, 0 };
|
||||
input_handle_event(&input, (SDL_Event*) &event);
|
||||
|
||||
assert_true(input_key_is_pressed(&input, KEY_UP));
|
||||
assert_true(input_key_is_pressed(&input, KEY_NUM0));
|
||||
|
||||
event.type = SDL_KEYUP;
|
||||
event.keysym = (SDL_Keysym) { SDL_SCANCODE_0, SDLK_0, KMOD_NONE, 0 };
|
||||
input_handle_event(&input, (SDL_Event*) &event);
|
||||
|
||||
assert_true(input_key_is_pressed(&input, KEY_UP));
|
||||
assert_true(!input_key_is_pressed(&input, KEY_NUM0));
|
||||
|
||||
input_reset(&input);
|
||||
|
||||
assert_true(input_key_is_released(&input, KEY_UP));
|
||||
assert_true(!input_key_is_released(&input, KEY_NUM0));
|
||||
}
|
||||
|
||||
static void
|
||||
test_keypress(void **state)
|
||||
{
|
||||
(void) state;
|
||||
Input input;
|
||||
input_init(&input);
|
||||
input.lastKeyState = 0;
|
||||
input.keyState = KEY_UP;
|
||||
assert_true(input_key_is_pressed(&input, KEY_UP));
|
||||
}
|
||||
|
||||
static void
|
||||
test_keyrelease(void **state)
|
||||
{
|
||||
(void) state;
|
||||
Input input;
|
||||
input_init(&input);
|
||||
input.lastKeyState = KEY_UP;
|
||||
input.keyState = 0;
|
||||
assert_true(input_key_is_released(&input, KEY_UP));
|
||||
}
|
||||
|
||||
static void
|
||||
test_keydown(void **state)
|
||||
{
|
||||
(void) state;
|
||||
Input input;
|
||||
input_init(&input);
|
||||
input.keyState = KEY_UP;
|
||||
assert_true(input_key_is_down(&input, KEY_UP));
|
||||
}
|
||||
|
||||
static void
|
||||
test_mousebuttons(void **state)
|
||||
{
|
||||
(void) state;
|
||||
Input input;
|
||||
input_init(&input);
|
||||
|
||||
SDL_MouseButtonEvent event;
|
||||
event.type = SDL_MOUSEBUTTONDOWN;
|
||||
event.button = SDL_BUTTON_LEFT;
|
||||
input_handle_event(&input, (SDL_Event*) &event);
|
||||
|
||||
assert_true(input_mousebutton_is_pressed(&input, MBUTTON_LEFT));
|
||||
|
||||
input_reset(&input);
|
||||
event.button = SDL_BUTTON_RIGHT;
|
||||
input_handle_event(&input, (SDL_Event*) &event);
|
||||
|
||||
assert_true(!input_mousebutton_is_pressed(&input, MBUTTON_LEFT));
|
||||
assert_true(input_mousebutton_is_pressed(&input, MBUTTON_RIGHT));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_keypress),
|
||||
cmocka_unit_test(test_keyrelease),
|
||||
cmocka_unit_test(test_keydown),
|
||||
cmocka_unit_test(test_event_parse),
|
||||
cmocka_unit_test(test_mousebuttons),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
#include "../src/keyboardinput.h"
|
||||
#include "../src/keyboard.h"
|
||||
|
||||
|
||||
bool __wrap_keyboard_direction_press(Direction, SDL_Event*);
|
||||
bool __wrap_keyboard_press(Uint64, SDL_Event*);
|
||||
|
||||
bool
|
||||
__wrap_keyboard_direction_press(Direction d, SDL_Event *event)
|
||||
{
|
||||
(void) d;
|
||||
(void) event;
|
||||
return mock_type(bool);
|
||||
}
|
||||
|
||||
bool
|
||||
__wrap_keyboard_press(Uint64 key, SDL_Event *event)
|
||||
{
|
||||
(void) key;
|
||||
(void) event;
|
||||
return mock_type(bool);
|
||||
}
|
||||
|
||||
static void
|
||||
test_event_parse(void **state)
|
||||
{
|
||||
(void) state;
|
||||
KeyboardInput input = { 0, 0 };
|
||||
|
||||
will_return(__wrap_keyboard_direction_press, true); // KEY_UP
|
||||
will_return(__wrap_keyboard_press, true); // NUM0
|
||||
will_return(__wrap_keyboard_press, false); // NUM1
|
||||
will_return(__wrap_keyboard_press, false); // NUM2
|
||||
will_return(__wrap_keyboard_press, false); // NUM3
|
||||
will_return(__wrap_keyboard_press, false); // NUM4
|
||||
will_return(__wrap_keyboard_press, false); // NUM5
|
||||
will_return(__wrap_keyboard_press, false); // NUM6
|
||||
will_return(__wrap_keyboard_press, false); // NUM7
|
||||
will_return(__wrap_keyboard_press, false); // NUM8
|
||||
will_return(__wrap_keyboard_press, false); // NUM9
|
||||
|
||||
SDL_Event event;
|
||||
keyboardinput_handle_event(&input, &event);
|
||||
|
||||
assert_true(key_is_pressed(&input, KEY_UP));
|
||||
assert_true(key_is_pressed(&input, KEY_NUM0));
|
||||
}
|
||||
|
||||
static void
|
||||
test_keypress(void **state)
|
||||
{
|
||||
(void) state;
|
||||
KeyboardInput input = { 0, 0 };
|
||||
input.lastState = 0;
|
||||
input.currentState = KEY_UP;
|
||||
assert_true(key_is_pressed(&input, KEY_UP));
|
||||
}
|
||||
|
||||
static void
|
||||
test_keyrelease(void **state)
|
||||
{
|
||||
(void) state;
|
||||
KeyboardInput input = { 0, 0 };
|
||||
input.lastState = KEY_UP;
|
||||
input.currentState = 0;
|
||||
assert_true(key_is_released(&input, KEY_UP));
|
||||
}
|
||||
|
||||
static void
|
||||
test_keydown(void **state)
|
||||
{
|
||||
(void) state;
|
||||
KeyboardInput input = { 0, 0 };
|
||||
input.currentState = KEY_UP;
|
||||
assert_true(key_is_down(&input, KEY_UP));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_keypress),
|
||||
cmocka_unit_test(test_keyrelease),
|
||||
cmocka_unit_test(test_keydown),
|
||||
cmocka_unit_test(test_event_parse),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
Loading…
Reference in New Issue