Browse Source

Begin adding player code

master
Forest Belton 2 years ago
parent
commit
d9e05dbe67
8 changed files with 134 additions and 2 deletions
  1. BIN
      assets/player-stand.png
  2. +12
    -0
      src/actor.c
  3. +7
    -1
      src/actor.h
  4. +45
    -0
      src/collision.c
  5. +7
    -1
      src/game.h
  6. +3
    -0
      src/level.c
  7. +52
    -0
      src/player.c
  8. +8
    -0
      src/player.h

BIN
assets/player-stand.png View File

Before After
Width: 16  |  Height: 32  |  Size: 191 B

+ 12
- 0
src/actor.c View File

@ -2,6 +2,7 @@
#include <stddef.h>
#include "player.h"
#include "sdk/oam.h"
#include "util.h"
@ -10,6 +11,7 @@
#define NUM_OAM_ENTRIES 40
#define TILE_WIDTH 8
#define FRAMES_PER_ANIM_FRAME 20
#define PLAYER_ACTOR_IDX 0
static actor_anim_state_t ANIM_TOTAL_FRAMES[] = {2};
@ -20,6 +22,16 @@ static actor_t all_actors[MAX_ACTORS];
static uint8_t actor_load_mob_anim_data(uint8_t mob_id);
actor_t *PLAYER_ACTOR = &all_actors[PLAYER_ACTOR_IDX];
void actor_init(void) {
actor_reset();
PLAYER_ACTOR->active = 1;
PLAYER_ACTOR->x = PLAYER.x;
PLAYER_ACTOR->y = PLAYER.y;
}
void actor_reset(void) {
for (uint8_t i = 0; i < ARRSIZE(mob_ids); ++i) {
mob_ids[i] = 0xff;

+ 7
- 1
src/actor.h View File

@ -5,6 +5,11 @@
#include "mob.h"
typedef enum {
DIR_LEFT,
DIR_RIGHT,
} actor_dir_t;
typedef enum {
ANIM_STAND,
ANIM_WALK,
@ -16,7 +21,6 @@ typedef enum {
typedef struct {
uint8_t active;
uint8_t dirty;
uint8_t mob_anim_idx;
actor_anim_state_t anim;
uint8_t frame_idx;
@ -65,4 +69,6 @@ void actor_update(void);
*/
void actor_flush_oam(void);
extern actor_t *PLAYER_ACTOR;
#endif

+ 45
- 0
src/collision.c View File

@ -0,0 +1,45 @@
#include "game.h"
#include "map.h"
#include "player.h"
typedef enum {
COLLF_WALK = (1 << 0),
COLLF_LADDER = (1 << 1),
COLLF_PORTAL = (1 << 2),
} coll_state_t;
uint8_t can_move_to(uint8_t x, uint8_t y) {
const uint8_t coll = ((uint8_t*)MAP.collision_ptr)[y * MAP.map_width + x];
return coll & COLLF_WALK;
}
uint8_t get_tile_coord(uint8_t pixel_coord) {
uint8_t offset = 0;
if (pixel_coord & 0x7) {
offset = 8;
}
return (pixel_coord + offset) >> 3;
}
uint8_t player_bg_collides(void) {
const int8_t map_x = PLAYER.x / 8 + MAP.camera_x;
if (map_x < 0 || map_x >= MAP.map_width) {
return 1;
}
const int8_t map_y = PLAYER.y / 8 + MAP.camera_y;
if (map_y < 0 || map_y >= MAP.map_height) {
return 1;
}
return !(can_move_to(map_x, map_y) && can_move_to(map_x + 1, map_y) &&
can_move_to(map_x, map_y + 1) &&
can_move_to(map_x + 1, map_y + 1));
}
uint8_t player_in_air(void) {
const uint8_t x = get_tile_coord(PLAYER.x) + MAP.camera_x;
const uint8_t y = get_tile_coord(PLAYER.y) + MAP.camera_y;
return can_move_to(x, y + 2) && can_move_to(x + 1, y + 2);
}

+ 7
- 1
src/game.h View File

@ -38,7 +38,9 @@
(ALLOC_SIZE_FONT + ALLOC_SIZE_PLAYER + ALLOC_SIZE_BACKGROUND + \
ALLOC_SIZE_ITEMS)
#define TILE_SIZE 16 //!< Size of 1 tile in bytes
#define TILE_WIDTH 8 //!< Width of 1 tile in pixels
#define TILE_HEIGHT 8 //!< Height of 1 tile in pixels
#define TILE_SIZE 16 //!< Size of 1 tile in bytes
#define VRAM_TILE_PTR(idx) \
((void*)(_VRAM + \
(idx)*TILE_SIZE)) //!< Compute VRAM pointer for tile section
@ -74,4 +76,8 @@ void interrupts_disable(void) __preserves_regs(a, b, c, d, e, h, l);
#define lcd_disable() lcd_off()
#define lcd_enable() rLCDC = LCDC_ON | LCDC_OBJON | LCDC_BGON | LCDC_BG8000
uint8_t player_bg_collides(void);
uint8_t player_in_air(void);
#endif

+ 3
- 0
src/level.c View File

@ -1,6 +1,7 @@
#include "game.h"
#include "intro.h"
#include "map.h"
#include "player.h"
#include "sdk/hardware.h"
#include "sdk/joypad.h"
#include "sdk/video.h"
@ -13,6 +14,8 @@ void level(void) {
while (1) {
joypad_update();
player_update();
actor_flush_oam();
HALT();
rIF = 0;

+ 52
- 0
src/player.c View File

@ -1,3 +1,55 @@
#include "player.h"
#include "actor.h"
#include "game.h"
#include "sdk/joypad.h"
#define PLAYER_SPEED 2
#define GRAVITY 0x002e //!< 0.18
#define PLAYER_INIT_JUMP_VY 0x0399 //!< 3.6
#define PLAYER_INIT_FALL_VY 0xff1a //!< -1.1015625
#define MAX_VY 0xf900 //!< -7.0
player_t PLAYER;
void player_update(void) {
if ((joypad_pressed & PAD_UP) && PLAYER.state != PLAYER_STATE_JUMP) {
PLAYER.state = PLAYER_STATE_JUMP;
PLAYER.vy = PLAYER_INIT_JUMP_VY;
}
if (PLAYER.state == PLAYER_STATE_JUMP) {
PLAYER.vy -= GRAVITY;
PLAYER.y -= PLAYER.vy;
if (player_bg_collides()) {
PLAYER.y += PLAYER.vy;
if (PLAYER.vy & (1 << 15)) {
PLAYER.state = PLAYER_STATE_WALK;
}
PLAYER.vy = 0;
}
}
if ((joypad_state & PAD_RIGHT) && PLAYER.x + TILE_WIDTH * 2 > SCRN_X) {
PLAYER.dir = DIR_RIGHT;
PLAYER.x += PLAYER_SPEED;
if (player_bg_collides()) {
PLAYER.x -= PLAYER_SPEED;
}
} else if ((joypad_state & PAD_LEFT) && PLAYER.x > 0) {
PLAYER.dir = DIR_LEFT;
PLAYER.x -= PLAYER_SPEED;
if (player_bg_collides()) {
PLAYER.x += PLAYER_SPEED;
}
}
if (player_in_air() && PLAYER.state != PLAYER_STATE_JUMP) {
PLAYER.state = PLAYER_STATE_JUMP;
PLAYER.vy = PLAYER_INIT_FALL_VY;
}
PLAYER_ACTOR->x = PLAYER.x;
PLAYER_ACTOR->y = PLAYER.y;
}

+ 8
- 0
src/player.h View File

@ -5,6 +5,12 @@
#define PLAYER_INV_SIZE 32
typedef enum {
PLAYER_STATE_STAND,
PLAYER_STATE_WALK,
PLAYER_STATE_JUMP,
} player_state_t;
typedef struct {
uint8_t x;
uint16_t y;
@ -16,4 +22,6 @@ typedef struct {
extern player_t PLAYER;
void player_update(void);
#endif

Loading…
Cancel
Save