Fonts are now baked in with #load and loaded via LoadFontFromMemory instead of LoadFontEx reading assets/*.ttf from disk, so a build no longer needs an assets/ folder next to it at runtime - the chdir to the executable's own directory in main.odin is dead code, removed. just package / just package-windows now produce a single executable (build/<name>_<version>_<os>_<arch>[.exe]) instead of a tar.gz/zip, and the release workflow's upload/release-asset globs and the lld/zip toolchain package list are updated to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
113 lines
3.3 KiB
Odin
113 lines
3.3 KiB
Odin
package main
|
|
|
|
import "core:fmt"
|
|
import "core:reflect"
|
|
import raylib "vendor:raylib"
|
|
import assets "src/assets"
|
|
import audio "src/audio"
|
|
import card "src/card"
|
|
import decks "src/decks"
|
|
import memory "src/memory"
|
|
import profile "src/profile"
|
|
import screens "src/screens"
|
|
import themes "src/themes"
|
|
import ui "src/ui"
|
|
|
|
TRANSITION_SPEED :: 4 // screen fade-ins per second
|
|
|
|
// Where Escape takes you from each screen (nil = quit)
|
|
parent_screen :: proc(screen: themes.Screen) -> Maybe(themes.Screen) {
|
|
switch screen {
|
|
case .MAIN_MENU: return nil
|
|
case .LANGUAGE_MENU: return .MAIN_MENU
|
|
case .MEMORY: return .LANGUAGE_MENU
|
|
}
|
|
return nil
|
|
}
|
|
|
|
main :: proc() {
|
|
raylib.SetConfigFlags({.MSAA_4X_HINT, .VSYNC_HINT})
|
|
raylib.InitWindow(themes.SCREEN_WIDTH, themes.SCREEN_HEIGHT, "HanjaKanaMun")
|
|
defer raylib.CloseWindow()
|
|
raylib.SetExitKey(.KEY_NULL)
|
|
raylib.SetTargetFPS(60)
|
|
|
|
raylib.InitAudioDevice()
|
|
defer raylib.CloseAudioDevice()
|
|
audio.load()
|
|
defer audio.unload()
|
|
|
|
assets.load_fonts()
|
|
defer assets.unload_fonts()
|
|
card.load_art()
|
|
defer card.unload_art()
|
|
defer memory.unload()
|
|
|
|
if !profile.init() {
|
|
raylib.TraceLog(.WARNING, "PROFILE: Could not read saved scores, starting fresh")
|
|
}
|
|
|
|
screen := themes.Screen.MAIN_MENU
|
|
language := decks.Language.JAPANESE
|
|
difficulty := memory.Difficulty.NORMAL
|
|
if saved, ok := reflect.enum_from_name(memory.Difficulty, profile.data.difficulty); ok {
|
|
difficulty = saved
|
|
}
|
|
transition_t: f32 = 1 // fades the screen in from the background color
|
|
running := true
|
|
for running && !raylib.WindowShouldClose() {
|
|
dt := raylib.GetFrameTime()
|
|
|
|
if raylib.IsKeyPressed(.ESCAPE) {
|
|
if parent, ok := parent_screen(screen).?; ok {
|
|
screen = parent
|
|
transition_t = 1
|
|
} else {
|
|
running = false
|
|
}
|
|
}
|
|
|
|
if screen == .MEMORY {
|
|
memory.update(dt)
|
|
}
|
|
|
|
raylib.BeginDrawing()
|
|
ui.begin_frame()
|
|
next := screen
|
|
start_deck: Maybe(decks.Deck_Id)
|
|
switch screen {
|
|
case .MAIN_MENU:
|
|
if picked, ok := screens.main_menu().?; ok {
|
|
language = picked
|
|
next = .LANGUAGE_MENU
|
|
}
|
|
case .LANGUAGE_MENU:
|
|
switch result in screens.language_menu(language, &difficulty) {
|
|
case decks.Deck_Id:
|
|
start_deck = result
|
|
next = .MEMORY
|
|
case themes.Screen:
|
|
next = result
|
|
}
|
|
case .MEMORY:
|
|
next = memory.draw()
|
|
}
|
|
if transition_t > 0 {
|
|
alpha := transition_t * transition_t
|
|
raylib.DrawRectangle(0, 0, themes.SCREEN_WIDTH, themes.SCREEN_HEIGHT, raylib.Fade(themes.MENU_BACKGROUND, alpha))
|
|
transition_t = max(transition_t - dt * TRANSITION_SPEED, 0)
|
|
}
|
|
ui.end_frame()
|
|
raylib.EndDrawing()
|
|
free_all(context.temp_allocator)
|
|
profile.set_difficulty(fmt.tprintf("%v", difficulty))
|
|
|
|
// Building card faces renders into textures, so do it outside of drawing
|
|
if deck, ok := start_deck.?; ok {
|
|
memory.start(deck, difficulty)
|
|
}
|
|
if next != screen { transition_t = 1 }
|
|
screen = next
|
|
}
|
|
}
|