package screens import "core:fmt" import "core:math" import "core:strings" import raylib "vendor:raylib" import card "../card" import decks "../decks" import memory "../memory" import profile "../profile" import themes "../themes" import ui "../ui" // Draws a card back like a playing card lying on the table @(private) draw_card_art :: proc(flag: themes.Flag, rect: raylib.Rectangle, rotation: f32 = 0) { texture := card.get_back_art(flag) source := raylib.Rectangle{0, 0, f32(texture.width), -f32(texture.height)} dest := raylib.Rectangle{rect.x + rect.width / 2, rect.y + rect.height / 2, rect.width, rect.height} origin := raylib.Vector2{rect.width / 2, rect.height / 2} shadow := dest shadow.x += 3 shadow.y += 6 raylib.DrawRectanglePro(shadow, origin, rotation, raylib.Fade(themes.BLACK, 0.15)) raylib.DrawTexturePro(texture, source, dest, origin, rotation, themes.WHITE) } @(private) NUMBER_KEYS :: [?]raylib.KeyboardKey{.ONE, .TWO, .THREE, .FOUR, .FIVE} // Returns the language picked this frame, if any main_menu :: proc() -> Maybe(decks.Language) { raylib.ClearBackground(themes.MENU_BACKGROUND) languages := decks.LANGUAGES keys := NUMBER_KEYS // Thin stripes along the top in each language's primary color stripe_w: i32 = themes.SCREEN_WIDTH / len(decks.Language) for lang, i in languages { raylib.DrawRectangle(i32(i) * stripe_w, 0, stripe_w, 8, lang.theme.primary) } ui.draw_title("HanjaKanaMun", 70, themes.SUMI_INK, 84) ui.draw_text_centered("Learn Japanese, Korean and Thai scripts", themes.SCREEN_WIDTH / 2, 170, themes.SUBTITLE_FONT_SIZE, themes.DARK_GRAY) tile_w: f32 = 150 tile_h: f32 = 200 gap: f32 = 110 total := 3 * tile_w + 2 * gap start_x := (themes.SCREEN_WIDTH - total) / 2 // Gentle bobbing so the menu feels alive time := f32(raylib.GetTime()) picked: Maybe(decks.Language) for lang, language in languages { i := int(language) x := start_x + f32(i) * (tile_w + gap) bob := math.sin(time * 1.6 + f32(i) * 1.1) * 4 rotation := f32(i - 1) * 4 draw_card_art(lang.theme.flag, {x, 250 + bob, tile_w, tile_h}, rotation) button_rect := raylib.Rectangle{x + tile_w / 2 - (themes.BUTTON_WIDTH - 60) / 2, 500, themes.BUTTON_WIDTH - 60, themes.BUTTON_HEIGHT} if ui.button(button_rect, lang.theme.name, lang.theme.primary, hotkey = keys[i]) { picked = language } } ui.draw_text_centered("1-3 pick a language · In game: arrows, WASD or hjkl to move, Enter/Space to flip · Esc back / quit", themes.SCREEN_WIDTH / 2, 660, 18, raylib.Fade(themes.DARK_GRAY, 0.8)) return picked } Language_Menu_Result :: union { decks.Deck_Id, // start a game with this deck themes.Screen, // go to another screen } // A language's menu: pick a deck and a difficulty language_menu :: proc(language: decks.Language, difficulty: ^memory.Difficulty) -> Language_Menu_Result { info := decks.LANGUAGES[language] theme := info.theme keys := NUMBER_KEYS raylib.ClearBackground(theme.background) raylib.DrawRectangle(0, 0, themes.SCREEN_WIDTH, 8, theme.primary) ui.draw_title(theme.name, 50, theme.primary) ui.draw_text_centered(info.native, themes.SCREEN_WIDTH / 2, 140, 30, theme.ink, info.symbol_style) // A small fan of card backs for i in 0 ..< 3 { offset := f32(i - 1) draw_card_art(theme.flag, {themes.SCREEN_WIDTH / 2 - 50 + offset * 64, 195 + abs(offset) * 10, 100, 133}, offset * 9) } result: Language_Menu_Result // One button per deck deck_list := decks.decks_for(language) button_w: f32 = 220 gap: f32 = 24 total := f32(len(deck_list)) * button_w + f32(len(deck_list) - 1) * gap x := (themes.SCREEN_WIDTH - total) / 2 for deck, i in deck_list { rect := raylib.Rectangle{x, 380, button_w, themes.BUTTON_HEIGHT} if ui.button(rect, decks.DECKS[deck].name, theme.primary, hotkey = keys[i]) { result = deck } ui.draw_text_centered(decks.DECKS[deck].native, x + button_w / 2, 448, 22, theme.ink, info.symbol_style) best_text := cstring("No games yet") if record, ok := profile.get(memory.score_key(deck, difficulty^)); ok { best_text = strings.clone_to_cstring(fmt.tprintf("Best %d moves · %s", record.best_moves, profile.format_time(record.best_seconds)), context.temp_allocator) } ui.draw_text_centered(best_text, x + button_w / 2, 476, 17, raylib.Fade(theme.ink, 0.65)) x += button_w + gap } // Difficulty selector names := memory.DIFFICULTY_NAMES layouts := memory.LAYOUTS ui.draw_text_centered("Difficulty (Left / Right)", themes.SCREEN_WIDTH / 2, 512, 20, raylib.Fade(theme.ink, 0.7)) seg_w: f32 = 150 seg_x := (themes.SCREEN_WIDTH - 3 * seg_w - 2 * 12) / 2 for level in memory.Difficulty { selected := difficulty^ == level color := selected ? theme.primary : raylib.ColorLerp(theme.primary, themes.WHITE, 0.55) label := raylib.TextFormat("%s %d", names[level], layouts[level].rows * layouts[level].cols / 2) if ui.button({seg_x, 542, seg_w, 48}, label, color, font_size = 22, selected = selected) { difficulty^ = level } seg_x += seg_w + 12 } if raylib.IsKeyPressed(.LEFT) && difficulty^ > .EASY { difficulty^ = memory.Difficulty(int(difficulty^) - 1) } if raylib.IsKeyPressed(.RIGHT) && difficulty^ < .HARD { difficulty^ = memory.Difficulty(int(difficulty^) + 1) } if ui.button({30, 28, 120, 48}, "Back", theme.ink, font_size = 22) { result = themes.Screen.MAIN_MENU } hint := len(deck_list) > 1 ? cstring("1-2 pick a deck · Left / Right difficulty · Esc back") : cstring("1 start · Left / Right difficulty · Esc back") ui.draw_text_centered(hint, themes.SCREEN_WIDTH / 2, 660, 18, raylib.Fade(theme.ink, 0.6)) return result }