alchemyst/cmd/game/main.go
2019-10-30 20:23:47 +03:00

194 lines
9.8 KiB
Go

package main
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens"
"lab.zaar.be/thefish/alchemyst-go/ui"
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
"lab.zaar.be/thefish/alchemyst-go/util"
blt "lab.zaar.be/thefish/bearlibterminal"
"os"
"runtime"
"time"
)
// Рецепт чтобы убежать от [fatal] 'refresh' was not called from the main thread
// https://github.com/golang/go/wiki/LockOSThread
func init() {
runtime.LockOSThread()
}
type GameState struct {
mainfunc chan func()
exit chan struct{}
input chan string
rawInput chan int
}
var State = GameState{
mainfunc: make(chan func()),
exit: make(chan struct{}, 1),
input: make(chan string, 5),
rawInput: make(chan int, 5),
}
func main() {
config := util.LoadConfig()
var logLevels = map[string]zerolog.Level{"debug": zerolog.DebugLevel, "info": zerolog.InfoLevel, "warn": zerolog.WarnLevel}
var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}).Level(logLevels[config.Verbosity])
mainCtx := util.NewClientContext(config, &logger)
mw := mainwindow.Init(mainCtx)
defer mw.Close()
//we can run logic in separate goroutines
go mainLoop(mainCtx)
//but every call to bearlibterminal must be wrapped to closure and passed to mainfunc
var exit = false
for !exit {
select {
case f := <-State.mainfunc:
f()
case <-State.exit:
mainCtx.Logger().Warn().Msg("quitting NOW")
exit = true
break
}
}
mainCtx.Logger().Info().Msg("pre-shutdown sequence")
}
// do runs f on the main thread.
func (*GameState) Do(f func()) {
done := make(chan struct{}, 1)
State.mainfunc <- func() {
f()
done <- struct{}{}
}
<-done
}
func mainLoop(ctx util.ClientCtx) {
baseLayer := mainwindow.AddLayer(0, "white")
bgLayer := mainwindow.AddLayer(1, "white")
menuLayer := mainwindow.AddLayer(2, "white")
initRender := func() {
//fixme!!
baseLayer.WithColor("white").NewWindow(3, 0, 17, 6).NoBorder()
baseLayer.WithColor("grey").NewWindow(22, 0, 38, 6).Splash()
baseLayer.WithColor("blue").NewWindow(3, 8, 57, 6).NoBorder()
menuLayer.WithColor("#99de7c26").NewWindow(50, 1, 10, 10).Splash()
menuLayer.WithColor("#aa26edca").NewWindow(0, 5, 40, 20).DoubleBordered("Testing with long title")
blt.PrintExt(1, 6, 40, 19, 1, `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Odio morbi quis commodo odio aenean sed. Egestas sed sed risus pretium quam vulputate dignissim suspendisse in. Viverra nam libero justo laoreet sit amet cursus sit. Sed egestas egestas fringilla phasellus faucibus. Ultrices neque ornare aenean euismod elementum nisi quis eleifend. Eget lorem dolor sed viverra ipsum nunc aliquet bibendum. Egestas maecenas pharetra convallis posuere morbi. In hac habitasse platea dictumst quisque. Aenean vel elit scelerisque mauris pellentesque pulvinar.
Enim diam vulputate ut pharetra sit amet. Vestibulum mattis ullamcorper velit sed. Ultrices dui sapien eget mi. Phasellus vestibulum lorem sed risus ultricies tristique. Dignissim sodales ut eu sem integer vitae. Donec massa sapien faucibus et molestie ac. Turpis nunc eget lorem dolor sed viverra ipsum. Lectus urna duis convallis convallis tellus id interdum velit. Neque vitae tempus quam pellentesque nec nam aliquam. Ornare suspendisse sed nisi lacus sed viverra tellus in hac. Orci a scelerisque purus semper eget duis at tellus. Est ullamcorper eget nulla facilisi etiam dignissim diam. Ipsum dolor sit amet consectetur adipiscing elit. Sed egestas egestas fringilla phasellus. Eget velit aliquet sagittis id consectetur purus ut faucibus pulvinar. Malesuada fames ac turpis egestas maecenas pharetra convallis posuere morbi. Pretium quam vulputate dignissim suspendisse in est. Sit amet tellus cras adipiscing. Viverra accumsan in nisl nisi scelerisque.
Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Convallis tellus id interdum velit. Enim nunc faucibus a pellentesque. Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Leo duis ut diam quam nulla porttitor massa id. Eu feugiat pretium nibh ipsum consequat nisl. Eget est lorem ipsum dolor sit amet. Et sollicitudin ac orci phasellus egestas. Donec adipiscing tristique risus nec. Et molestie ac feugiat sed. Ante in nibh mauris cursus mattis molestie a iaculis at. Neque laoreet suspendisse interdum consectetur. Vitae et leo duis ut diam quam nulla. Sed ullamcorper morbi tincidunt ornare massa eget egestas purus viverra. Ornare lectus sit amet est placerat in egestas erat.
Cursus in hac habitasse platea. Aliquet risus feugiat in ante metus dictum. Maecenas sed enim ut sem viverra aliquet eget sit. Vitae aliquet nec ullamcorper sit amet risus nullam. Scelerisque fermentum dui faucibus in ornare quam viverra orci sagittis. Sed tempus urna et pharetra pharetra massa massa ultricies. Est ultricies integer quis auctor. Volutpat est velit egestas dui id ornare arcu. Eget nunc lobortis mattis aliquam faucibus purus. Erat nam at lectus urna duis.
Sed euismod nisi porta lorem mollis aliquam ut porttitor leo. Ut tellus elementum sagittis vitae et leo duis ut diam. Elementum curabitur vitae nunc sed velit dignissim. Auctor elit sed vulputate mi sit. Consectetur adipiscing elit ut aliquam purus. Feugiat vivamus at augue eget arcu. Duis ut diam quam nulla porttitor massa id neque. Pharetra magna ac placerat vestibulum lectus mauris ultrices. Non sodales neque sodales ut etiam. Massa ultricies mi quis hendrerit dolor. Est sit amet facilisis magna etiam. Ornare suspendisse sed nisi lacus sed viverra tellus in.
`)
menuLayer.WithColor("red").PutWithBackground(20, 40, "Ы", "#aa1257d4")
menuLayer.WithColor("white").PutWithBackground(21, 40, "Щ", "#cd31ed12")
menuLayer.WithColor("yellow").PutWithBackground(22, 40, "Ц", "#efcccccc")
menuLayer.WithColor("red").PutWithBackground(39, 1, "Ы", "#aa1257d4")
menuLayer.WithColor("white").PutWithBackground(40, 1, "Щ", "#cd31ed12")
menuLayer.WithColor("yellow").PutWithBackground(41, 1, "Ц", "#efcccccc")
bgLayer.WithColor("#77cfcfcf").NewWindow(45, 5, 40, 40).Splash()
menuLayer.WithColor("#aaed26ca").NewWindow(45, 5, 40, 40).DoubleBordered("Transparent BG window test")
blt.PrintExt(46, 6, 40, 39, 1, `Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Convallis tellus id interdum velit. Enim nunc faucibus a pellentesque. Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Leo duis ut diam quam nulla porttitor massa id. Eu feugiat pretium nibh ipsum consequat nisl. Eget est lorem ipsum dolor sit amet. Et sollicitudin ac orci phasellus egestas. Donec adipiscing tristique risus nec. Et molestie ac feugiat sed. Ante in nibh mauris cursus mattis molestie a iaculis at. Neque laoreet suspendisse interdum consectetur. Vitae et leo duis ut diam quam nulla. Sed ullamcorper morbi tincidunt ornare massa eget egestas purus viverra. Ornare lectus sit amet est placerat in egestas erat.
Cursus in hac habitasse platea. Aliquet risus feugiat in ante metus dictum. Maecenas sed enim ut sem viverra aliquet eget sit. [color=orange]Vitae[/color] aliquet nec ullamcorper sit amet risus nullam. Scelerisque fermentum dui faucibus in ornare quam viverra orci sagittis. Sed tempus urna et pharetra pharetra massa massa ultricies. Est ultricies integer quis auctor. Volutpat est velit egestas dui id ornare arcu. Eget nunc lobortis mattis aliquam faucibus purus. Erat nam at lectus urna duis.
Sed euismod nisi porta lorem mollis aliquam ut porttitor leo. Ut tellus elementum sagittis vitae et leo duis ut diam. Elementum curabitur vitae nunc sed velit dignissim. Auctor elit sed vulputate mi sit. Consectetur adipiscing elit ut aliquam purus. Feugiat vivamus at augue eget arcu. Duis ut diam quam nulla porttitor massa id neque. Pharetra magna ac placerat vestibulum lectus mauris ultrices. Non sodales neque sodales ut etiam. Massa ultricies mi quis hendrerit dolor. Est sit amet facilisis magna etiam. Ornare suspendisse sed nisi lacus sed viverra tellus in.
`)
baseLayer.Print(1, 1, "Hello, [font=bold]world[/font]!")
baseLayer.Print(1, 4, "Testing line-[color=orange]spacing[/color]")
blt.Refresh()
}
State.Do(initRender)
level := gamemap.NewLevel(ctx, "test", 1)
level = mapgens.DefaultGen(level)
vp := mainwindow.NewViewPort(40, 0, 60, 47, level, &baseLayer)
State.Do(func() {
vp.Render()
})
d, _ := time.ParseDuration("166ms") // ~6 fps for terrain
d2, _ := time.ParseDuration("1ms")
terrainAnimationTicker := time.NewTicker(d)
//fpsTicker := time.NewTicker(d2)
//main loop!
for {
select {
case <-terrainAnimationTicker.C:
//ctx.Logger().Debug().Msg("hb!")
State.Do(func() {
vp.Render()
})
case key := <-State.input:
switch key {
case "F10":
State.Do(func(){
blt.Set("window: size=100x47; font: ./resources/fonts-ttf/UbuntuMono-R.ttf, size=11;")
return
})
case "Ctrl+q":
fallthrough
case "Escape":
ctx.Logger().Info().Msg("exiting on quit command...")
State.exit <- struct{}{}
ctx.Logger().Info().Msg("...done")
return
default:
State.Do(func(){
baseLayer.ClearArea(0, 3, 80, 1)
baseLayer.Print(1, 3, "Key: "+key)
baseLayer.Print(1, 4, "█")
return
})
}
default:
State.Do(func() {
var key, keycode = ui.ReadKey(ctx)
if keycode == blt.TK_NONE {
return
}
if keycode == blt.TK_CLOSE {
ctx.Logger().Warn().Msg("exiting on window close...")
State.exit <- struct{}{}
ctx.Logger().Warn().Msg("...done")
return
}
State.input <- key
//time.Sleep(d2)
})
//update screen
State.Do(func() {
blt.Refresh()
time.Sleep(d2) //Костыль для убирания 100% CPU
})
}
}
ctx.Logger().Warn().Msg("and it continues")
}