From: Wintermute Date: Sat, 12 Oct 2013 21:48:58 +0000 (+0200) Subject: Jumpnrun: Neueste Entwicklung geportet. Schnellere Bewegung, neuer Gegner, X-Git-Url: https://git.rohieb.name/hackover2013-badge-firmware.git/commitdiff_plain/a7875e0dd83390a47de359df1f33a017ecb3f065 Jumpnrun: Neueste Entwicklung geportet. Schnellere Bewegung, neuer Gegner, Springen auf Gegner möglich. --- diff --git a/Makefile b/Makefile index e1ce46d..0abe529 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ DEBUGBUILD = FALSE # IDE Flags (Keeps various IDEs happy) ########################################################################## -OPTDEFINES = -D __NEWLIB__ +OPTDEFINES = -D __NEWLIB__ -DR0KET ########################################################################## # Project-specific files diff --git a/badge/init.c b/badge/init.c index 5acecad..4623b8e 100644 --- a/badge/init.c +++ b/badge/init.c @@ -9,8 +9,7 @@ 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; diff --git a/badge/jumpnrun/collision.h b/badge/jumpnrun/collision.h index 1fe6462..2ae4e10 100644 --- a/badge/jumpnrun/collision.h +++ b/badge/jumpnrun/collision.h @@ -2,20 +2,20 @@ #define INCLUDED_COLLISION_H #include "jumpnrun.h" -#include +#include "../util/rectangle.h" #include 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 diff --git a/badge/jumpnrun/enemies.c b/badge/jumpnrun/enemies.c index a6e391a..4ba4e07 100644 --- a/badge/jumpnrun/enemies.c +++ b/badge/jumpnrun/enemies.c @@ -11,6 +11,15 @@ static badge_sprite const anim_cat[] = { { 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, @@ -25,11 +34,14 @@ void jumpnrun_process_enemy(jumpnrun_enemy *self, 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 || @@ -69,14 +81,20 @@ void enemy_collision_tiles_bounce_horiz(jumpnrun_enemy *self, } } -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; + } } } @@ -105,10 +123,16 @@ void enemy_tick_cat(jumpnrun_enemy *self, } 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 } }; diff --git a/badge/jumpnrun/enemies.h b/badge/jumpnrun/enemies.h index 394cf45..8277e69 100644 --- a/badge/jumpnrun/enemies.h +++ b/badge/jumpnrun/enemies.h @@ -1,8 +1,8 @@ #ifndef INCLUDED_JUMPNRUN_ENEMIES_H #define INCLUDED_JUMPNRUN_ENEMIES_H -#include -#include +#include "../ui/sprite.h" +#include "../util/rectangle.h" #include "tiles.h" @@ -20,13 +20,13 @@ typedef struct jumpnrun_enemy_type { 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; @@ -55,6 +55,7 @@ enum { enum { JUMPNRUN_ENEMY_TYPE_CAT, + JUMPNRUN_ENEMY_TYPE_MUSHROOM, JUMPNRUN_ENEMY_TYPE_COUNT }; @@ -62,8 +63,8 @@ enum { 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 diff --git a/badge/jumpnrun/items.h b/badge/jumpnrun/items.h index f10204a..3ea9668 100644 --- a/badge/jumpnrun/items.h +++ b/badge/jumpnrun/items.h @@ -1,8 +1,8 @@ #ifndef INCLUDED_JUMPNRUN_ITEMS_H #define INCLUDED_JUMPNRUN_ITEMS_H -#include -#include +#include "../ui/sprite.h" +#include "../util/rectangle.h" struct jumpnrun_game_state; diff --git a/badge/jumpnrun/jumpnrun.c b/badge/jumpnrun/jumpnrun.c index ef3c471..3b7a4c6 100644 --- a/badge/jumpnrun/jumpnrun.c +++ b/badge/jumpnrun/jumpnrun.c @@ -1,9 +1,10 @@ #include "jumpnrun.h" #include "collision.h" +#include "levels.h" -#include -#include -#include +#include "../ui/display.h" +#include "../ui/event.h" +#include "../ui/sprite.h" #include #include @@ -13,11 +14,11 @@ #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" }, @@ -158,9 +159,6 @@ static void jumpnrun_apply_movement(jumpnrun_level const *lv, 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))) { @@ -170,6 +168,7 @@ static void jumpnrun_apply_movement(jumpnrun_level const *lv, 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; @@ -237,37 +236,21 @@ void jumpnrun_level_tick(jumpnrun_level *lv, } 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)); @@ -284,7 +267,7 @@ uint8_t jumpnrun_play(char const *lvname) { 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; } diff --git a/badge/jumpnrun/jumpnrun.h b/badge/jumpnrun/jumpnrun.h index 0d0dfd1..e8c2c05 100644 --- a/badge/jumpnrun/jumpnrun.h +++ b/badge/jumpnrun/jumpnrun.h @@ -6,9 +6,9 @@ #include "levels.h" #include "tiles.h" -#include -#include -#include +#include "../util/fixed_point.h" +#include "../util/rectangle.h" +#include "../ui/sprite.h" #include #include @@ -28,6 +28,7 @@ enum { typedef struct jumpnrun_game_state { vec2d current_pos; vec2d inertia; + vec2d inertia_mod; uint8_t status; uint8_t tick_minor; diff --git a/badge/jumpnrun/level_load.c b/badge/jumpnrun/level_load.c index 3ae31d7..c2f9dfe 100644 --- a/badge/jumpnrun/level_load.c +++ b/badge/jumpnrun/level_load.c @@ -3,6 +3,8 @@ #include "items.h" #include "enemies.h" +#include + #include typedef struct { diff --git a/badge/jumpnrun/levels.h b/badge/jumpnrun/levels.h index fa7b1a3..182cafd 100644 --- a/badge/jumpnrun/levels.h +++ b/badge/jumpnrun/levels.h @@ -5,9 +5,7 @@ #include "items.h" #include "tiles.h" -#include - -#include +#include "../util/rectangle.h" #include #include @@ -36,9 +34,6 @@ enum { 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]; \ @@ -48,5 +43,48 @@ int jumpnrun_load_level_from_file (jumpnrun_level *dest, FIL *fd); 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 + +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 diff --git a/badge/jumpnrun/tiles.h b/badge/jumpnrun/tiles.h index e487e1c..8010e11 100644 --- a/badge/jumpnrun/tiles.h +++ b/badge/jumpnrun/tiles.h @@ -1,9 +1,9 @@ #ifndef INCLUDED_JUMPNRUN_TILES_H #define INCLUDED_JUMPNRUN_TILES_H -#include -#include -#include +#include "../util/fixed_point.h" +#include "../util/rectangle.h" +#include "../ui/sprite.h" #include diff --git a/badge/main.c b/badge/main.c index 99ecee2..ffa0be1 100644 --- a/badge/main.c +++ b/badge/main.c @@ -190,7 +190,6 @@ int main(void) badge_init(); #endif - /* { // f_mkfs(0, 1, 0); badge_framebuffer fb; @@ -212,22 +211,20 @@ int main(void) } 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; diff --git a/badge/pinconfig.h b/badge/pinconfig.h index dd5f358..52f05b9 100644 --- a/badge/pinconfig.h +++ b/badge/pinconfig.h @@ -94,11 +94,4 @@ | 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 diff --git a/badge/ui/event.c b/badge/ui/event.c index 544625e..9c504be 100644 --- a/badge/ui/event.c +++ b/badge/ui/event.c @@ -18,15 +18,15 @@ enum { 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 @@ -77,7 +77,7 @@ badge_event_t badge_event_wait(void) { } void badge_event_start(void) { - timer32Init(0, TIMER32_CCLK_10MS * 2); + timer32Init(0, TIMER32_CCLK_10MS); timer32SetIntHandler(badge_event_irq); timer32Enable(0); } diff --git a/badge/ui/event.h b/badge/ui/event.h index 5871207..920df40 100644 --- a/badge/ui/event.h +++ b/badge/ui/event.h @@ -28,6 +28,7 @@ extern "C" { 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) {