#include #include #include #include #include #include "duet.h" extern bopti_image_t img_title; extern bopti_image_t img_levels; int main_menu(int *episode, int *level) { volatile int need_frame = 1; int timer = timer_configure(TIMER_ANY, 33000, GINT_CALL_SET(&need_frame)); if(timer >= 0) timer_start(timer); float time = 0; int s_episode = 0; int s_level = 0; int scroll = 0; int target_scroll = 0; int scroll_by_episode[20] = { 0 }; *episode = 0; *level = 0; while(1) { while (need_frame == 0) sleep(); need_frame = 0; time += 1.0 / 30; /* Smooth scroll update */ if(target_scroll != scroll) { int diff = (target_scroll - scroll) * 3 / 16; if(diff == 0) diff = (target_scroll > scroll) ? 1 : -1; scroll += diff; } /* Keyboard input */ key_event_t e; bool input_finished = false; while((e = pollevent()).type != KEYEV_NONE) { if(e.type == KEYEV_DOWN && e.key == KEY_MENU) gint_osmenu(); if(e.type == KEYEV_DOWN && e.key == KEY_EXE) { *episode = s_episode; *level = s_level; input_finished = true; break; } if(e.type == KEYEV_DOWN && e.key == KEY_DOWN && (s_episode < episode_count - 1 || s_level < episodes[s_episode].level_count - 1)) { s_level++; if(s_level >= episodes[s_episode].level_count) { s_episode++; s_level = 0; } } if(e.type == KEYEV_DOWN && e.key == KEY_UP && (s_episode > 0 || s_level > 0)) { s_level--; if(s_level < 0) { s_episode--; s_level = episodes[s_episode].level_count - 1; } } if(e.type == KEYEV_DOWN && e.key == KEY_RIGHT) { if(s_level >= 4) s_level -= 4; else if(s_episode > 0) { s_episode--; s_level = (episodes[s_episode].level_count & ~3) + (s_level & 3); if(s_level >= episodes[s_episode].level_count) s_level = episodes[s_episode].level_count - 1; } } if(e.type == KEYEV_DOWN && e.key == KEY_LEFT) { if(s_level + 4 < episodes[s_episode].level_count) s_level += 4; else if(s_episode + 1 < episode_count) { s_episode++; s_level &= 3; if(s_level >= episodes[s_episode].level_count) s_level = episodes[s_episode].level_count - 1; } } } if(input_finished) break; target_scroll = scroll_by_episode[0]-scroll_by_episode[s_episode]; /* Rendering */ dclear(C_BLACK); dimage(330+scroll, DHEIGHT/2 - img_title.height / 2, &img_title); render_player(268+scroll, DHEIGHT/2, time * 0.8, PLAYER_R, 1.0); int x=188+scroll, y=40; for(int i = 0; i < episode_count; i++) { episode_t const *e = &episodes[i]; scroll_by_episode[i] = x; duet_text_opt(x, y, C_WHITE, C_NONE, DTEXT_LEFT, DTEXT_TOP, e->name, -1); x -= 11; for(int j = 0; j < e->level_count; j++) { int rx = x - 38 * (j/4); int ry = y + 38 * (j%4); if(s_episode == i && s_level == j) { drect(rx+2, ry-2, rx-32, ry+32, C_WHITE); } drect(rx, ry, rx-30, ry+30, C_RGB(10, 10, 10)); dsubimage(rx-30, ry, &img_levels, 0, 31*j, 31, 31, DIMAGE_NONE); } x -= 35 * ((e->level_count + 3) / 4); x -= 20; } dupdate(); } timer_stop(timer); return 1; }