Files
HanjaKanaMun/main.odin
T
SansanandClaude Opus 5.5 9ee2eabe9a Add justfile, ols/odinfmt config, tests and Gitea workflows; drop odin.json
- justfile with build/run/check/test/release/package/fmt/clean recipes
- ols.json and odinfmt.json for neovim (ols)
- Tests for memory game rules and card animation; memory.deal and
  memory.select_card split out so logic is testable without a window
- Gitea workflows: build+test on main/develop, package and upload to the
  generic package registry on version branches
- Game changes to the executable's directory so packaged builds find assets

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:04:08 +02:00

80 lines
2.3 KiB
Odin

package main
import raylib "vendor:raylib"
import assets "src/assets"
import audio "src/audio"
import card "src/card"
import memory "src/memory"
import screens "src/screens"
import themes "src/themes"
import ui "src/ui"
// 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 .JAPANESE_MEMORY: return .JAPANESE_MENU
case .JAPANESE_MENU, .KOREAN_MENU, .THAI_MENU: return .MAIN_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)
// Assets are loaded relative to the executable, so it can be started from anywhere
raylib.ChangeDirectory(raylib.GetApplicationDirectory())
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()
screen := themes.Screen.MAIN_MENU
running := true
for running && !raylib.WindowShouldClose() {
dt := raylib.GetFrameTime()
if raylib.IsKeyPressed(.ESCAPE) {
if parent, ok := parent_screen(screen).?; ok {
screen = parent
} else {
running = false
}
}
if screen == .JAPANESE_MEMORY {
memory.update(dt)
}
raylib.BeginDrawing()
ui.begin_frame()
next := screen
switch screen {
case .MAIN_MENU: next = screens.main_menu()
case .JAPANESE_MENU: next = screens.japanese_menu()
case .JAPANESE_MEMORY: next = memory.draw()
case .KOREAN_MENU: next = screens.korean_menu()
case .THAI_MENU: next = screens.thai_menu()
}
ui.end_frame()
raylib.EndDrawing()
// Start a fresh game when entering the memory screen (outside of drawing,
// because building card faces renders into textures)
if next == .JAPANESE_MEMORY && screen != .JAPANESE_MEMORY {
memory.start(themes.JAPAN)
}
screen = next
}
}