diff options
28 files changed, 870 insertions, 254 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eb39a79..aa269d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,8 @@ set(components gui header instance + keyboard + mouse pad player resource diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index b99f2e6..5ecf3c5 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -22,12 +22,19 @@ function(sprite) BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}) add_dependencies(iso ${SPRITE_NAME}_img) elseif(SDL1_2_BUILD) - add_custom_target(${SPRITE_NAME}_img ALL - cp ${SPRITE_NAME}.bmp ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME} + if(${SPRITE_TRANSPARENT}) + set(trans "transparent=1") + else() + set(trans "transparent=0") + endif() + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME} + COMMAND add-header ${trans} ${SPRITE_NAME}_24.bmp ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${SPRITE_NAME}.bmp - BYPRODUCTS ${SPRITE_NAME}) - add_dependencies(${PROJECT_NAME} ${SPRITE_NAME}_img) + DEPENDS ${SPRITE_NAME}_24.bmp + VERBATIM) + add_custom_target(${SPRITE_NAME}_img + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SPRITE_NAME}) endif() endfunction() @@ -51,16 +58,20 @@ function(sound) BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}) add_dependencies(iso ${SOUND_NAME}_snd) elseif(SDL1_2_BUILD) - add_custom_target(${SOUND_NAME}_snd ALL - #ffmpeg -y -i ${SOUND_NAME}.wav - # -loglevel error - # -c:a libvorbis - # ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME} - cp ${SOUND_NAME}.wav ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME} + if(${SOUND_LOOP}) + set(loop "loop=1") + else() + set(loop "loop=0") + endif() + + # Reference: https://gist.github.com/socantre/7ee63133a0a3a08f3990 + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME} + COMMAND add-header ${loop} ${SOUND_NAME}.wav ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${SOUND_NAME}.wav - BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}) - add_dependencies(${PROJECT_NAME} ${SOUND_NAME}_snd) + VERBATIM) + add_custom_target(${SOUND_NAME}_snd + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SOUND_NAME}) endif() endfunction() @@ -71,11 +82,15 @@ function(container) cmake_parse_arguments(CONTAINER "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - add_custom_target(${CONTAINER_NAME}_container ALL - container ${CONTAINER_SPRITES} ${CONTAINER_SOUNDS} + add_custom_command(OUTPUT ${cdroot}/${CONTAINER_NAME}.cnt + COMMAND container ${CONTAINER_SPRITES} ${CONTAINER_SOUNDS} ${cdroot}/${CONTAINER_NAME}.cnt WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - BYPRODUCTS ${cdroot}/${CONTAINER_NAME}.cnt) + VERBATIM) + + add_custom_target(${CONTAINER_NAME}_container + DEPENDS ${cdroot}/${CONTAINER_NAME}.cnt) + add_dependencies(${PROJECT_NAME} ${CONTAINER_NAME}_container) foreach(sprite ${CONTAINER_SPRITES}) add_dependencies(${CONTAINER_NAME}_container ${sprite}_img) @@ -168,7 +183,7 @@ sprite(NAME gui_bar_mid BPP 4 CX 368 CY 506 - TRANSPARENT TRUE) + TRANSPARENT FALSE) sprite(NAME gui_bar_right X 376 diff --git a/src/camera/CMakeLists.txt b/src/camera/CMakeLists.txt index fd029b0..3d9d113 100644 --- a/src/camera/CMakeLists.txt +++ b/src/camera/CMakeLists.txt @@ -1,3 +1,3 @@ -add_library(camera "src/camera.c") -target_include_directories(camera PUBLIC "inc") -target_link_libraries(camera PUBLIC container pad util PRIVATE gfx terrain) +add_library(camera "src/camera.c" "src/pad.c" "src/mouse.c") +target_include_directories(camera PUBLIC "inc" PRIVATE "privinc") +target_link_libraries(camera PUBLIC container mouse pad terrain util PRIVATE gfx) diff --git a/src/camera/inc/camera.h b/src/camera/inc/camera.h index 151ea74..ec2739b 100644 --- a/src/camera/inc/camera.h +++ b/src/camera/inc/camera.h @@ -1,6 +1,7 @@ #ifndef CAMERA_H #define CAMERA_H +#include <mouse.h> #include <pad.h> #include <util.h> #include <stdbool.h> @@ -32,7 +33,8 @@ struct camera extern struct sprite cursor_sprite; -void camera_update(struct camera *cam, const struct pad *p); +void camera_update_pad(struct camera *cam, const struct pad *p); +void camera_update_mouse(struct camera *cam, const struct mouse *m); bool camera_translate(const struct camera *cam, const struct util_rect *dim, short *x, short *y); void cursor_init(struct cursor *c); bool cursor_collision(const struct camera *cam, const struct util_rect *d); diff --git a/src/camera/privinc/camera_private.h b/src/camera/privinc/camera_private.h new file mode 100644 index 0000000..f571f2d --- /dev/null +++ b/src/camera/privinc/camera_private.h @@ -0,0 +1,17 @@ +#ifndef CAMERA_PRIVATE_H +#define CAMERA_PRIVATE_H + +#include <camera.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +void camera_update_pos(struct camera *cam); + +#ifdef __cplusplus +} +#endif + +#endif /* CAMERA_PRIVATE_H */ diff --git a/src/camera/src/camera.c b/src/camera/src/camera.c index 4f529df..21c18c7 100644 --- a/src/camera/src/camera.c +++ b/src/camera/src/camera.c @@ -1,5 +1,7 @@ #include <camera.h> +#include <camera_private.h> #include <gfx.h> +#include <mouse.h> #include <pad.h> #include <terrain.h> #include <util.h> @@ -40,37 +42,6 @@ void cursor_pos(const struct camera *const cam, unsigned long *const x, *y = c->y - cam->y; } -static void cursor_update(struct camera *const cam, const struct pad *const p) -{ - struct cursor *const c = &cam->cursor; - enum {STEP = 4}; - - if (c->screen.last_w != screen_w - || c->screen.last_h != screen_h) - cursor_init(c); - - if (pad_pressed(p, PAD_KEY_LEFT) - && (c->x - STEP) - && (!cam->x || c->x != c->x_init)) - c->x -= STEP; - else if (pad_pressed(p, PAD_KEY_RIGHT) - && (c->x + STEP < screen_w) - && (c->x != c->x_init || cam->x <= -MAP_X)) - c->x += STEP; - - if (pad_pressed(p, PAD_KEY_UP) - && (c->y - STEP) - && (c->y != c->y_init || !cam->y)) - c->y -= STEP; - else if (pad_pressed(p, PAD_KEY_DOWN) - && (c->y + STEP < screen_h) - && (c->y != c->y_init || cam->y <= -MAP_Y)) - c->y += STEP; - - c->state = pad_pressed(p, PAD_KEY_A) || pad_pressed(p, PAD_KEY_B) ? - CURSOR_STATE_PRESSED: CURSOR_STATE_IDLE; -} - int cursor_render(const struct cursor *const c) { sprite_get_or_ret(s, -1); @@ -105,69 +76,7 @@ void cursor_init(struct cursor *const c) c->screen.last_h = screen_h; } -static void update_speed(struct camera *const cam, const struct pad *const p) -{ - enum - { - MAX_SPEED = 10, - STEP = 1, - T_STEP = 3 - }; - - const struct cursor *const c = &cam->cursor; - - if (c->x == c->x_init - && (!cam->x_speed || ++cam->xt >= T_STEP)) - { - if (pad_pressed(p, PAD_KEY_RIGHT)) - { - if (cam->x_speed > 0) - cam->x_speed = -STEP; - else if (cam->x_speed - STEP >= -MAX_SPEED) - cam->x_speed -= STEP; - } - else if (pad_pressed(p, PAD_KEY_LEFT)) - { - if (cam->x_speed < 0) - cam->x_speed = STEP; - else if (cam->x_speed + STEP <= MAX_SPEED) - cam->x_speed += STEP; - } - else - cam->x_speed = 0; - - cam->xt = 0; - } - else if (c->x != c->x_init) - cam->x_speed = 0; - - if (c->y == c->y_init - && (!cam->y_speed || ++cam->yt >= T_STEP)) - { - if (pad_pressed(p, PAD_KEY_DOWN)) - { - if (cam->y_speed > 0) - cam->y_speed = STEP; - else if (cam->y_speed - STEP >= -MAX_SPEED) - cam->y_speed -= STEP; - } - else if (pad_pressed(p, PAD_KEY_UP)) - { - if (cam->y_speed < 0) - cam->y_speed = -STEP; - else if (cam->y_speed + STEP <= MAX_SPEED) - cam->y_speed += STEP; - } - else - cam->y_speed = 0; - - cam->yt = 0; - } - else if (c->y != c->y_init) - cam->y_speed = 0; -} - -static void update_pos(struct camera *const cam) +void camera_update_pos(struct camera *const cam) { const int x = cam->x + cam->x_speed; @@ -188,13 +97,6 @@ static void update_pos(struct camera *const cam) cam->y = -MAP_Y; } -void camera_update(struct camera *const cam, const struct pad *const p) -{ - cursor_update(cam, p); - update_speed(cam, p); - update_pos(cam); -} - bool camera_translate(const struct camera *const cam, const struct util_rect *const dim, short *const x, short *const y) { diff --git a/src/camera/src/mouse.c b/src/camera/src/mouse.c new file mode 100644 index 0000000..eff15bf --- /dev/null +++ b/src/camera/src/mouse.c @@ -0,0 +1,37 @@ +#include <camera.h> +#include <camera_private.h> +#include <gfx.h> +#include <mouse.h> +#include <util.h> +#include <stdbool.h> + +static void cursor_update(struct cursor *const c, const struct mouse *const m) +{ + if (c->screen.last_w != screen_w + || c->screen.last_h != screen_h) + cursor_init(c); + + c->x = m->x; + c->y = m->y; +} + +static void update_speed(struct camera *const cam, const struct mouse *const m) +{ + enum + { + MAX_SPEED = 10, + STEP = 1, + T_STEP = 3 + }; + + struct cursor *const c = &cam->cursor; + + +} + +void camera_update_mouse(struct camera *const cam, const struct mouse *const m) +{ + cursor_update(&cam->cursor, m); + update_speed(cam, m); + camera_update_pos(cam); +} diff --git a/src/camera/src/pad.c b/src/camera/src/pad.c new file mode 100644 index 0000000..b445e53 --- /dev/null +++ b/src/camera/src/pad.c @@ -0,0 +1,106 @@ +#include <camera.h> +#include <camera_private.h> +#include <pad.h> +#include <terrain.h> +#include <util.h> +#include <stdbool.h> + +static void cursor_update(struct camera *const cam, const struct pad *const p) +{ + struct cursor *const c = &cam->cursor; + enum {STEP = 4}; + + if (c->screen.last_w != screen_w + || c->screen.last_h != screen_h) + cursor_init(c); + + if (pad_pressed(p, PAD_KEY_LEFT) + && (c->x - STEP) + && (!cam->x || c->x != c->x_init)) + c->x -= STEP; + else if (pad_pressed(p, PAD_KEY_RIGHT) + && (c->x + STEP < screen_w) + && (c->x != c->x_init || cam->x <= -MAP_X)) + c->x += STEP; + + if (pad_pressed(p, PAD_KEY_UP) + && (c->y - STEP) + && (c->y != c->y_init || !cam->y)) + c->y -= STEP; + else if (pad_pressed(p, PAD_KEY_DOWN) + && (c->y + STEP < screen_h) + && (c->y != c->y_init || cam->y <= -MAP_Y)) + c->y += STEP; + + c->state = pad_pressed(p, PAD_KEY_A) || pad_pressed(p, PAD_KEY_B) ? + CURSOR_STATE_PRESSED: CURSOR_STATE_IDLE; +} + +static void update_speed(struct camera *const cam, const struct pad *const p) +{ + enum + { + MAX_SPEED = 10, + STEP = 1, + T_STEP = 3 + }; + + const struct cursor *const c = &cam->cursor; + + if (c->x == c->x_init + && (!cam->x_speed || ++cam->xt >= T_STEP)) + { + if (pad_pressed(p, PAD_KEY_RIGHT)) + { + if (cam->x_speed > 0) + cam->x_speed = -STEP; + else if (cam->x_speed - STEP >= -MAX_SPEED) + cam->x_speed -= STEP; + } + else if (pad_pressed(p, PAD_KEY_LEFT)) + { + if (cam->x_speed < 0) + cam->x_speed = STEP; + else if (cam->x_speed + STEP <= MAX_SPEED) + cam->x_speed += STEP; + } + else + cam->x_speed = 0; + + cam->xt = 0; + } + else if (c->x != c->x_init) + cam->x_speed = 0; + + if (c->y == c->y_init + && (!cam->y_speed || ++cam->yt >= T_STEP)) + { + if (pad_pressed(p, PAD_KEY_DOWN)) + { + if (cam->y_speed > 0) + cam->y_speed = STEP; + else if (cam->y_speed - STEP >= -MAX_SPEED) + cam->y_speed -= STEP; + } + else if (pad_pressed(p, PAD_KEY_UP)) + { + if (cam->y_speed < 0) + cam->y_speed = -STEP; + else if (cam->y_speed + STEP <= MAX_SPEED) + cam->y_speed += STEP; + } + else + cam->y_speed = 0; + + cam->yt = 0; + } + else if (c->y != c->y_init) + cam->y_speed = 0; +} + +void camera_update_pad(struct camera *const cam, const struct pad *const p) +{ + cursor_update(cam, p); + update_speed(cam, p); + camera_update_pos(cam); +} diff --git a/src/game/src/game.c b/src/game/src/game.c index 8907be9..34d79d2 100644 --- a/src/game/src/game.c +++ b/src/game/src/game.c @@ -22,6 +22,7 @@ int game(void) { const struct human_player_cfg cfg = { + .sel_periph = HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE, .padn = i, .pl = { diff --git a/src/gfx/sdl-1.2/inc/gfx/port.h b/src/gfx/sdl-1.2/inc/gfx/port.h index 3dbc23b..add8b8c 100644 --- a/src/gfx/sdl-1.2/inc/gfx/port.h +++ b/src/gfx/sdl-1.2/inc/gfx/port.h @@ -2,6 +2,7 @@ #define GFX_SDL_H #include <SDL/SDL.h> +#include <stdbool.h> #ifdef __cplusplus extern "C" @@ -13,6 +14,7 @@ struct sprite SDL_Surface *s; short x, y, w, h; unsigned char u, v; + bool transparent; }; struct quad @@ -22,6 +24,7 @@ struct quad short y0, y1, y2, y3; unsigned char u0, u1, u2, u3; unsigned char v0, v1, v2, v3; + bool transparent; SDL_Surface *s; }; @@ -29,6 +32,7 @@ struct rect { unsigned char r, g, b; short x, y, w, h; + bool stp; }; struct stp_4line diff --git a/src/keyboard/CMakeLists.txt b/src/keyboard/CMakeLists.txt new file mode 100644 index 0000000..e4c0e8e --- /dev/null +++ b/src/keyboard/CMakeLists.txt @@ -0,0 +1,13 @@ +set(src "src/keyboard.c") +set(inc "inc") + +if(PS1_BUILD) + set(src ${src} "ps1/src/keyboard.c") +elseif(SDL1_2_BUILD) + set(src ${src} "sdl-1.2/src/keyboard.c") + set(deps ${deps} SDL) +endif() + +add_library(keyboard ${src}) +target_include_directories(keyboard PUBLIC ${inc}) +target_link_libraries(keyboard PUBLIC ${deps} PRIVATE ${privdeps}) diff --git a/src/keyboard/inc/keyboard.h b/src/keyboard/inc/keyboard.h new file mode 100644 index 0000000..5c53ba8 --- /dev/null +++ b/src/keyboard/inc/keyboard.h @@ -0,0 +1,38 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include <keyboard_key.h> +#include <stdbool.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define KEYBOARD_COMBO(...) (const struct keyboard_combo){.keys = {__VA_ARGS__}} + +enum {KEYBOARD_MAX_COMBO_KEYS = 3}; + +struct keyboard +{ + struct keyboard_combo + { + enum keyboard_key keys[KEYBOARD_MAX_COMBO_KEYS]; + } combo, oldcombo; + + size_t i; +}; + +void keyboard_init(struct keyboard *k); +void keyboard_update(struct keyboard *k); +bool keyboard_justpressed(const struct keyboard *k, const struct keyboard_combo *c); +bool keyboard_pressed(const struct keyboard *k, const struct keyboard_combo *c); +bool keyboard_justreleased(const struct keyboard *k, const struct keyboard_combo *c); +const char *keyboard_key_str(enum keyboard_key k); + +#ifdef __cplusplus +} +#endif + +#endif /* KEYBOARD_H */ diff --git a/src/keyboard/inc/keyboard_key.h b/src/keyboard/inc/keyboard_key.h new file mode 100644 index 0000000..337a09f --- /dev/null +++ b/src/keyboard/inc/keyboard_key.h @@ -0,0 +1,70 @@ +#ifndef KEYBOARD_KEYS_H +#define KEYBOARD_KEYS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define KEYBOARD_KEYS \ + X(KEYBOARD_KEY_NONE) \ + X(KEYBOARD_KEY_A) \ + X(KEYBOARD_KEY_B) \ + X(KEYBOARD_KEY_C) \ + X(KEYBOARD_KEY_D) \ + X(KEYBOARD_KEY_E) \ + X(KEYBOARD_KEY_F) \ + X(KEYBOARD_KEY_G) \ + X(KEYBOARD_KEY_H) \ + X(KEYBOARD_KEY_I) \ + X(KEYBOARD_KEY_J) \ + X(KEYBOARD_KEY_K) \ + X(KEYBOARD_KEY_L) \ + X(KEYBOARD_KEY_M) \ + X(KEYBOARD_KEY_N) \ + X(KEYBOARD_KEY_O) \ + X(KEYBOARD_KEY_P) \ + X(KEYBOARD_KEY_Q) \ + X(KEYBOARD_KEY_R) \ + X(KEYBOARD_KEY_S) \ + X(KEYBOARD_KEY_T) \ + X(KEYBOARD_KEY_U) \ + X(KEYBOARD_KEY_V) \ + X(KEYBOARD_KEY_W) \ + X(KEYBOARD_KEY_X) \ + X(KEYBOARD_KEY_Y) \ + X(KEYBOARD_KEY_Z) \ + X(KEYBOARD_KEY_0) \ + X(KEYBOARD_KEY_1) \ + X(KEYBOARD_KEY_2) \ + X(KEYBOARD_KEY_3) \ + X(KEYBOARD_KEY_4) \ + X(KEYBOARD_KEY_5) \ + X(KEYBOARD_KEY_6) \ + X(KEYBOARD_KEY_7) \ + X(KEYBOARD_KEY_8) \ + X(KEYBOARD_KEY_9) \ + X(KEYBOARD_KEY_LSHIFT) \ + X(KEYBOARD_KEY_RSHIFT) \ + X(KEYBOARD_KEY_LCTRL) \ + X(KEYBOARD_KEY_RCTRL) \ + X(KEYBOARD_KEY_F11) \ + X(KEYBOARD_KEY_ESC) \ + X(KEYBOARD_KEY_LEFT) \ + X(KEYBOARD_KEY_RIGHT) \ + X(KEYBOARD_KEY_UP) \ + X(KEYBOARD_KEY_DOWN) \ + X(KEYBOARD_KEY_EXIT) + +enum keyboard_key +{ +#define X(x) x, + KEYBOARD_KEYS +#undef X +}; + +#ifdef __cplusplus +} +#endif + +#endif /* KEYBOARD_KEYS_H */ diff --git a/src/keyboard/ps1/src/keyboard.c b/src/keyboard/ps1/src/keyboard.c new file mode 100644 index 0000000..69e7a90 --- /dev/null +++ b/src/keyboard/ps1/src/keyboard.c @@ -0,0 +1,5 @@ +#include <keyboard.h> + +void keyboard_update(struct keyboard *const k) +{ +} diff --git a/src/keyboard/sdl-1.2/src/keyboard.c b/src/keyboard/sdl-1.2/src/keyboard.c new file mode 100644 index 0000000..fafa754 --- /dev/null +++ b/src/keyboard/sdl-1.2/src/keyboard.c @@ -0,0 +1,109 @@ +#include <keyboard.h> +#include <keyboard_key.h> +#include <SDL/SDL.h> +#include <stdio.h> + +static void append_key(const enum keyboard_key key, struct keyboard *const k) +{ + struct keyboard_combo *const c = &k->combo; + + for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) + { + enum keyboard_key *const sel = &c->keys[i]; + + if (*sel == KEYBOARD_KEY_NONE) + { + *sel = key; + break; + } + } +} + +static void remove_key(const enum keyboard_key key, struct keyboard *const k) +{ + struct keyboard_combo *const c = &k->combo; + + for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) + { + enum keyboard_key *const sel = &c->keys[i]; + + if (*sel == key) + *sel = KEYBOARD_KEY_NONE; + } +} + +static void key_event(const SDL_KeyboardEvent *const ev, + struct keyboard *const k) +{ + static const struct keymap + { + enum keyboard_key key; + SDLKey sdl_key; + } keymap[] = + { + {.key = KEYBOARD_KEY_LEFT, .sdl_key = SDLK_LEFT}, + {.key = KEYBOARD_KEY_RIGHT, .sdl_key = SDLK_RIGHT}, + {.key = KEYBOARD_KEY_UP, .sdl_key = SDLK_UP}, + {.key = KEYBOARD_KEY_DOWN, .sdl_key = SDLK_DOWN}, + {.key = KEYBOARD_KEY_LCTRL, .sdl_key = SDLK_LCTRL}, + {.key = KEYBOARD_KEY_RCTRL, .sdl_key = SDLK_RCTRL}, + {.key = KEYBOARD_KEY_LSHIFT, .sdl_key = SDLK_LSHIFT}, + {.key = KEYBOARD_KEY_RSHIFT, .sdl_key = SDLK_RSHIFT}, + {.key = KEYBOARD_KEY_EXIT, .sdl_key = SDLK_ESCAPE}, + {.key = KEYBOARD_KEY_F11, .sdl_key = SDLK_F11}, + {.key = KEYBOARD_KEY_W, .sdl_key = SDLK_w}, + {.key = KEYBOARD_KEY_A, .sdl_key = SDLK_a}, + {.key = KEYBOARD_KEY_S, .sdl_key = SDLK_s}, + {.key = KEYBOARD_KEY_D, .sdl_key = SDLK_d} + }; + + for (size_t i = 0; i < sizeof keymap / sizeof *keymap; i++) + { + const struct keymap *const km = &keymap[i]; + + if (ev->keysym.sym == km->sdl_key) + { + if (ev->state == SDL_PRESSED) + append_key(km->key, k); + else + remove_key(km->key, k); + } + } +} + +void keyboard_update(struct keyboard *const k) +{ + SDL_Event ev; + int n; + + k->oldcombo = k->combo; + + while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT, + SDL_KEYEVENTMASK | SDL_QUITMASK)) > 0) + { + switch (ev.type) + { + case SDL_KEYDOWN: + /* Fall through. */ + case SDL_KEYUP: + key_event(&ev.key, k); + break; + + case SDL_QUIT: + append_key(KEYBOARD_KEY_EXIT, k); + break; + + default: + fprintf(stderr, "%s: unexpected SDL_Event %d\n", + __func__, ev.type); + break; + } + } + + if (n < 0) + { + fprintf(stderr, "%s: SDL_PeepEvents: %s\n", + __func__, SDL_GetError()); + return; + } +} diff --git a/src/keyboard/src/keyboard.c b/src/keyboard/src/keyboard.c new file mode 100644 index 0000000..c247b16 --- /dev/null +++ b/src/keyboard/src/keyboard.c @@ -0,0 +1,69 @@ +#include <keyboard.h> +#include <keyboard_key.h> +#include <stdbool.h> +#include <string.h> + +static bool combo_pressed(const struct keyboard_combo *const ref, + const struct keyboard_combo *const c) +{ + bool ret = false; + + for (size_t i = 0; i < sizeof c->keys / sizeof *c->keys; i++) + { + const enum keyboard_key key = c->keys[i]; + + if (key != KEYBOARD_KEY_NONE) + { + bool success = false; + + for (size_t i = 0; i < sizeof ref->keys / sizeof *ref->keys; i++) + { + if (key == ref->keys[i]) + { + success = true; + break; + } + } + + if (!(ret = success)) + break; + } + } + + return ret; +} + +bool keyboard_pressed(const struct keyboard *const k, + const struct keyboard_combo *const c) +{ + return combo_pressed(&k->combo, c); +} + +bool keyboard_justreleased(const struct keyboard *const k, + const struct keyboard_combo *const c) +{ + return !combo_pressed(&k->combo, c) && combo_pressed(&k->oldcombo, c); +} + +bool keyboard_justpressed(const struct keyboard *const k, + const struct keyboard_combo *const c) +{ + return combo_pressed(&k->combo, c) && !combo_pressed(&k->oldcombo, c); +} + +void keyboard_init(struct keyboard *const k) +{ + memset(k, 0, sizeof *k); +} + +const char *keyboard_key_str(const enum keyboard_key k) +{ + static const char *const s[] = + { +#define X(x) [x] = #x, + KEYBOARD_KEYS +#undef X + }; + + return s[k]; +} diff --git a/src/mouse/CMakeLists.txt b/src/mouse/CMakeLists.txt new file mode 100644 index 0000000..b4814f9 --- /dev/null +++ b/src/mouse/CMakeLists.txt @@ -0,0 +1,13 @@ +set(src "src/mouse.c") +set(inc "inc") + +if(PS1_BUILD) + set(src ${src} "ps1/src/mouse.c") +elseif(SDL1_2_BUILD) + set(src ${src} "sdl-1.2/src/mouse.c") + set(deps ${deps} SDL) +endif() + +add_library(mouse ${src}) +target_include_directories(mouse PUBLIC ${inc}) +target_link_libraries(mouse PUBLIC ${deps} PRIVATE ${privdeps}) diff --git a/src/mouse/inc/mouse.h b/src/mouse/inc/mouse.h new file mode 100644 index 0000000..a4b4044 --- /dev/null +++ b/src/mouse/inc/mouse.h @@ -0,0 +1,32 @@ +#ifndef MOUSE_H +#define MOUSE_H + +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum mouse_button +{ + MOUSE_BUTTON_LEFT, + MOUSE_BUTTON_RIGHT +}; + +struct mouse +{ + short x, y; + int mask, oldmask; +}; + +void mouse_init(struct mouse *m); +void mouse_update(struct mouse *m); +bool mouse_justpressed(const struct mouse *m, enum mouse_button b); +bool mouse_justreleased(const struct mouse *m, enum mouse_button b); + +#ifdef __cplusplus +} +#endif + +#endif /* MOUSE_H */ diff --git a/src/mouse/ps1/src/mouse.c b/src/mouse/ps1/src/mouse.c new file mode 100644 index 0000000..78ea425 --- /dev/null +++ b/src/mouse/ps1/src/mouse.c @@ -0,0 +1,9 @@ +#include <mouse.h> + +void mouse_update(struct mouse *const m) +{ +} + +void mouse_init(struct mouse *const m) +{ +} diff --git a/src/mouse/sdl-1.2/src/mouse.c b/src/mouse/sdl-1.2/src/mouse.c new file mode 100644 index 0000000..381ac0e --- /dev/null +++ b/src/mouse/sdl-1.2/src/mouse.c @@ -0,0 +1,80 @@ +#include <mouse.h> +#include <SDL/SDL.h> +#include <stdint.h> +#include <inttypes.h> +#include <stdio.h> +#include <string.h> + +static void mouse_click(const SDL_MouseButtonEvent *const ev, + struct mouse *const m) +{ + int mask; + + switch (ev->button) + { + case 1: + mask = 1 << MOUSE_BUTTON_LEFT; + break; + + case 3: + mask = 1 << MOUSE_BUTTON_RIGHT; + break; + + default: + return; + } + + if (ev->state == SDL_PRESSED) + m->mask |= mask; + else + m->mask &= ~mask; +} + +static void mouse_event(const SDL_MouseMotionEvent *const ev, + struct mouse *const m) +{ + m->x = ev->x; + m->y = ev->y; +} + +void mouse_update(struct mouse *const m) +{ + SDL_Event ev; + int n; + + m->oldmask = m->mask; + + while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK + | SDL_MOUSEBUTTONDOWNMASK | SDL_MOUSEBUTTONUPMASK)) > 0) + { + switch (ev.type) + { + case SDL_MOUSEBUTTONDOWN: + /* Fall through. */ + case SDL_MOUSEBUTTONUP: + mouse_click(&ev.button, m); + break; + + case SDL_MOUSEMOTION: + mouse_event(&ev.motion, m); + break; + + default: + fprintf(stderr, "%s: unexpected SDL_Event %d\n", + __func__, ev.type); + break; + } + } + + if (n < 0) + { + fprintf(stderr, "%s: SDL_PeepEvents: %s\n", + __func__, SDL_GetError()); + return; + } +} + +void mouse_init(struct mouse *const m) +{ + memset(m, 0, sizeof *m); +} diff --git a/src/mouse/src/mouse.c b/src/mouse/src/mouse.c new file mode 100644 index 0000000..5f5c059 --- /dev/null +++ b/src/mouse/src/mouse.c @@ -0,0 +1,14 @@ +#include <mouse.h> +#include <stdbool.h> + +bool mouse_justpressed(const struct mouse *const m, + const enum mouse_button b) +{ + return m->mask & (1 << b) && !(m->oldmask & (1 << b)); +} + +bool mouse_justreleased(const struct mouse *const m, + const enum mouse_button b) +{ + return !(m->mask & (1 << b)) && m->oldmask & (1 << b); +} diff --git a/src/pad/CMakeLists.txt b/src/pad/CMakeLists.txt index 4862c2b..e4aee5b 100644 --- a/src/pad/CMakeLists.txt +++ b/src/pad/CMakeLists.txt @@ -1,10 +1,15 @@ -add_library(pad "src/pad.c") -target_include_directories(pad PUBLIC "inc" PRIVATE "privinc") +set(inc "inc") +set(privinc "privinc") +set(src "src/pad.c") if(PS1_BUILD) - target_include_directories(pad PUBLIC "ps1/inc") - target_sources(pad PRIVATE "ps1/src/pad.c") + set(src ${src} "ps1/src/pad.c") + set(inc ${inc} "ps1/inc") elseif(SDL1_2_BUILD) - target_include_directories(pad PUBLIC "sdl-1.2/inc") - target_sources(pad PRIVATE "sdl-1.2/src/pad.c") + set(src ${src} "sdl-1.2/src/pad.c") + set(inc ${inc} "sdl-1.2/inc") + set(deps ${deps} SDL) endif() + +add_library(pad ${src}) +target_include_directories(pad PUBLIC ${inc} PRIVATE ${privinc}) diff --git a/src/pad/inc/pad.h b/src/pad/inc/pad.h index 2579c84..c8f6b31 100644 --- a/src/pad/inc/pad.h +++ b/src/pad/inc/pad.h @@ -19,13 +19,17 @@ extern "C" X(PAD_KEY_C) \ X(PAD_KEY_D) \ X(PAD_KEY_E) \ - X(PAD_KEY_OPTIONS) + X(PAD_KEY_OPTIONS) \ + X(PAD_KEY_FULL_SCREEN) \ + X(PAD_KEY_EXIT) enum pad_key { #define X(x) x, PAD_KEYS #undef X + + MAX_PAD_KEYS }; struct pad diff --git a/src/pad/sdl-1.2/inc/pad/port.h b/src/pad/sdl-1.2/inc/pad/port.h index b6ae85a..8334b6a 100644 --- a/src/pad/sdl-1.2/inc/pad/port.h +++ b/src/pad/sdl-1.2/inc/pad/port.h @@ -1,8 +1,6 @@ #ifndef PAD_SDL_1_2_H #define PAD_SDL_1_2_H -#include <stdbool.h> - #ifdef __cplusplus extern "C" { @@ -10,7 +8,7 @@ extern "C" struct pad_port { - bool exit; + int dummy; }; #ifdef __cplusplus diff --git a/src/pad/sdl-1.2/src/pad.c b/src/pad/sdl-1.2/src/pad.c index a062758..f6a96c1 100644 --- a/src/pad/sdl-1.2/src/pad.c +++ b/src/pad/sdl-1.2/src/pad.c @@ -2,77 +2,8 @@ #include <SDL/SDL.h> #include <stdio.h> -static void key_event(const SDL_KeyboardEvent *const key, struct pad *const p) -{ - static const int keys[] = - { - [PAD_KEY_LEFT] = SDLK_LEFT, - [PAD_KEY_RIGHT] = SDLK_RIGHT, - [PAD_KEY_UP] = SDLK_UP, - [PAD_KEY_DOWN] = SDLK_DOWN, - [PAD_KEY_A] = SDLK_x, - [PAD_KEY_B] = SDLK_d, - [PAD_KEY_C] = SDLK_w, - [PAD_KEY_D] = SDLK_a, - [PAD_KEY_E] = SDLK_q, - [PAD_KEY_OPTIONS] = SDLK_ESCAPE - }; - - for (size_t i = 0; i < sizeof keys / sizeof *keys; i++) - { - const SDLKey k = key->keysym.sym; - - if (k == keys[i]) - { - const int mask = 1 << i; - - if (key->type == SDL_KEYDOWN) - { - printf("%s pressed\n", pad_str(i)); - p->mask |= mask; - } - else - { - printf("%s released\n", pad_str(i)); - p->mask &= ~mask; - } - } - } -} - void pad_port_update(struct pad *const p) { - SDL_Event ev; - static const int masks[] = {SDL_KEYEVENTMASK}; - int n; - - while ((n = SDL_PeepEvents(&ev, 1, SDL_GETEVENT, - masks[p->player] | SDL_QUITMASK)) > 0) - { - switch (ev.type) - { - case SDL_KEYDOWN: - /* Fall through. */ - case SDL_KEYUP: - key_event(&ev.key, p); - break; - - case SDL_QUIT: - p->port.exit = true; - break; - - default: - fprintf(stderr, "%s: unexpected SDL_Event %d\n", - __func__, ev.type); - break; - } - } - - if (n < 0) - { - fprintf(stderr, "%s: SDL_PeepEvents: %s\n", __func__, SDL_GetError()); - return; - } } void pad_init(const int player, struct pad *const p) diff --git a/src/player/CMakeLists.txt b/src/player/CMakeLists.txt index d7a275d..6d692fe 100644 --- a/src/player/CMakeLists.txt +++ b/src/player/CMakeLists.txt @@ -5,7 +5,9 @@ target_link_libraries(player building camera gfx + keyboard instance + mouse pad resource tech diff --git a/src/player/inc/human_player.h b/src/player/inc/human_player.h index 6d97cf7..b2a07ee 100644 --- a/src/player/inc/human_player.h +++ b/src/player/inc/human_player.h @@ -2,7 +2,9 @@ #define HUMAN_PLAYER_H #include <camera.h> +#include <keyboard.h> #include <instance.h> +#include <mouse.h> #include <pad.h> #include <player.h> #include <stdbool.h> @@ -15,11 +17,34 @@ extern "C" enum {MAX_SELECTED_INSTANCES = 4}; +struct human_player_cfg +{ + enum human_player_periph + { + HUMAN_PLAYER_PERIPH_PAD, + HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE + } sel_periph; + + struct player_cfg pl; + int padn; +}; + struct human_player { struct player pl; struct camera cam; - struct pad pad; + enum human_player_periph sel_periph; + + union + { + struct pad pad; + + struct + { + struct mouse mouse; + struct keyboard keyboard; + } kbm; + } periph; struct sel_instance { @@ -52,12 +77,6 @@ struct human_player unsigned long gui_res[MAX_RESOURCE_TYPES]; }; -struct human_player_cfg -{ - struct player_cfg pl; - int padn; -}; - int human_player_init(const struct human_player_cfg *cfg, struct human_player *h); bool human_player_update(struct human_player *h, struct player_others *o); int human_player_render(const struct human_player *h, const struct player_others *o); diff --git a/src/player/src/human_player.c b/src/player/src/human_player.c index 7fd558a..b45e24f 100644 --- a/src/player/src/human_player.c +++ b/src/player/src/human_player.c @@ -2,8 +2,10 @@ #include <player.h> #include <building.h> #include <camera.h> +#include <gfx.h> #include <gui.h> #include <instance.h> +#include <keyboard.h> #include <pad.h> #include <resource.h> #include <unit.h> @@ -29,7 +31,7 @@ static bool instance_selected(const struct human_player *const h, } static bool select_units(struct human_player *const h, const short x, - const short y) + const short y, const bool excl) { struct player *const pl = &h->pl; @@ -50,19 +52,37 @@ static bool select_units(struct human_player *const h, const short x, && cursor_collision(&h->cam, &in->r) && h->n_sel < sizeof h->sel / sizeof *h->sel) { - for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++) - { - struct sel_instance *const sel = &h->sel[i]; + struct sel_instance *sel = NULL; - if (!sel->d.u) + if (excl) + { + sel = h->sel; + h->n_sel = 1; + } + else + { + for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++) { - sel->type = INSTANCE_TYPE_UNIT; - sel->d.u = u; - h->n_sel++; - sfx_play(&unit_sounds[UNIT_SOUND_SELECTED]); - return true; + struct sel_instance *const s = &h->sel[i]; + + if (!s->d.u) + { + sel = s; + h->n_sel++; + break; + } } } + + if (sel) + { + sel->type = INSTANCE_TYPE_UNIT; + sel->d.u = u; + sfx_play(&unit_sounds[UNIT_SOUND_SELECTED]); + return true; + } + + return false; } } break; @@ -79,7 +99,7 @@ static bool select_units(struct human_player *const h, const short x, } static bool select_buildings(struct human_player *const h, const short x, - const short y) + const short y, const bool excl) { struct player *const pl = &h->pl; @@ -96,18 +116,36 @@ static bool select_buildings(struct human_player *const h, const short x, && cursor_collision(&h->cam, &in->r) && h->n_sel < sizeof h->sel / sizeof *h->sel) { - for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++) - { - struct sel_instance *const sel = &h->sel[i]; + struct sel_instance *sel = NULL; - if (!sel->d.b) + if (excl) + { + sel = h->sel; + h->n_sel = 1; + } + else + { + for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++) { - sel->type = INSTANCE_TYPE_BUILDING; - sel->d.b = b; - h->n_sel++; - return true; + struct sel_instance *const s = &h->sel[i]; + + if (!s->d.b) + { + sel = s; + h->n_sel++; + break; + } } } + + if (sel) + { + sel->type = INSTANCE_TYPE_BUILDING; + sel->d.b = b; + return true; + } + + return false; } } } @@ -116,7 +154,7 @@ static bool select_buildings(struct human_player *const h, const short x, } static bool select_resources(struct human_player *const h, const short x, - const short y, const struct player_others *const o) + const short y, const struct player_others *const o, const bool excl) { for (size_t i = 0; i < o->n_res; i++) { @@ -131,18 +169,36 @@ static bool select_resources(struct human_player *const h, const short x, && cursor_collision(&h->cam, &in->r) && h->n_sel < sizeof h->sel / sizeof *h->sel) { - for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++) - { - struct sel_instance *const sel = &h->sel[i]; + struct sel_instance *sel = NULL; - if (!sel->d.r) + if (excl) + { + sel = h->sel; + h->n_sel = 1; + } + else + { + for (size_t i = 0; i < sizeof h->sel / sizeof *h->sel; i++) { - sel->type = INSTANCE_TYPE_RESOURCE; - sel->d.r = r; - h->n_sel++; - return true; + struct sel_instance *const s = &h->sel[i]; + + if (!s->d.r) + { + sel = s; + h->n_sel++; + break; + } } } + + if (sel) + { + sel->type = INSTANCE_TYPE_RESOURCE; + sel->d.r = r; + return true; + } + + return false; } } } @@ -150,16 +206,16 @@ static bool select_resources(struct human_player *const h, const short x, return false; } -static void select_instances(struct human_player *const h, - const struct player_others *const o) +static bool select_instances(struct human_player *const h, + const struct player_others *const o, const bool excl) { unsigned long x, y; cursor_pos(&h->cam, &x, &y); - if (!select_buildings(h, x, y) - && !select_units(h, x, y)) - select_resources(h, x, y, o); + return select_buildings(h, x, y, excl) + || select_units(h, x, y, excl) + || select_resources(h, x, y, o, excl); } static bool instance_collision(const struct camera *const cam, @@ -450,6 +506,58 @@ static void update_target(struct human_player *const h) } } +static bool update_from_pad(struct human_player *const h, + struct player_others *const o) +{ + bool ret = false; + struct pad *const p = &h->periph.pad; + + pad_update(p); + + if (pad_justpressed(p, PAD_KEY_OPTIONS) + || pad_justpressed(p, PAD_KEY_EXIT)) + ret = true; + else if (pad_justpressed(p, PAD_KEY_A)) + select_instances(h, o, false); + else if (pad_justpressed(p, PAD_KEY_B)) + move_units(h, o); + else if (pad_justpressed(p, PAD_KEY_C)) + deselect_instances(h); + else if (pad_justpressed(p, PAD_KEY_E)) + h->top_gui ^= true; + + return ret; +} + +static bool update_from_keyboard_mouse(struct human_player *const h, + struct player_others *const o) +{ + bool ret = false; + struct mouse *const m = &h->periph.kbm.mouse; + struct keyboard *const k = &h->periph.kbm.keyboard; + + mouse_update(m); + keyboard_update(k); + + if (mouse_justreleased(m, MOUSE_BUTTON_LEFT)) + { + const bool shift_pressed = + keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_LSHIFT)) + || keyboard_pressed(k, &KEYBOARD_COMBO(KEYBOARD_KEY_RSHIFT)); + + if (!select_instances(h, o, !shift_pressed)) + deselect_instances(h); + } + else if (mouse_justreleased(m, MOUSE_BUTTON_RIGHT)) + move_units(h, o); + else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_EXIT))) + ret = true; + else if (keyboard_justreleased(k, &KEYBOARD_COMBO(KEYBOARD_KEY_F11))) + gfx_toggle_fullscreen(); + + return ret; +} + bool human_player_update(struct human_player *const h, struct player_others *const o) { @@ -459,22 +567,22 @@ bool human_player_update(struct human_player *const h, if (p->alive) { gui_update(h); - pad_update(&h->pad); update_selected(h); update_target(h); - if (pad_justpressed(&h->pad, PAD_KEY_OPTIONS)) - ret = true; - else if (pad_justpressed(&h->pad, PAD_KEY_A)) - select_instances(h, o); - else if (pad_justpressed(&h->pad, PAD_KEY_B)) - move_units(h, o); - else if (pad_justpressed(&h->pad, PAD_KEY_C)) - deselect_instances(h); - else if (pad_justpressed(&h->pad, PAD_KEY_E)) - h->top_gui ^= true; + switch (h->sel_periph) + { + case HUMAN_PLAYER_PERIPH_PAD: + ret = update_from_pad(h, o); + camera_update_pad(&h->cam, &h->periph.pad); + break; + + case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE: + ret = update_from_keyboard_mouse(h, o); + camera_update_mouse(&h->cam, &h->periph.kbm.mouse); + break; + } - camera_update(&h->cam, &h->pad); player_update(p); } @@ -562,7 +670,18 @@ int human_player_init(const struct human_player_cfg *const cfg, if (player_init(&cfg->pl, &h->pl)) return -1; - pad_init(cfg->padn, &h->pad); + switch (h->sel_periph = cfg->sel_periph) + { + case HUMAN_PLAYER_PERIPH_KEYBOARD_MOUSE: + mouse_init(&h->periph.kbm.mouse); + keyboard_init(&h->periph.kbm.keyboard); + break; + + case HUMAN_PLAYER_PERIPH_PAD: + pad_init(cfg->padn, &h->periph.pad); + break; + } + cursor_init(&h->cam.cursor); h->top_gui = true; memmove(h->gui_res, h->pl.resources, sizeof h->gui_res); |
