krampus19/cmd/krampus19/krampus19.go

151 lines
3.2 KiB
Go

package main
import (
"fmt"
"io"
"log"
"time"
rice "github.com/GeertJohan/go.rice"
"github.com/spf13/afero"
"opslag.de/schobers/allg5"
"opslag.de/schobers/fs/ricefs"
"opslag.de/schobers/fs/vfs"
"opslag.de/schobers/geom"
"opslag.de/schobers/krampus19/gut"
)
//go:generate rice embed-syso
func main() {
err := run()
if err != nil {
log.Fatal(err)
}
}
func resources() (vfs.CopyDir, error) {
var embeddedFs = ricefs.NewFs(rice.MustFindBox("res"))
var osFs = afero.NewBasePathFs(afero.NewOsFs(), "./res")
return vfs.NewCopyDir(vfs.NewFallbackFs(osFs, embeddedFs))
}
func run() error {
defer log.Printf("All cleaned up, bye bye!")
cons := &gut.Console{}
log.SetOutput(io.MultiWriter(log.Writer(), cons))
res, err := resources()
if err != nil {
return err
}
defer res.Destroy()
settings := newDefaultSettings()
err = settings.LoadDefault()
if err != nil {
log.Printf("Unable to load settings, falling back on defaults.")
}
err = settings.StoreDefault()
if err != nil {
log.Printf("Unable to store settings; err: %v", err)
}
log.Printf("Initializing Allegro.")
var init = allg5.InitAll
init.Audio = false
err = allg5.Init(init)
if err != nil {
return err
}
log.Printf("Creating display.")
var size = geom.Pt(1280, 720)
dispOptions := allg5.NewDisplayOptions{Vsync: true, Fullscreen: true}
if settings.Video.Windowed {
dispOptions.Frameless = true
dispOptions.Windowed = true
} else {
dispOptions.Fullscreen = true
str := func(m allg5.DisplayMode) string { return fmt.Sprintf("%d x %d", m.Width, m.Height) }
for _, mode := range allg5.DisplayModes() {
if str(mode) == settings.Video.DisplayMode {
size = geom.Pt(mode.Width, mode.Height)
}
}
}
disp, err := allg5.NewDisplay(size.X, size.Y, dispOptions)
if err != nil {
return err
}
defer disp.Destroy()
iconPath, err := res.Retrieve("icon.png")
if err != nil {
log.Printf("Unable to retrieve icon.")
} else {
icon, err := allg5.LoadBitmap(iconPath)
if err != nil {
log.Printf("Unable to load icon bitmap.")
} else {
defer icon.Destroy()
disp.SetIcon(icon)
}
}
eq, err := allg5.NewEventQueue()
if err != nil {
return err
}
defer eq.Destroy()
eq.RegisterDisplay(disp)
eq.RegisterKeyboard()
eq.RegisterMouse()
fps := gut.NewFPS()
defer fps.Destroy()
game := &game{}
err = game.Init(disp, settings, res, cons, fps)
if err != nil {
return err
}
defer game.Destroy()
log.Printf("Starting game loop")
defer log.Printf("Stopped game loop, cleaning up")
start := time.Now()
for {
game.ctx.Tick = time.Now().Sub(start)
allg5.ClearToColor(game.ctx.Palette.Icon)
game.Render()
disp.Flip()
fps.Count()
e := eq.Get()
for e != nil {
switch e := e.(type) {
case *allg5.DisplayCloseEvent:
log.Printf("Stopping game loop, user closed display")
return nil
case *allg5.KeyCharEvent:
if e.KeyCode == allg5.KeyF4 && e.Modifiers&allg5.KeyModAlt != 0 {
log.Printf("Stopping game loop, user pressed Alt+F4")
return nil
}
case *allg5.DisplayResizeEvent:
game.ctx.DisplaySize = geom.Pt(disp.Width(), disp.Height())
}
game.Handle(e)
e = eq.Get()
}
if game.scene.Proxy == nil {
log.Printf("Stopping game loop, user quit via an in-game option")
return nil
}
}
}