jumprun_tile als packed struct für mehr Speicher.
[hackover2013-badge-firmware.git] / badge / jumpnrun / jumpnrun.c
index b264696..c91aac1 100644 (file)
 #include <stddef.h>
 #include <stdio.h>
 
-static vec2d       const gravity      = { FIXED_POINT_I(0,   0), FIXED_POINT_I(0,  56) };
-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, 167);
-static fixed_point const drag_factor  =   FIXED_POINT_I(0, 854);
-static fixed_point const speed_jump_x =   FIXED_POINT_I(0, 600);
+static vec2d       gravity     () { return (vec2d) { FIXED_POINT(0,   0), FIXED_POINT(0,  56) }; }
+static vec2d       move_max    () { return (vec2d) { FIXED_POINT(0, 600), FIXED_POINT(1, 300) }; }
+static fixed_point accel_horiz () { return           FIXED_POINT(0,  50); }
+static fixed_point accel_vert  () { return           FIXED_POINT(0, 167); }
+static fixed_point drag_factor () { return           FIXED_POINT(0, 854); }
 
 static inline int imax(int x, int y) {
   return x < y ? y : x;
@@ -81,15 +80,15 @@ jumpnrun_tile_range jumpnrun_visible_tiles(jumpnrun_level const *lv,
 }
 
 void jumpnrun_apply_gravity(vec2d *inertia) {
-  *inertia = vec2d_add(*inertia, gravity);
+  *inertia = vec2d_add(*inertia, gravity());
 }
 
 void jumpnrun_passive_movement(vec2d *inertia)
 {
   jumpnrun_apply_gravity(inertia);
 
-  inertia->x = fixed_point_min(fixed_point_max(fixed_point_neg(move_max.x), inertia->x), move_max.x);
-  inertia->y = fixed_point_min(fixed_point_max(fixed_point_neg(move_max.y), inertia->y), move_max.y);
+  inertia->x = fixed_point_min(fixed_point_max(fixed_point_neg(move_max().x), inertia->x), move_max().x);
+  inertia->y = fixed_point_min(fixed_point_max(fixed_point_neg(move_max().y), inertia->y), move_max().y);
 }
 
 static void jumpnrun_apply_movement(jumpnrun_level      const *lv,
@@ -100,18 +99,18 @@ static void jumpnrun_apply_movement(jumpnrun_level      const *lv,
          (BADGE_EVENT_KEY_LEFT |
           BADGE_EVENT_KEY_RIGHT)) {
   case BADGE_EVENT_KEY_LEFT:
-    //    state->player.base.inertia.x = state->player.touching_ground ? fixed_point_sub(state->player.base.inertia.x, accel_horiz) : fixed_point_neg(speed_jump_x);
-    state->player.base.inertia.x = fixed_point_sub(state->player.base.inertia.x, accel_horiz);
+    //    state->player.base.inertia.x = state->player.touching_ground ? fixed_point_sub(state->player.base.inertia.x, accel_horiz()) : fixed_point_neg(speed_jump_x());
+    state->player.base.inertia.x = fixed_point_sub(state->player.base.inertia.x, accel_horiz());
     state->player.base.flags |= JUMPNRUN_MOVEABLE_MIRRORED;
     break;
   case BADGE_EVENT_KEY_RIGHT:
-    //    state->player.base.inertia.x = state->player.touching_ground ? fixed_point_add(state->player.base.inertia.x, accel_horiz) : speed_jump_x;
-    state->player.base.inertia.x = fixed_point_add(state->player.base.inertia.x, accel_horiz);
+    //    state->player.base.inertia.x = state->player.touching_ground ? fixed_point_add(state->player.base.inertia.x, accel_horiz()) : speed_jump_x();
+    state->player.base.inertia.x = fixed_point_add(state->player.base.inertia.x, accel_horiz());
     state->player.base.flags &= ~JUMPNRUN_MOVEABLE_MIRRORED;
     break;
   default:
     if(jumpnrun_moveable_touching_ground(&state->player.base)) {
-      state->player.base.inertia.x = fixed_point_mul(state->player.base.inertia.x, drag_factor);
+      state->player.base.inertia.x = fixed_point_mul(state->player.base.inertia.x, drag_factor());
     } //else {
       //state->player.base.inertia.x = FIXED_INT(0);
     //}
@@ -122,7 +121,7 @@ static void jumpnrun_apply_movement(jumpnrun_level      const *lv,
   if(state->player.base.jumpable_frames == 0) {
     // intentionally left blank.
   } else if(badge_event_current_input_state() & BADGE_EVENT_KEY_BTN_A) {
-    state->player.base.inertia.y = fixed_point_sub(state->player.base.inertia.y, accel_vert);
+    state->player.base.inertia.y = fixed_point_sub(state->player.base.inertia.y, accel_vert());
     --state->player.base.jumpable_frames;
   } else {
     state->player.base.jumpable_frames = 0;
@@ -163,11 +162,11 @@ void jumpnrun_level_tick(jumpnrun_level      *lv,
   if(state->tick == 0) {
     badge_framebuffer fb = { { { 0 } } };
 
-    for(size_t tile = tilerange.first; tile < tilerange.last; ++tile) {
+    for(uint16_t tile = tilerange.first; tile < tilerange.last; ++tile) {
       jumpnrun_render_tile(&fb, state, &lv->tiles[tile]);
     }
 
-    for(size_t item = 0; item < lv->header.item_count; ++item) {
+    for(uint16_t item = 0; item < lv->header.item_count; ++item) {
       jumpnrun_item *item_obj = &lv->items[item];
 
       if(item_obj->flags & JUMPNRUN_ITEM_COLLECTED) {
@@ -187,7 +186,7 @@ void jumpnrun_level_tick(jumpnrun_level      *lv,
       }
     }
 
-    for(size_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) {
+    for(uint16_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) {
       jumpnrun_shot *shot = &state->shots[shot_ix];
       jumpnrun_shot_process(shot);
       if(jumpnrun_shot_spawned(shot)) {
@@ -195,7 +194,7 @@ void jumpnrun_level_tick(jumpnrun_level      *lv,
       }
     }
 
-    for(size_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) {
+    for(uint16_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) {
       jumpnrun_enemy *enemy = &lv->enemies[enemy_ix];
       jumpnrun_process_enemy(enemy, &fb, state, lv, &tilerange, &inertia_mod);
     }
@@ -220,11 +219,11 @@ void jumpnrun_level_tick(jumpnrun_level      *lv,
       state->player.base.anim_frame = 0;
     }
   } else {
-    for(size_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) {
+    for(uint16_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) {
       jumpnrun_shot_process(&state->shots[shot_ix]);
     }
 
-    for(size_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) {
+    for(uint16_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, &inertia_mod);
     }
@@ -237,14 +236,16 @@ void jumpnrun_level_tick(jumpnrun_level      *lv,
   }
 }
 
-uint8_t jumpnrun_play(char const *lvname) {
+uint8_t jumpnrun_play_level(char const *lvname) {
   jumpnrun_level lv;
 
   JUMPNRUN_LEVEL_LOAD(lv, lvname);
 
   jumpnrun_game_state gs;
 
-  for(jumpnrun_game_state_init(&gs, &lv); (gs.flags & JUMPNRUN_STATE_WON) == 0 && gs.player.lives != 0; --gs.player.lives) {
+  jumpnrun_game_state_init(&gs, &lv);
+
+  do {
     jumpnrun_show_lives_screen(&gs);
     jumpnrun_game_state_respawn(&gs, &lv);
 
@@ -282,9 +283,17 @@ uint8_t jumpnrun_play(char const *lvname) {
       }
       }
     }
+  } while((gs.flags & JUMPNRUN_STATE_WON) == 0 && gs.player.lives-- != 0);
+
+  if(gs.flags & JUMPNRUN_STATE_WON) {
+    jumpnrun_show_you_rock();
+    return JUMPNRUN_WON;
+  }
+
+  if(++gs.player.lives == 0) {
+    jumpnrun_show_game_over();
+    return JUMPNRUN_LOST;
   }
 
-  if(gs.flags & JUMPNRUN_STATE_WON) { return JUMPNRUN_WON; }
-  if(gs.player.lives == 0) return JUMPNRUN_LOST;
   return JUMPNRUN_ERROR;
 }
This page took 0.024163 seconds and 4 git commands to generate.