main.go (2263B)
1 package main 2 3 import ( 4 "context" 5 "flag" 6 "os" 7 "os/signal" 8 "path/filepath" 9 "syscall" 10 "time" 11 12 "code.dwrz.net/src/pkg/log" 13 "code.dwrz.net/src/pkg/minotaur" 14 "code.dwrz.net/src/pkg/terminal" 15 ) 16 17 var ( 18 height = flag.Int("h", 0, "height") 19 width = flag.Int("w", 0, "width") 20 tick = flag.Int("t", 250, "ms between minotaur movement") 21 ) 22 23 func main() { 24 var l = log.New(os.Stderr) 25 26 // Parse flags. 27 flag.Parse() 28 if *height < 0 { 29 l.Error.Fatalf("invalid height: %d", *height) 30 } 31 if *width < 0 { 32 l.Error.Fatalf("invalid width: %d", *width) 33 } 34 if *tick <= 0 { 35 l.Error.Fatalf("invalid tick: %d", *tick) 36 } 37 38 // Setup the main context. 39 ctx, cancel := context.WithCancel(context.Background()) 40 41 // Setup workspace and log file. 42 cdir, err := os.UserCacheDir() 43 if err != nil { 44 l.Error.Fatalf( 45 "failed to determine user cache directory: %v", err, 46 ) 47 } 48 wdir := filepath.Join(cdir, "minotaur") 49 50 if err := os.MkdirAll(wdir, os.ModeDir|0700); err != nil { 51 l.Error.Fatalf("failed to create tmp dir: %v", err) 52 } 53 54 f, err := os.Create(wdir + "/log") 55 if err != nil { 56 l.Error.Fatalf("failed to create log file: %v", err) 57 } 58 defer f.Close() 59 60 // Retrieve terminal info. 61 t, err := terminal.New(os.Stdin.Fd()) 62 if err != nil { 63 l.Error.Fatalf("failed to get terminal attributes: %v", err) 64 } 65 size, err := t.Size() 66 if err != nil { 67 l.Error.Fatalf("failed to get terminal size: %v", err) 68 } 69 // If no dimensions were provided, use the terminal size. 70 if *height == 0 { 71 rows := int(size.Rows) 72 height = &rows 73 } 74 if *width == 0 { 75 cols := int(size.Columns) 76 width = &cols 77 } 78 79 // TODO: refactor; handle sigwinch. 80 go func() { 81 var signals = make(chan os.Signal, 1) 82 signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) 83 84 // Block until we receive a signal. 85 s := <-signals 86 l.Debug.Printf("received signal: %s", s) 87 88 cancel() 89 }() 90 91 // Setup the game. 92 game, err := minotaur.New(minotaur.Parameters{ 93 Height: *height, 94 In: os.Stdin, 95 Log: log.New(f), 96 Out: os.Stdout, 97 Terminal: t, 98 Tick: time.Duration(*tick) * time.Millisecond, 99 Width: *width, 100 }) 101 if err != nil { 102 l.Error.Fatalf("failed to create game: %v", err) 103 } 104 105 // Run the game. 106 if err := game.Run(ctx); err != nil { 107 l.Error.Fatal(err) 108 } 109 }