/** * @file engine.c * @brief Graphics engine */ #include #include "graphics_main.h" #include "utils.h" #include "text.h" #include "title.h" #include "menu.h" #define TEXT_TILE_OFFSET_MAIN 7 #define TEXT_TILE_MAP_MAIN BG_MAP_RAM(TEXT_TILE_OFFSET_MAIN) #define CLEAR_TEXT_TILE_MAP_MAIN() memset(TEXT_TILE_MAP_MAIN,0,32*48); #define TEXT_RENDERER_SIZE 100 void clear_main_text(){ CLEAR_TEXT_TILE_MAP_MAIN(); } //PrintConsole cs0; void configure_graphics_main() { videoSetMode(MODE_5_2D); vramSetBankA(VRAM_A_MAIN_BG_0x06000000); vramSetBankB(VRAM_B_MAIN_BG_0x06020000); //consoleInit(&cs0, 0, BgType_Text4bpp, BgSize_T_256x256, 14, 0, true, true); bgInit(1, BgType_Text8bpp, BgSize_T_256x256, TEXT_TILE_OFFSET_MAIN, 0); bgInit(2, BgType_Bmp8, BgSize_B8_256x256, 1, 0); swiCopy(textTiles, BG_TILE_RAM(0), textTilesLen); CLEAR_TEXT_TILE_MAP_MAIN(); } void create_palette_main() { vramSetBankH(VRAM_E_BG_EXT_PALETTE); swiCopy(menuPal, BG_PALETTE, menuPalLen); SET_PERSONAL_PALETTE(BG_PALETTE); } void switch_mode_main(gmode_t mode) { switch (mode) { case GGAME_ALT: case GGAME: CLEAR_TEXT_TILE_MAP_MAIN(); swiCopy(textPal, BG_PALETTE, textPalLen); memset(BG_BMP_RAM(1), 0, SCREEN_WIDTH * SCREEN_HEIGHT); break; case GMENU: CLEAR_TEXT_TILE_MAP_MAIN(); swiCopy(menuPal, BG_PALETTE, menuPalLen); swiCopy(menuBitmap, BG_BMP_RAM(1), menuBitmapLen); break; default: break; } } void draw_text_at_idx(char* str, u32 top, u32 offset, textalign_t ta) { u16 start = 0; switch (ta) { case TA_LEFT: start = offset; break; case TA_RIGHT: start = (32 - strlen(str)) - offset; break; case TA_CENTER: start = (16 - strlen(str) / 2) + offset; break; } u16 cc = 0; for (cc = 0; cc < strlen(str); ++cc) { TEXT_TILE_MAP_MAIN[top * 32 + start + cc] = char_to_tile(str[cc]); } } void draw_title_main() { draw_text_at_idx("> Press Start <", 6, 0, TA_CENTER); } void draw_menu_main() { } void draw_guide_main() { draw_text_at_idx("You are in a Maze, looking for the EXIT.", 1, 1, TA_LEFT); draw_text_at_idx("To unlock the EXIT you need to bring KEYS to LOCKS.", 4, 1, TA_LEFT); draw_text_at_idx("In multiplayer, other players might have a KEY or LOCK matching your LOCK or KEY, use SHARED rooms to exchange KEYS.", 7, 1, TA_LEFT); draw_text_at_idx("Careful: a room can only have one KEY at a time and you can only carry one... Be smart !", 12, 1, TA_LEFT); draw_text_at_idx("Good Luck in solving NFH !", 17, 0, TA_CENTER); draw_text_at_idx("> Press Start <", 20, 0, TA_CENTER); } void draw_credits_main() { draw_text_at_idx("Made by C. Holzl", 8, 0, TA_CENTER); draw_text_at_idx("Music 'frozen26.exe'", 12,0, TA_CENTER); draw_text_at_idx("by roz/rno @ ModArchive.org", 14,0, TA_CENTER); draw_text_at_idx("> Press Start <", 20, 0, TA_CENTER); } void draw_rank_main() { u32 i; char text_renderer[TEXT_RENDERER_SIZE] = {0}; pscore_t* highscore = get_score(); draw_text_at_idx("NAME", 1, 4, TA_LEFT); draw_text_at_idx("SCORE", 1, 4, TA_RIGHT); for (i = 0; i < SCORE_TAB_SIZE; ++i) { if (strnlen(highscore[i].name, NAME_LEN + 1) != 0 && highscore[i].time <= SECTIME_MAX_VALUE) { snprintf(text_renderer, TEXT_RENDERER_SIZE, "%2s", highscore[i].name); draw_text_at_idx(text_renderer, 3 + i, 4, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "%04u", highscore[i].time); draw_text_at_idx(text_renderer, 3 + i, 4, TA_RIGHT); } } draw_text_at_idx("> Press Start <", 20, 0, TA_CENTER); } void draw_warning_main(char* str) { memset(BG_BMP_RAM(1)+12*SCREEN_WIDTH, P_DARK_RED, SCREEN_WIDTH * 18); draw_text_at_idx("- W A R N I N G -", 3, 0, TA_CENTER); draw_text_at_idx(str, 4, 0, TA_CENTER); } void draw_message_main(char* str) { memset(BG_BMP_RAM(1)+12*SCREEN_WIDTH, P_DARK_YELLOW, SCREEN_WIDTH * 18); draw_text_at_idx("- I N F O -", 3, 0, TA_CENTER); draw_text_at_idx(str, 4, 0, TA_CENTER); } void clear_message_main() { memset(BG_BMP_RAM(1)+12*SCREEN_WIDTH, 0, SCREEN_WIDTH * 18); memset(TEXT_TILE_MAP_MAIN+3*32,0, 32*2); } void print_room_content(char* text_renderer, const room_t room, const u16 slot_left, u8 top) { u8 empty = true; if (check_room_has_element(room, REXIT)) { empty = false; snprintf(text_renderer, TEXT_RENDERER_SIZE, " EXIT(%02u) ", slot_left); draw_text_at_idx(text_renderer, top, 0, TA_CENTER); ++top; } if (check_room_has_element(room, RPART)) { //INPUT() empty = false; snprintf(text_renderer, TEXT_RENDERER_SIZE, " KEY(%02u) ", get_part_id(room)); draw_text_at_idx(text_renderer, top, 0, TA_CENTER); ++top; } if (check_room_has_element(room, RSLOT)) { //OUTPUT() empty = false; snprintf(text_renderer, TEXT_RENDERER_SIZE, " LOCK(%02u) ", get_slot_id(room)); draw_text_at_idx(text_renderer, top, 0, TA_CENTER); ++top; } if (check_room_has_element(room, RTRAP)) { empty = false; snprintf(text_renderer, TEXT_RENDERER_SIZE, " SHARED "); draw_text_at_idx(text_renderer, top, 0, TA_CENTER); ++top; } if (empty == true) { //PRIVATE snprintf(text_renderer, TEXT_RENDERER_SIZE, " EMPTY "); draw_text_at_idx(text_renderer, top, 0, TA_CENTER); ++top; } } void draw_game_multi_main(const room_t room,const part_t part, const u16 slot_left, const bool taunt){ char text_renderer[TEXT_RENDERER_SIZE] = {0}; snprintf(text_renderer, TEXT_RENDERER_SIZE, "LEVEL: #"); draw_text_at_idx(text_renderer, 1, 1, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "TIME: ####"); draw_text_at_idx(text_renderer, 1, 1, TA_RIGHT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "%s", taunt ? "T" : " "); draw_text_at_idx(text_renderer, 1, 0, TA_CENTER); snprintf(text_renderer, TEXT_RENDERER_SIZE, "ROOM CONTENT"); draw_text_at_idx(text_renderer, 6, 0, TA_CENTER); print_room_content(text_renderer, room, slot_left, 8); if (part > 0) { snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: %02u (1/1)", part); } else { snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: -- (0/1) "); } draw_text_at_idx(text_renderer, 17, 1, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "SLOTS LEFT: %02u", slot_left); draw_text_at_idx(text_renderer, 19, 1, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "EXIT: %s", slot_left == 0 ? "OPEN " : "CLOSED"); draw_text_at_idx(text_renderer, 21, 1, TA_LEFT); } void draw_game_main(const game_t* const game, const u32 time) { char text_renderer[TEXT_RENDERER_SIZE] = {0}; u16 level = 0; u16 tmp = game->maze->level; while (tmp > 0) { tmp = tmp >> 1; ++level; } snprintf(text_renderer, TEXT_RENDERER_SIZE, "LEVEL: %u", level); draw_text_at_idx(text_renderer, 1, 1, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "TIME: %04u", time); draw_text_at_idx(text_renderer, 1, 1, TA_RIGHT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "%s", game->player->taunt ? "T" : " "); draw_text_at_idx(text_renderer, 1, 0, TA_CENTER); snprintf(text_renderer, TEXT_RENDERER_SIZE, "ROOM CONTENT"); draw_text_at_idx(text_renderer, 6, 0, TA_CENTER); print_room_content(text_renderer, *get_player_current_room(game->maze, game->player), game->maze->slot_left, 8); if (game->player->part > 0) { snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: %02u (1/1)", game->player->part); } else { snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: -- (0/1) "); } draw_text_at_idx(text_renderer, 17, 1, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "SLOTS LEFT: %02u", game->maze->slot_left); draw_text_at_idx(text_renderer, 19, 1, TA_LEFT); snprintf(text_renderer, TEXT_RENDERER_SIZE, "EXIT: %s", game->maze->slot_left == 0 ? "OPEN " : "CLOSED"); draw_text_at_idx(text_renderer, 21, 1, TA_LEFT); }