diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2021-07-03 00:49:03 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-30 08:20:20 +0200 |
| commit | 6b9f686913efc3725b2690033cd4f398e07076ba (patch) | |
| tree | e9aa91a6b9f617d78123ebe7ad272fc42a60d306 /src/camera | |
| parent | c9e6ae44a9aeb89b3f48f3443d6baa80103f7445 (diff) | |
| download | jancity-6b9f686913efc3725b2690033cd4f398e07076ba.tar.gz | |
Add project source code
Diffstat (limited to 'src/camera')
| -rw-r--r-- | src/camera/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/camera/inc/camera.h | 42 | ||||
| -rw-r--r-- | src/camera/src/camera.c | 203 |
3 files changed, 248 insertions, 0 deletions
diff --git a/src/camera/CMakeLists.txt b/src/camera/CMakeLists.txt new file mode 100644 index 0000000..fd029b0 --- /dev/null +++ b/src/camera/CMakeLists.txt @@ -0,0 +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) diff --git a/src/camera/inc/camera.h b/src/camera/inc/camera.h new file mode 100644 index 0000000..1daebd2 --- /dev/null +++ b/src/camera/inc/camera.h @@ -0,0 +1,42 @@ +#ifndef CAMERA_H +#define CAMERA_H + +#include <pad.h> +#include <util.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct camera +{ + int x, y, x_speed, y_speed; + unsigned int xt, yt; + + struct cursor + { + unsigned int x, y, x_init, y_init; + enum + { + CURSOR_STATE_IDLE, + CURSOR_STATE_PRESSED + } state; + } cursor; +}; + +extern struct sprite cursor_sprite; + +void camera_update(struct camera *cam, const struct pad *p); +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); +void cursor_pos(const struct camera *cam, unsigned long *x, unsigned long *y); +int cursor_render(const struct cursor *c); + +#ifdef __cplusplus +} +#endif + +#endif /* CAMERA_H */ diff --git a/src/camera/src/camera.c b/src/camera/src/camera.c new file mode 100644 index 0000000..4b046e1 --- /dev/null +++ b/src/camera/src/camera.c @@ -0,0 +1,203 @@ +#include <camera.h> +#include <gfx.h> +#include <pad.h> +#include <terrain.h> +#include <util.h> +#include <limits.h> +#include <stdbool.h> + +struct sprite cursor_sprite; + +enum +{ + CURSOR_WIDTH = 20, + CURSOR_HEIGHT = 20 +}; + +bool cursor_collision(const struct camera *const cam, const struct util_rect *const d) +{ + unsigned long x, y; + + cursor_pos(cam, &x, &y); + + const struct util_rect cd = + { + .x = x, + .y = y, + .w = CURSOR_WIDTH / 4, + .h = CURSOR_HEIGHT / 4 + }; + + return util_collision(d, &cd); +} + +void cursor_pos(const struct camera *const cam, unsigned long *const x, + unsigned long *const y) +{ + const struct cursor *const c = &cam->cursor; + + *x = c->x - cam->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 (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) +{ + struct sprite *const s = sprite_get(); + + if (!s || sprite_clone(&cursor_sprite, s)) + return -1; + + s->x = c->x; + s->y = c->y; + s->w = CURSOR_WIDTH; + s->h = CURSOR_HEIGHT; + + switch (c->state) + { + case CURSOR_STATE_IDLE: + s->u += CURSOR_WIDTH; + break; + + case CURSOR_STATE_PRESSED: + break; + } + + sprite_sort(s); + return 0; +} + +void cursor_init(struct cursor *const c) +{ + c->x = c->x_init = (screen_w / 2) - CURSOR_WIDTH; + c->y = c->y_init = (screen_h / 2) - CURSOR_HEIGHT; +} + +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) +{ + const int x = cam->x + cam->x_speed; + + cam->x = x; + + if (cam->x > 0) + cam->x = 0; + else if (cam->x < -MAP_X) + cam->x = -MAP_X; + + const int y = cam->y + cam->y_speed; + + cam->y = y; + + if (cam->y > 0) + cam->y = 0; + else if (cam->y < -MAP_Y) + 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) +{ + const long tx = dim->x + cam->x, ty = dim->y + cam->y; + + if (!gfx_inside_drawenv(tx, ty, dim->w, dim->h)) + return false; + + *x = tx; + *y = ty; + return true; +} |
