aboutsummaryrefslogtreecommitdiff
path: root/src/player.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-06-18 00:08:28 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-06-18 00:08:28 +0100
commitb50f8d403e36137d6f8dccd847efd4e220f2c505 (patch)
tree86707ad45c51484d07c62243a0906e3fe8ed7cc7 /src/player.c
parent4c1f33184f1cba5006b4da8bbe2a161cd971aabc (diff)
downloadgold-mine-run-b50f8d403e36137d6f8dccd847efd4e220f2c505.tar.gz
gold-mine-run-b50f8d403e36137d6f8dccd847efd4e220f2c505.zip
Enter the player!
Diffstat (limited to 'src/player.c')
-rw-r--r--src/player.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/player.c b/src/player.c
new file mode 100644
index 0000000..b0960bc
--- /dev/null
+++ b/src/player.c
@@ -0,0 +1,206 @@
+#include <stdint.h>
+
+#include "keyb.h"
+#include "vga.h"
+#include "map.h"
+#include "data.h"
+
+#include "player.h"
+
+#define DIR_RIGHT 0
+#define DIR_LEFT 1
+
+#define FRAME_STANDING 0
+#define FRAME_JUMPING 4
+#define FRAME_DYING 5
+
+#define WALK_CYCLE_FRAMES 4
+#define WALK_DELAY 8
+
+#define GRAVITY_OFF 0
+/* XXX: subtract 1 to get the value from gravity_seq */
+#define GRAVITY_DOWN 14
+#define GRAVITY_UP 1
+
+#define GRAVITY_SEQ_LEN 24
+
+#define IS_GOING_DOWN(x) ((x)>=GRAVITY_DOWN)
+
+static uint16_t x, y;
+static uint8_t dir, frame, delay, gravity, jump;
+
+const uint8_t gravity_seq[GRAVITY_SEQ_LEN] = {
+ 6, 4, 4, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4
+};
+
+static uint8_t bg[256];
+
+static const Rect frames[2][6] =
+{
+ {
+ /* walk cycle */
+ { 0, 0, 144, 144 },
+ { 16, 0, 144, 144 },
+ { 0, 0, 144, 144 },
+ { 32, 0, 144, 144 },
+
+ /* jump */
+ { 48, 0, 144, 144 },
+
+ /* dying */
+ { 128, 0, 144, 144 },
+ },
+ {
+ /* walk cycle */
+ { 64, 0, 144, 144 },
+ { 80, 0, 144, 144 },
+ { 64, 0, 144, 144 },
+ { 96, 0, 144, 144 },
+
+ /* jump */
+ { 112, 0, 144, 144 },
+
+ /* dying */
+ { 128, 0, 144, 144 },
+ },
+};
+
+void player_init(uint16_t start_x, uint8_t start_y)
+{
+ dir = DIR_RIGHT;
+ frame = FRAME_STANDING;
+ delay = 0;
+ jump = 0;
+
+ x = start_x;
+ y = start_y;
+ gravity = GRAVITY_OFF;
+}
+
+void player_update()
+{
+ uint8_t moved = 0;
+
+ if (gravity == GRAVITY_OFF
+ && !map_is_blocked(x + 4, y + 16)
+ && !map_is_blocked(x + 11, y + 16))
+ {
+ gravity = GRAVITY_DOWN;
+ frame = FRAME_JUMPING;
+ moved = 1;
+ }
+
+ if (keys[KEY_UP])
+ {
+ if (gravity == GRAVITY_OFF && !jump)
+ {
+ jump = 1;
+ frame = FRAME_JUMPING;
+ gravity = GRAVITY_UP;
+ }
+ }
+ else
+ jump = 0;
+
+ if (keys[KEY_RIGHT] && !keys[KEY_LEFT])
+ {
+ moved = 1;
+ dir = DIR_RIGHT;
+
+ /* XXX: off limits */
+ if (x < MAP_W * MAP_TILE_W - 16)
+ {
+ if ((IS_GOING_DOWN(gravity) && !map_is_blocked(x + 16, y + 15))
+ || (!IS_GOING_DOWN(gravity)
+ && !(map_is_blocked(x + 16, y + 15)
+ && map_is_blocked(x + 16, y + 7))))
+ x++;
+ }
+ }
+
+ if (keys[KEY_LEFT] && !keys[KEY_RIGHT])
+ {
+ moved = 1;
+ dir = DIR_LEFT;
+
+ /* XXX: off limits */
+ if (x)
+ {
+ if ((IS_GOING_DOWN(gravity) && !map_is_blocked(x - 1, y + 15))
+ || (!IS_GOING_DOWN(gravity)
+ && !(map_is_blocked(x - 1, y + 15)
+ && map_is_blocked(x - 1, y + 7))))
+ x--;
+ }
+ }
+
+ if (gravity != GRAVITY_OFF)
+ {
+ uint8_t steps = gravity_seq[gravity - 1];
+
+ moved = 1;
+
+ if (gravity > GRAVITY_DOWN)
+ {
+ /* going down! */
+ for (uint8_t i = 0; i < steps; i++)
+ {
+ /* hit the floor */
+ if ((map_is_blocked(x + 11, y + 16)
+ || map_is_blocked(x + 4, y + 16))
+ && !map_is_blocked(x + 4, y + 15)
+ && !map_is_blocked(x + 11, y + 15))
+ {
+ gravity = GRAVITY_OFF;
+ frame = FRAME_STANDING;
+ break;
+ }
+ y++;
+ }
+ }
+ else
+ {
+ /* going up! */
+ if (y < steps)
+ y = 0;
+ else
+ y -= steps;
+ }
+
+ if (gravity != GRAVITY_OFF && gravity != GRAVITY_SEQ_LEN)
+ gravity++;
+ }
+
+ if (moved)
+ {
+ if (delay++ == WALK_DELAY)
+ {
+ delay = 0;
+ if (frame != FRAME_JUMPING)
+ {
+ frame++;
+ if (frame == WALK_CYCLE_FRAMES)
+ frame = FRAME_STANDING;
+ }
+ }
+ }
+ else
+ {
+ delay = 0;
+ frame = FRAME_STANDING;
+ }
+}
+
+void player_erase()
+{
+ Rect dst = { x, y + MAP_OFFS_Y, 16, 16 };
+ blit(bg, &dst);
+}
+
+void player_draw()
+{
+ Rect dst = { x, y + MAP_OFFS_Y, 16, 16 };
+
+ read_buffer(bg, &dst);
+ blitrc(binary_sprites_start, &frames[dir][frame], &dst);
+}