/* * @file: main.c * @author C. Hölzl * @brief: Main file * 2019 */ #include #include #include #include "utils.h" #include "input.h" #include "network.h" #include "graphics_main.h" #include "graphics_sub.h" #include "graphics_engine.h" gs_t status = LOAD; gt_t gt = START; #define DEFAULT_SOLO_MAZE_SIZE 0 void main_start() { while (status != QUIT) { handle_keys_start(&status); draw_title(); swiWaitForVBlank(); oamUpdate(&oamSub); } } void main_menu() { while (status != QUIT) { handle_keys_menu(&status, >); swiWaitForVBlank(); } } void main_submenu() { while (status != QUIT) { handle_keys_submenu(&status, >); swiWaitForVBlank(); } } void main_solo() { u32 dimentions = DEFAULT_SOLO_MAZE_SIZE; char name[NAME_LEN + 1] = PNAME; draw_loading(); game_t* game = game_init(game_alloc(), dimentions, name, &status); update_player_room(game->maze, game->player); init_game_timer(); clear_main_text(); clear_message(); while (status != QUIT) { if (game->maze->level > MAX_MAZE_SIZE) { status = QUIT; } switch (status) { case RUN: handle_keys_solo(game, &status); draw_game(game, get_game_time()); break; case LOAD: break; case FINISHED: if (game->maze->level == 8) { pscore_t score = {"++", get_game_time()}; strncpy(score.name, game->player->name, NAME_LEN); insert_score(&score); write_score(); } draw_loading(); game_reset(game, game->maze->level * DIFINC, game->player->name, &status); reset_game_time(); clear_main_text(); clear_message(); break; default: break; } swiWaitForVBlank(); oamUpdate(&oamSub); } disable_game_timer(); game_end(game); } bool handle_rcv_msg_sc(const char * const in_msg) { switch (in_msg[0]) { case 'L': status = LOAD; break; case 'W': status = WAIT; break; case 'D': status = DEADLOCK; break; case 'R': default: break; } return true; } bool handle_rcv_msg_op(const char * imptr, room_t room) { net_player_t oplayer; u32 n = 0; while (strlen(imptr) >= 3) { if (sscanf(imptr, " %2s %hhd %hhd %hhu %hhu %n", oplayer.name, &oplayer.pos.x, &oplayer.pos.y, &oplayer.part, &oplayer.taunt, &n) != 5) { return false; } imptr += n; draw_player_multi_sub(&oplayer,check_room_has_element(room, RTRAP)); } return true; } bool handle_rcv_msg(const char * const in_msg) { if (strlen(in_msg) == 1) { return handle_rcv_msg_sc(in_msg); } else { if (status != RUN && status != DEADLOCK && status != QUIT) { status = RUN; } u32 slot_left = 0; room_t room = BOX_ROOM; u8 global_slot_left = 0; u32 size = 0; net_player_t player; u32 n = 0; const char* imptr = in_msg; if (sscanf(imptr, "%u %hhu %d %2s %hhd %hhd %hhu %hhu %n", &room, &global_slot_left, &slot_left, player.name, &player.pos.x, &player.pos.y, &player.part, &player.taunt, &n) != 8) { return false; } if (size) {} imptr += n; draw_game_multi(room, player.part, slot_left, player.taunt); if (handle_rcv_msg_op(imptr, room) == false) return false; draw_player_multi_sub(&player,true); //drawinfo(room, player.part, slot_left); if (global_slot_left > 0 && slot_left == 0) { draw_message("Waiting for everybody to finish"); } else { clear_message_main(); } } return true; } #define RCV_BUFF_SIZE 1024 void main_multi() { char name[NAME_LEN + 1] = PNAME; char rcv_buff[RCV_BUFF_SIZE] = {0}; draw_connecting(); if (init_wlpif() != 0) { //Connect to Wifi status = QUIT; return; } if (init_socket(1) != 0) { //Connect to Server status = QUIT; end_wlpif(); return; } if (net_snd(name, strlen(name)) == -1) { //Send name to server end_wlpif(); end_socket(); return; } draw_loading(); while (status != QUIT) { switch (status) { case DEADLOCK: draw_warning("A player left, maze might be unsolvable"); case RUN: handle_keys_multi(&status); // draw_game_multi(game, get_game_time()); break; case WAIT: draw_message("Waiting for Previous Game to Finish"); break; case LOAD: clear_message_main(); draw_loading(); break; case TIMEOUT: status = QUIT; break; case FINISHED: clear_message_main(); //draw_loading(); break; default: break; } if(rcv_room_from_server(rcv_buff, RCV_BUFF_SIZE, &status)){ if(handle_rcv_msg(rcv_buff)==false){ status = QUIT; } } swiWaitForVBlank(); oamUpdate(&oamSub); } end_wlpif(); end_socket(); } int main(void) { fatInitDefault(); rand_init(clock()); read_score(); init_graphics(); init_load_timer(); init_audio(); while (gt != END) { status = LOAD; switch (gt) { case START: main_start(); next_loading_isr(1); gt = MENU; break; case MENU: switch_mode(GMENU); draw_menu(); main_menu(); break; case SOLO: switch_mode(GGAME); main_solo(); gt = MENU; break; case MULTI: switch_mode(GGAME_ALT); main_multi(); gt = MENU; break; case CREDITS: switch_mode_main(GGAME); draw_credits(); main_submenu(); gt = MENU; break; case GUIDE: switch_mode_main(GGAME); draw_guide(); main_submenu(); gt = MENU; break; case RANKING: switch_mode_main(GGAME); draw_rank(); main_submenu(); gt = MENU; break; default: return 1; } swiWaitForVBlank(); } return 0; }