#include #include #include #include #include #include "menu.h" #include "draw.h" #include "draw_menu.h" #include "main.h" #include "progress.h" #include "level.h" #include "levelpack.h" uint24_t menu_view_x = 0; uint8_t menu_view_y = 240; uint8_t menu_view_vy = 4; int16_t menu_view_vx = 0; int24_t menu_view_dx = 0; uint8_t menu_level_x = 0; uint8_t menu_level_y = 0; uint8_t menu_level_ymax = 0; uint8_t menu_level_status = MENU_NONE; uint16_t menu_level_selection = 0; uint16_t menu_levels_count = 0; static void menu_level_selection_changed() { if (menu_level_selection) { if (menu_level_selection > menu_levels_count) { if (menu_level_selection & 0x8000) { menu_level_status = MENU_LEAVING; menu_level_selection = 0; menu_view_dx = 0; return; } menu_level_selection = menu_levels_count; } menu_level_y = (menu_level_selection - 1) % 10 + 1; menu_level_x = (menu_level_selection - 1) / 10; { uint16_t menu_level_ymax_tmp = menu_levels_count - (menu_level_x * 10); menu_level_ymax = menu_level_ymax_tmp > 10 ? 10 : menu_level_ymax_tmp; } } else { menu_level_x = menu_level_y = 0; } menu_view_dx = (++menu_level_x + 3) * 320; } void menu(void) { uint8_t keys_mask, keys_delay; uint8_t keys_new, keys; uint8_t redraw_needed = 1; draw_init(); menu_level_selection = progress.level_wip.index; for (keys_delay = keys_mask = 0;;) { if (redraw_needed) { redraw_needed = 0; draw_menu(); } delay(32); keys_new = ((keys = keys_test()) & keys_mask); keys_mask = ~keys; if (keys_new & kb_Clear) break; if (keys_new & kb_Enter) { if (menu_level_status != MENU_VISIBLE) { menu_level_status = MENU_ENTERING; if (menu_view_y > MENU_LAND_Y) { menu_view_vy = 8; menu_view_y &= ~(8 - 1); //menu_view_y |= MENU_LAND_Y & (8 - 1); //0 } if (!menu_level_selection) menu_level_selection = 1; if (menu_level_selection > menu_levels_count) menu_level_selection = menu_levels_count; menu_level_selection_changed(); ++redraw_needed; if (menu_view_x < 320 * 2) { menu_view_vx = 11; } else if (menu_view_x < 320 * 3) { menu_view_x += (((int) ((320 - (menu_view_x % 320)) / 40)) * 40); } } else { if (!menu_level_selection || (progress_level_get(menu_level_selection) != LOCKED)) { for (level.level_index = menu_level_selection;; ++level.level_index) { enum level_play_result result = levelpack_load_level(); (result == DONE ? progress_level_done : progress_level_tried)(level.level_index); if ((result == QUIT) || (level.level_index+1 > menu_levels_count)) break; } keys_mask = 0; menu_level_selection = level.level_index; menu_level_selection_changed(); ++redraw_needed; } } } if (keys_delay) --keys_delay; else if (menu_level_status == MENU_VISIBLE) { uint8_t dir = keys_test_dir(); if (dir) { switch (dir) { case DIR_U: if (menu_level_selection > 1) menu_level_selection -= 1; break; case DIR_L: if (!(menu_level_selection -= 10)) --menu_level_selection; break; case DIR_R: if (menu_levels_count > (((int) ((menu_level_selection - 1) / 10)) + 1) * 10) menu_level_selection += 10; break; case DIR_D: menu_level_selection += 1; break; } menu_level_selection_changed(); ++redraw_needed; keys_delay = 3; } } if (menu_view_vy) { if ((menu_view_y -= menu_view_vy) == MENU_LAND_Y) { menu_view_vy = 0; if (!menu_view_vx) menu_view_vx = 6; } } if (menu_level_status == MENU_NONE) { if ((menu_view_x += menu_view_vx) >= 320 * 3) { menu_view_x -= 320; } } else { int speed = ((int) (menu_view_dx - ((int) menu_view_x))) / 16; menu_view_vx = speed < -17 ? -17 : speed > 17 ? 17 : (int) ((int8_t) speed + (int8_t) (menu_view_dx > menu_view_x) - (int8_t) (menu_view_dx < menu_view_x)); if ((menu_view_x += menu_view_vx) < 320 * 3 + 120) { if (menu_level_status == MENU_LEAVING) { menu_level_status = MENU_NONE; menu_view_vx = 11; } } else if (menu_level_status == MENU_ENTERING) menu_level_status = MENU_VISIBLE; } if (menu_view_vy || menu_view_vx) ++redraw_needed; } draw_exit(); }