Files
rgoue/cmd/rogue/main.go
sneak 43c59b7f82 Update module base path to git.eeqj.de/sneak/rgoue
go.mod, term/ and cmd/ imports, the ARCHITECTURE.md module references,
and the in-game version string. User request; the repo already lives
at this remote.
2026-07-06 23:10:39 +02:00

102 lines
1.9 KiB
Go

// Command rogue is the Go port of Rogue 5.4.4: Exploring the Dungeons of
// Doom. It is a faithful function-by-function port of the classic C game;
// see ARCHITECTURE.md at the repository root.
package main
import (
"flag"
"fmt"
"os"
"os/signal"
"os/user"
"strconv"
"syscall"
"time"
"git.eeqj.de/sneak/rgoue/game"
"git.eeqj.de/sneak/rgoue/term"
)
func main() {
scores := flag.Bool("s", false, "print the scoreboard and exit")
deathDemo := flag.Bool("d", false, "die a random death (demo)")
flag.Parse()
home, _ := os.UserHomeDir()
// get options from environment (main.c)
rogueOpts := os.Getenv("ROGUEOPTS")
name := ""
if u, err := user.Current(); err == nil {
name = u.Username
}
wizard := os.Getenv("ROGUE_WIZARD") != ""
// dungeon number: SEED for reproducible dungeons (wizard mode in C),
// else time+pid
var seed int32
if env := os.Getenv("SEED"); env != "" && wizard {
n, _ := strconv.Atoi(env)
seed = int32(n)
} else {
seed = int32(time.Now().Unix()) + int32(os.Getpid())
}
cfg := game.Config{
Seed: seed,
Name: name,
RogueOpts: rogueOpts,
Home: home,
ScorePath: home + "/.rogue.scores",
Wizard: wizard,
}
if *scores {
g := game.NewGame(cfg)
g.ShowScores()
return
}
t, err := term.New()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer t.Fini()
cfg.Term = t
var g *game.RogueGame
if args := flag.Args(); len(args) == 1 && !*deathDemo {
// restore a saved game
g, err = game.Restore(args[0], cfg)
if err != nil {
t.Fini()
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
} else {
g = game.NewGame(cfg)
}
if *deathDemo {
g.DeathDemo()
return
}
// SIGHUP/SIGTERM autosave (save.c auto_save)
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGHUP, syscall.SIGTERM)
go func() {
<-sig
g.AutoSave()
t.Fini()
os.Exit(0)
}()
if err := g.Run(); err != nil {
t.Fini()
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}