Springen auf Gegner möglich.
# IDE Flags (Keeps various IDEs happy)\r
##########################################################################\r
\r
-OPTDEFINES = -D __NEWLIB__\r
+OPTDEFINES = -D __NEWLIB__ -DR0KET\r
\r
##########################################################################\r
# Project-specific files \r
static void badge_init_backlight(void) {
HOB_SET_PIN_FUNC(HOB_LCD_BACKLIGHT, CLKOUT);
- wdtInit(false);
- SCB_CLKOUTCLKSEL = SCB_MAINCLKSEL_SOURCE_WDTOSC;
+ SCB_CLKOUTCLKSEL = SCB_MAINCLKSEL_SOURCE_INTERNALOSC;
SCB_CLKOUTCLKUEN = SCB_CLKOUTCLKUEN_DISABLE;
SCB_CLKOUTCLKUEN = SCB_CLKOUTCLKUEN_UPDATE;
SCB_CLKOUTCLKDIV = 30;
#define INCLUDED_COLLISION_H
#include "jumpnrun.h"
-#include <badge/util/rectangle.h>
+#include "../util/rectangle.h"
#include <stdbool.h>
void collision_displace(vec2d *desired_pos,
- rectangle const *current,
- rectangle const *obstacle,
- vec2d *inertia,
- bool *touching_ground);
+ rectangle const *current,
+ rectangle const *obstacle,
+ vec2d *inertia_mod,
+ bool *touching_ground);
void collisions_tiles_displace(vec2d *desired_position,
- rectangle const *current,
- jumpnrun_level const *level,
- jumpnrun_tile_range const *visible_tiles,
- vec2d *inertia,
- bool *touching_ground);
+ rectangle const *current,
+ jumpnrun_level const *level,
+ jumpnrun_tile_range const *visible_tiles,
+ vec2d *inertia_mod,
+ bool *touching_ground);
#endif
{ 8, 5, (uint8_t const *) "\xd7\x7d\xc6\x19\x25" }
};
+static badge_sprite const anim_mushroom[] = {
+ { 7, 7, (uint8_t const *) "\x10\x0c\x9f\xcf\xc7\x40" },
+ { 7, 7, (uint8_t const *) "\x20\x18\x1e\x8f\x87\x81" },
+ { 7, 7, (uint8_t const *) "\x10\x0c\x9f\xcf\xc7\x40" },
+ { 7, 7, (uint8_t const *) "\x08\x86\xdf\xef\x67\x20" },
+ { 7, 7, (uint8_t const *) "\x04\xc3\xef\xf7\x33\x10" },
+ { 7, 7, (uint8_t const *) "\x04\xc3\xe7\xf3\x31\x10" }
+};
+
void jumpnrun_process_enemy(jumpnrun_enemy *self,
badge_framebuffer *fb,
struct jumpnrun_game_state *state,
self->flags &= ~JUMPNRUN_ENEMY_SPAWNED;
} else {
self->type->game_tick(self, state, lv, visible_tiles);
- badge_framebuffer_blt(fb,
- fixed_point_cast_int(self->current_pos.x) - state->left,
- fixed_point_cast_int(self->current_pos.y),
- &self->type->animation_frames[self->current_frame],
- fixed_point_lt(self->inertia.x, FIXED_POINT(0, 0)) ? 0 : BADGE_BLT_MIRRORED);
+
+ if(state->tick_minor == 0) {
+ badge_framebuffer_blt(fb,
+ fixed_point_cast_int(self->current_pos.x) - state->left,
+ fixed_point_cast_int(self->current_pos.y),
+ &self->type->animation_frames[self->current_frame],
+ fixed_point_lt(self->inertia.x, FIXED_POINT(0, 0)) ? 0 : BADGE_BLT_MIRRORED);
+ }
}
} else if(self->flags & JUMPNRUN_ENEMY_UNAVAILABLE) {
if(state->left > fixed_point_cast_int(self->spawn_pos.x) + spawn_margin ||
}
}
-void enemy_collision_player_kill(jumpnrun_enemy *self,
- jumpnrun_game_state *state)
+void enemy_collision_player_jumpable(jumpnrun_enemy *self,
+ jumpnrun_game_state *state)
{
rectangle rect_self = rect_from_enemy(self);
rectangle rect_hacker = hacker_rect_current(state);
if(rectangle_intersect(&rect_self, &rect_hacker)) {
- state->status = JUMPNRUN_DEAD;
+ if(fixed_point_gt(state->inertia.y, FIXED_POINT(0, 0))) {
+ self->flags &= ~JUMPNRUN_ENEMY_SPAWNED;
+ state->inertia_mod.y = FIXED_POINT(0, -250);
+ state->jumpable_frames = 8;
+ } else {
+ state->status = JUMPNRUN_DEAD;
+ }
}
}
}
jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = {
- { 2, ARRAY_SIZE(anim_cat), anim_cat,
- { FIXED_POINT_I(0, -800), FIXED_POINT_I(0, 0) },
+ { 16, ARRAY_SIZE(anim_cat), anim_cat,
+ { FIXED_POINT_I(0, -100), FIXED_POINT_I(0, 0) },
+ enemy_collision_tiles_bounce_horiz,
+ enemy_collision_player_jumpable,
+ enemy_tick_cat
+ }, {
+ 16, ARRAY_SIZE(anim_mushroom), anim_mushroom,
+ { FIXED_POINT_I(0, -50), FIXED_POINT_I(0, 0) },
enemy_collision_tiles_bounce_horiz,
- enemy_collision_player_kill,
+ enemy_collision_player_jumpable,
enemy_tick_cat
}
};
#ifndef INCLUDED_JUMPNRUN_ENEMIES_H
#define INCLUDED_JUMPNRUN_ENEMIES_H
-#include <badge/ui/sprite.h>
-#include <badge/util/rectangle.h>
+#include "../ui/sprite.h"
+#include "../util/rectangle.h"
#include "tiles.h"
vec2d spawn_inertia;
void (*collision_tiles)(struct jumpnrun_enemy *self,
- vec2d *desired_position,
- struct jumpnrun_level *lv,
- struct jumpnrun_tile_range const *visible_tiles);
+ vec2d *desired_position,
+ struct jumpnrun_level *lv,
+ struct jumpnrun_tile_range const *visible_tiles);
void (*collision_player)(struct jumpnrun_enemy *self,
- struct jumpnrun_game_state *state);
+ struct jumpnrun_game_state *state);
void (*game_tick)(struct jumpnrun_enemy *self,
- struct jumpnrun_game_state *state,
+ struct jumpnrun_game_state *state,
struct jumpnrun_level *lv,
struct jumpnrun_tile_range const *visible_tiles);
} jumpnrun_enemy_type;
enum {
JUMPNRUN_ENEMY_TYPE_CAT,
+ JUMPNRUN_ENEMY_TYPE_MUSHROOM,
JUMPNRUN_ENEMY_TYPE_COUNT
};
extern jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT];
void jumpnrun_process_enemy(jumpnrun_enemy *self,
- badge_framebuffer *fb,
- struct jumpnrun_game_state *state,
- struct jumpnrun_level *lv,
- struct jumpnrun_tile_range const *visible_tiles);
+ badge_framebuffer *fb,
+ struct jumpnrun_game_state *state,
+ struct jumpnrun_level *lv,
+ struct jumpnrun_tile_range const *visible_tiles);
#endif
#ifndef INCLUDED_JUMPNRUN_ITEMS_H
#define INCLUDED_JUMPNRUN_ITEMS_H
-#include <badge/ui/sprite.h>
-#include <badge/util/rectangle.h>
+#include "../ui/sprite.h"
+#include "../util/rectangle.h"
struct jumpnrun_game_state;
#include "jumpnrun.h"
#include "collision.h"
+#include "levels.h"
-#include <badge/ui/display.h>
-#include <badge/ui/event.h>
-#include <badge/ui/sprite.h>
+#include "../ui/display.h"
+#include "../ui/event.h"
+#include "../ui/sprite.h"
#include <assert.h>
#include <math.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof*(arr))
static vec2d const gravity = { FIXED_POINT_I(0, 0), FIXED_POINT_I(0, 56) };
-static vec2d const move_max = { FIXED_POINT_I(1, 200), FIXED_POINT_I(1, 300) };
-static fixed_point const accel_horiz = FIXED_POINT_I(0, 100);
+static vec2d const move_max = { FIXED_POINT_I(0, 600), FIXED_POINT_I(1, 300) };
+static fixed_point const accel_horiz = FIXED_POINT_I(0, 50);
static fixed_point const accel_vert = FIXED_POINT_I(0, 250);
static fixed_point const drag_factor = FIXED_POINT_I(0, 854);
-static fixed_point const speed_jump_x = FIXED_POINT_I(1, 200);
+static fixed_point const speed_jump_x = FIXED_POINT_I(0, 600);
static badge_sprite const anim_hacker[] = {
{ 5, 8, (uint8_t const *) "\x1c\xff\xfd\x04\x04" },
jumpnrun_passive_movement(&state->inertia);
- state->inertia.x = fixed_point_min(fixed_point_max(fixed_point_neg(move_max.x), state->inertia.x), move_max.x);
- state->inertia.y = fixed_point_min(fixed_point_max(fixed_point_neg(move_max.y), state->inertia.y), move_max.y);
-
vec2d new_pos = vec2d_add(state->current_pos, state->inertia);
if(fixed_point_lt(new_pos.x, FIXED_POINT(state->left, 0))) {
rectangle hacker_rect_c = hacker_rect(&state->current_pos, state);
collisions_tiles_displace(&new_pos, &hacker_rect_c, lv, tilerange, &state->inertia, &state->touching_ground);
+ state->inertia_mod = state->inertia;
state->current_pos = new_pos;
} else {
state->anim_frame = 0;
}
+ } else {
+ for(size_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) {
+ jumpnrun_enemy *enemy = &lv->enemies[enemy_ix];
+ jumpnrun_process_enemy(enemy, NULL, state, lv, &tilerange);
+ }
}
- state->tick_minor = (state->tick_minor + 1) % 2;
+ state->inertia = state->inertia_mod;
+ state->tick_minor = (state->tick_minor + 1) % 4;
}
uint8_t jumpnrun_play(char const *lvname) {
jumpnrun_level lv;
- memset(&lv, 0, sizeof(lv));
-
- // This part looks ugly. The reason it's done this way is that we don't know how much memory
- // we need for the level before parsing its header, and that the VLAs we use to store it have
- // block scope.
- // Still, better than opening the whole dynamic memory can of worms.
- FIL fd;
- int err;
-
- if(FR_OK != f_open(&fd, lvname, FA_OPEN_EXISTING | FA_READ)) { return JUMPNRUN_ERROR; }
-
- if(0 != jumpnrun_load_level_header_from_file(&lv, &fd)) {
- f_close(&fd);
- return JUMPNRUN_ERROR;
- }
-
- JUMPNRUN_LEVEL_MAKE_SPACE(lv);
- err = jumpnrun_load_level_from_file(&lv, &fd);
-
- f_close(&fd);
- if(err != 0) {
- return JUMPNRUN_ERROR;
- }
+ JUMPNRUN_LEVEL_LOAD(lv, lvname);
jumpnrun_game_state gs;
memset(&gs, 0, sizeof(gs));
uint8_t new_state = badge_event_new_input_state(ev);
uint8_t new_buttons = new_state & (old_state ^ new_state);
- if((new_buttons & BADGE_EVENT_KEY_BTN_B) && gs.touching_ground) {
+ if((new_buttons & BADGE_EVENT_KEY_BTN_A) && gs.touching_ground) {
gs.jumpable_frames = 8;
}
#include "levels.h"
#include "tiles.h"
-#include <badge/util/fixed_point.h>
-#include <badge/util/rectangle.h>
-#include <badge/ui/sprite.h>
+#include "../util/fixed_point.h"
+#include "../util/rectangle.h"
+#include "../ui/sprite.h"
#include <stdbool.h>
#include <stddef.h>
typedef struct jumpnrun_game_state {
vec2d current_pos;
vec2d inertia;
+ vec2d inertia_mod;
uint8_t status;
uint8_t tick_minor;
#include "items.h"
#include "enemies.h"
+#include <drivers/fatfs/ff.h>
+
#include <stdio.h>
typedef struct {
#include "items.h"
#include "tiles.h"
-#include <badge/util/rectangle.h>
-
-#include <drivers/fatfs/ff.h>
+#include "../util/rectangle.h"
#include <stddef.h>
#include <stdio.h>
size_t jumpnrun_level_count(void);
void jumpnrun_levels_dump(void);
-int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FIL *fd);
-int jumpnrun_load_level_from_file (jumpnrun_level *dest, FIL *fd);
-
// Use stack-local VLAs to store dynamic content.
#define JUMPNRUN_LEVEL_MAKE_SPACE(var) \
jumpnrun_tile var ## _tiles [var.header.tile_count]; \
var.tiles = var ## _tiles; \
var.items = var ## _items; \
var.enemies = var ## _enemies;
+#else
+
+#ifdef __linux__
+
+int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FILE *fd);
+int jumpnrun_load_level_from_file (jumpnrun_level *dest, FILE *fd);
+
+#define JUMPNRUN_LEVEL_LOAD(lv, lvname) \
+ memset(&(lv), 0, sizeof(lv)); \
+ FILE *fd = fopen((lvname), "r"); \
+ if(fd == NULL) return JUMPNRUN_ERROR; \
+ int err = jumpnrun_load_level_header_from_file(&(lv), fd); \
+ if(err != 0) { \
+ fclose(fd); \
+ return JUMPNRUN_ERROR; \
+ } \
+ JUMPNRUN_LEVEL_MAKE_SPACE(lv); \
+ err = jumpnrun_load_level_from_file(&(lv), fd); \
+ fclose(fd); \
+ if(err != 0) return JUMPNRUN_ERROR;
+#else
+#include <drivers/fatfs/ff.h>
+
+int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FIL *fd);
+int jumpnrun_load_level_from_file (jumpnrun_level *dest, FIL *fd);
+
+#define JUMPNRUN_LEVEL_LOAD(lv, lvname) \
+ memset(&(lv), 0, sizeof(lv)); \
+ FIL fd; \
+ if(FR_OK != f_open(&fd, (lvname), FA_OPEN_EXISTING | FA_READ)) { \
+ return JUMPNRUN_ERROR; \
+ } \
+ if(0 != jumpnrun_load_level_header_from_file(&(lv), &fd)) { \
+ f_close(&fd); \
+ return JUMPNRUN_ERROR; \
+ } \
+ JUMPNRUN_LEVEL_MAKE_SPACE(lv); \
+ int err = jumpnrun_load_level_from_file(&(lv), &fd); \
+ f_close(&fd); \
+ if(err != 0) { \
+ return JUMPNRUN_ERROR; \
+ }
+#endif
#endif
#ifndef INCLUDED_JUMPNRUN_TILES_H
#define INCLUDED_JUMPNRUN_TILES_H
-#include <badge/util/fixed_point.h>
-#include <badge/util/rectangle.h>
-#include <badge/ui/sprite.h>
+#include "../util/fixed_point.h"
+#include "../util/rectangle.h"
+#include "../ui/sprite.h"
#include <stdint.h>
badge_init();
#endif
- /*
{
// f_mkfs(0, 1, 0);
badge_framebuffer fb;
}
badge_framebuffer_flush(&fb);
-
}
- usbMSCInit();
- for(;;);
- */
+ if(badge_input_raw() & BADGE_EVENT_KEY_DOWN) {
+ usbMSCInit();
+ for(;;);
+ }
badge_event_start();
- /*
for(;;) {
if(JUMPNRUN_ERROR == jumpnrun_play("smb.lvl")) {
break;
}
}
- */
uint8_t buttons = 0;
| HOB_IOCON_MASK(spec, FUNC_ ## func); \
} while(0)
-/*
-HOB_PORT(HOB_LCD_BACKLIGHT)
-HOB_PIN(HOB_LCD_BACKLIGHT)
-HOB_IOCON(HOB_LCD_BACKLIGHT)
-HOB_IOCON_MASK(HOB_LCD_BACKLIGHT, FUNC_GPIO)
-*/
-
#endif
BADGE_EVENT_FLAG_TIMER = 2
};
-static uint8_t badge_input_raw(void) {
+uint8_t badge_input_raw(void) {
uint8_t result = 0;
#ifdef R0KET
- if (gpioGetValue(RB_BTN3) == 0) { result |= BADGE_EVENT_KEY_UP ; }
- if (gpioGetValue(RB_BTN2) == 0) { result |= BADGE_EVENT_KEY_DOWN ; }
+ if (gpioGetValue(RB_BTN3) == 0) { result |= BADGE_EVENT_KEY_DOWN ; }
+ if (gpioGetValue(RB_BTN2) == 0) { result |= BADGE_EVENT_KEY_UP ; }
if (gpioGetValue(RB_BTN4) == 0) { result |= BADGE_EVENT_KEY_CENTER; }
- if (gpioGetValue(RB_BTN0) == 0) { result |= BADGE_EVENT_KEY_LEFT ; }
- if (gpioGetValue(RB_BTN1) == 0) { result |= BADGE_EVENT_KEY_RIGHT ; }
+ if (gpioGetValue(RB_BTN0) == 0) { result |= BADGE_EVENT_KEY_RIGHT ; }
+ if (gpioGetValue(RB_BTN1) == 0) { result |= BADGE_EVENT_KEY_LEFT ; }
if (gpioGetValue(RB_HB0 ) == 0) { result |= BADGE_EVENT_KEY_BTN_A ; }
if (gpioGetValue(RB_HB1 ) == 0) { result |= BADGE_EVENT_KEY_BTN_B ; }
#else
}
void badge_event_start(void) {
- timer32Init(0, TIMER32_CCLK_10MS * 2);
+ timer32Init(0, TIMER32_CCLK_10MS);
timer32SetIntHandler(badge_event_irq);
timer32Enable(0);
}
static inline uint8_t badge_event_old_input_state(badge_event_t event) { return (uint8_t) (event >> 2 & 0x7f); }
static inline uint8_t badge_event_new_input_state(badge_event_t event) { return (uint8_t) (event >> 9 ); }
+ uint8_t badge_input_raw(void);
uint8_t badge_event_current_input_state(void);
static inline badge_event_t badge_event_new(uint8_t type, uint8_t old_input_state, uint8_t new_input_state) {