mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 07:27:19 -05:00
removed d2term singleton (#483)
This commit is contained in:
parent
3f575cf1d8
commit
09a28c2822
58
d2common/d2interface/terminal.go
Normal file
58
d2common/d2interface/terminal.go
Normal file
@ -0,0 +1,58 @@
|
||||
package d2interface
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
type TermCategory int
|
||||
|
||||
const (
|
||||
TermCategoryNone TermCategory = iota
|
||||
TermCategoryInfo
|
||||
TermCategoryWarning
|
||||
TermCategoryError
|
||||
)
|
||||
|
||||
const (
|
||||
termCharWidth = 6
|
||||
termCharHeight = 16
|
||||
termRowCount = 24
|
||||
termRowCountMax = 32
|
||||
termColCountMax = 128
|
||||
termAnimLength = 0.5
|
||||
)
|
||||
|
||||
type termVis int
|
||||
|
||||
const (
|
||||
termVisHidden termVis = iota
|
||||
termVisShowing
|
||||
termVisShown
|
||||
termVisHiding
|
||||
)
|
||||
|
||||
type Terminal interface {
|
||||
BindLogger()
|
||||
|
||||
Advance(elapsed float64) error
|
||||
OnKeyDown(event d2input.KeyEvent) bool
|
||||
OnKeyChars(event d2input.KeyCharsEvent) bool
|
||||
Render(surface d2render.Surface) error
|
||||
Execute(command string) error
|
||||
OutputRaw(text string, category TermCategory)
|
||||
Output(format string, params ...interface{})
|
||||
OutputInfo(format string, params ...interface{})
|
||||
OutputWarning(format string, params ...interface{})
|
||||
OutputError(format string, params ...interface{})
|
||||
OutputClear()
|
||||
IsVisible() bool
|
||||
Hide()
|
||||
Show()
|
||||
BindAction(name, description string, action interface{}) error
|
||||
UnbindAction(name string) error
|
||||
}
|
||||
|
||||
type TerminalLogger interface {
|
||||
Write(p []byte) (int, error)
|
||||
}
|
@ -6,15 +6,15 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2pl2"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
||||
)
|
||||
|
||||
var singleton *assetManager
|
||||
|
||||
func Initialize() error {
|
||||
func Initialize(term d2interface.Terminal) error {
|
||||
verifyNotInit()
|
||||
|
||||
var (
|
||||
@ -36,11 +36,11 @@ func Initialize() error {
|
||||
fontManager,
|
||||
}
|
||||
|
||||
d2term.BindAction("assetspam", "display verbose asset manager logs", func(verbose bool) {
|
||||
term.BindAction("assetspam", "display verbose asset manager logs", func(verbose bool) {
|
||||
if verbose {
|
||||
d2term.OutputInfo("asset manager verbose logging enabled")
|
||||
term.OutputInfo("asset manager verbose logging enabled")
|
||||
} else {
|
||||
d2term.OutputInfo("asset manager verbose logging disabled")
|
||||
term.OutputInfo("asset manager verbose logging disabled")
|
||||
}
|
||||
|
||||
archiveManager.cache.SetVerbose(verbose)
|
||||
@ -50,16 +50,16 @@ func Initialize() error {
|
||||
animationManager.cache.SetVerbose(verbose)
|
||||
})
|
||||
|
||||
d2term.BindAction("assetstat", "display asset manager cache statistics", func() {
|
||||
d2term.OutputInfo("archive cache: %f", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
|
||||
d2term.OutputInfo("file cache: %f", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
|
||||
d2term.OutputInfo("palette cache: %f", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
|
||||
d2term.OutputInfo("palette transform cache: %f", float64(paletteTransformManager.cache.GetWeight())/float64(paletteTransformManager.cache.GetBudget())*100.0)
|
||||
d2term.OutputInfo("animation cache: %f", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
|
||||
d2term.OutputInfo("font cache: %f", float64(fontManager.cache.GetWeight())/float64(fontManager.cache.GetBudget())*100.0)
|
||||
term.BindAction("assetstat", "display asset manager cache statistics", func() {
|
||||
term.OutputInfo("archive cache: %f", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfo("file cache: %f", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfo("palette cache: %f", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfo("palette transform cache: %f", float64(paletteTransformManager.cache.GetWeight())/float64(paletteTransformManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfo("animation cache: %f", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfo("font cache: %f", float64(fontManager.cache.GetWeight())/float64(fontManager.cache.GetBudget())*100.0)
|
||||
})
|
||||
|
||||
d2term.BindAction("assetclear", "clear asset manager cache", func() {
|
||||
term.BindAction("assetclear", "clear asset manager cache", func() {
|
||||
archiveManager.cache.Clear()
|
||||
fileManager.cache.Clear()
|
||||
paletteManager.cache.Clear()
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
||||
)
|
||||
|
||||
// The map renderer, used to render the map
|
||||
@ -30,7 +30,7 @@ type MapRenderer struct {
|
||||
}
|
||||
|
||||
// Creates an instance of the map renderer
|
||||
func CreateMapRenderer(mapEngine *d2mapengine.MapEngine) *MapRenderer {
|
||||
func CreateMapRenderer(mapEngine *d2mapengine.MapEngine, term d2interface.Terminal) *MapRenderer {
|
||||
result := &MapRenderer{
|
||||
mapEngine: mapEngine,
|
||||
viewport: NewViewport(0, 0, 800, 600),
|
||||
@ -38,7 +38,7 @@ func CreateMapRenderer(mapEngine *d2mapengine.MapEngine) *MapRenderer {
|
||||
|
||||
result.viewport.SetCamera(&result.camera)
|
||||
|
||||
d2term.BindAction("mapdebugvis", "set map debug visualization level", func(level int) {
|
||||
term.BindAction("mapdebugvis", "set map debug visualization level", func(level int) {
|
||||
result.debugVisLevel = level
|
||||
})
|
||||
|
||||
|
@ -1,88 +1,19 @@
|
||||
package d2term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrWasInit = errors.New("terminal system is already initialized")
|
||||
ErrNotInit = errors.New("terminal system is not initialized")
|
||||
)
|
||||
func Initialize() (*terminal, error) {
|
||||
|
||||
var singleton *terminal
|
||||
|
||||
func Initialize() error {
|
||||
verifyNotInit()
|
||||
|
||||
terminal, err := createTerminal()
|
||||
term, err := createTerminal()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := d2input.BindHandlerWithPriority(terminal, d2input.PriorityHigh); err != nil {
|
||||
return err
|
||||
if err := d2input.BindHandlerWithPriority(term, d2input.PriorityHigh); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
singleton = terminal
|
||||
return nil
|
||||
}
|
||||
|
||||
func Advance(elapsed float64) error {
|
||||
verifyWasInit()
|
||||
return singleton.advance(elapsed)
|
||||
}
|
||||
|
||||
func Output(format string, params ...interface{}) {
|
||||
verifyWasInit()
|
||||
singleton.output(format, params...)
|
||||
}
|
||||
|
||||
func OutputInfo(format string, params ...interface{}) {
|
||||
verifyWasInit()
|
||||
singleton.outputInfo(format, params...)
|
||||
}
|
||||
|
||||
func OutputWarning(format string, params ...interface{}) {
|
||||
verifyWasInit()
|
||||
singleton.outputWarning(format, params...)
|
||||
}
|
||||
|
||||
func OutputError(format string, params ...interface{}) {
|
||||
verifyWasInit()
|
||||
singleton.outputError(format, params...)
|
||||
}
|
||||
|
||||
func BindAction(name, description string, action interface{}) error {
|
||||
verifyWasInit()
|
||||
return singleton.bindAction(name, description, action)
|
||||
}
|
||||
|
||||
func UnbindAction(name string) error {
|
||||
verifyWasInit()
|
||||
return singleton.unbindAction(name)
|
||||
}
|
||||
|
||||
func Render(surface d2render.Surface) error {
|
||||
verifyWasInit()
|
||||
return singleton.render(surface)
|
||||
}
|
||||
|
||||
func BindLogger() {
|
||||
log.SetOutput(&terminalLogger{writer: log.Writer()})
|
||||
}
|
||||
|
||||
func verifyWasInit() {
|
||||
if singleton == nil {
|
||||
panic(ErrNotInit)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyNotInit() {
|
||||
if singleton != nil {
|
||||
panic(ErrWasInit)
|
||||
}
|
||||
return term, nil
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package d2term
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
@ -14,10 +12,20 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
type TermCategory d2interface.TermCategory
|
||||
|
||||
const (
|
||||
TermCategoryNone = TermCategory(d2interface.TermCategoryNone)
|
||||
TermCategoryInfo = TermCategory(d2interface.TermCategoryInfo)
|
||||
TermCategoryWarning = TermCategory(d2interface.TermCategoryWarning)
|
||||
TermCategoryError = TermCategory(d2interface.TermCategoryError)
|
||||
)
|
||||
const (
|
||||
termCharWidth = 6
|
||||
termCharHeight = 16
|
||||
@ -27,15 +35,6 @@ const (
|
||||
termAnimLength = 0.5
|
||||
)
|
||||
|
||||
type termCategory int
|
||||
|
||||
const (
|
||||
termCategoryNone termCategory = iota
|
||||
termCategoryInfo
|
||||
termCategoryWarning
|
||||
termCategoryError
|
||||
)
|
||||
|
||||
type termVis int
|
||||
|
||||
const (
|
||||
@ -55,7 +54,7 @@ var (
|
||||
|
||||
type termHistroyEntry struct {
|
||||
text string
|
||||
category termCategory
|
||||
category d2interface.TermCategory
|
||||
}
|
||||
|
||||
type termActionEntry struct {
|
||||
@ -78,37 +77,7 @@ type terminal struct {
|
||||
actions map[string]termActionEntry
|
||||
}
|
||||
|
||||
func createTerminal() (*terminal, error) {
|
||||
terminal := &terminal{
|
||||
lineCount: termRowCount,
|
||||
actions: make(map[string]termActionEntry),
|
||||
}
|
||||
|
||||
terminal.outputInfo("::: OpenDiablo2 Terminal :::")
|
||||
terminal.outputInfo("type \"ls\" for a list of actions")
|
||||
|
||||
terminal.bindAction("ls", "list available actions", func() {
|
||||
var names []string
|
||||
for name := range terminal.actions {
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
sort.Strings(names)
|
||||
|
||||
terminal.outputInfo("available actions (%d):", len(names))
|
||||
for _, name := range names {
|
||||
entry := terminal.actions[name]
|
||||
terminal.outputInfo("%s: %s; %s", name, entry.description, reflect.TypeOf(entry.action).String())
|
||||
}
|
||||
})
|
||||
terminal.bindAction("clear", "clear terminal", func() {
|
||||
terminal.outputClear()
|
||||
})
|
||||
|
||||
return terminal, nil
|
||||
}
|
||||
|
||||
func (t *terminal) advance(elapsed float64) error {
|
||||
func (t *terminal) Advance(elapsed float64) error {
|
||||
switch t.visState {
|
||||
case termVisShowing:
|
||||
t.visAnim = math.Min(1.0, t.visAnim+elapsed/termAnimLength)
|
||||
@ -122,7 +91,7 @@ func (t *terminal) advance(elapsed float64) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !t.isVisible() {
|
||||
if !t.IsVisible() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -131,16 +100,16 @@ func (t *terminal) advance(elapsed float64) error {
|
||||
|
||||
func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
if t.visState == termVisHiding || t.visState == termVisHidden && event.Key == d2input.KeyGraveAccent {
|
||||
t.show()
|
||||
t.Show()
|
||||
return true
|
||||
}
|
||||
|
||||
if !t.isVisible() {
|
||||
if !t.IsVisible() {
|
||||
return false
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyGraveAccent {
|
||||
t.hide()
|
||||
t.Hide()
|
||||
return true
|
||||
}
|
||||
|
||||
@ -149,10 +118,10 @@ func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
maxOutputIndex := d2common.MaxInt(0, len(t.outputHistory)-t.lineCount)
|
||||
maxoutputIndex := d2common.MaxInt(0, len(t.outputHistory)-t.lineCount)
|
||||
|
||||
if event.Key == d2input.KeyHome {
|
||||
t.outputIndex = maxOutputIndex
|
||||
t.outputIndex = maxoutputIndex
|
||||
return true
|
||||
}
|
||||
|
||||
@ -162,8 +131,8 @@ func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyPageUp {
|
||||
if t.outputIndex += t.lineCount; t.outputIndex >= maxOutputIndex {
|
||||
t.outputIndex = maxOutputIndex
|
||||
if t.outputIndex += t.lineCount; t.outputIndex >= maxoutputIndex {
|
||||
t.outputIndex = maxoutputIndex
|
||||
}
|
||||
|
||||
return true
|
||||
@ -207,9 +176,9 @@ func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
|
||||
t.commandHistory = append(commandHistory, t.command)
|
||||
|
||||
t.output(t.command)
|
||||
if err := t.execute(t.command); err != nil {
|
||||
t.outputError(err.Error())
|
||||
t.Output(t.command)
|
||||
if err := t.Execute(t.command); err != nil {
|
||||
t.OutputError(err.Error())
|
||||
}
|
||||
|
||||
t.commandIndex = len(t.commandHistory) - 1
|
||||
@ -227,7 +196,7 @@ func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
}
|
||||
|
||||
func (t *terminal) OnKeyChars(event d2input.KeyCharsEvent) bool {
|
||||
if !t.isVisible() {
|
||||
if !t.IsVisible() {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -242,8 +211,8 @@ func (t *terminal) OnKeyChars(event d2input.KeyCharsEvent) bool {
|
||||
return handled
|
||||
}
|
||||
|
||||
func (t *terminal) render(surface d2render.Surface) error {
|
||||
if !t.isVisible() {
|
||||
func (t *terminal) Render(surface d2render.Surface) error {
|
||||
if !t.IsVisible() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -267,11 +236,11 @@ func (t *terminal) render(surface d2render.Surface) error {
|
||||
surface.DrawText(historyEntry.text)
|
||||
surface.PushTranslation(-termCharWidth*2, 0)
|
||||
switch historyEntry.category {
|
||||
case termCategoryInfo:
|
||||
case d2interface.TermCategoryInfo:
|
||||
surface.DrawRect(termCharWidth, termCharHeight, termInfoColor)
|
||||
case termCategoryWarning:
|
||||
case d2interface.TermCategoryWarning:
|
||||
surface.DrawRect(termCharWidth, termCharHeight, termWarningColor)
|
||||
case termCategoryError:
|
||||
case d2interface.TermCategoryError:
|
||||
surface.DrawRect(termCharWidth, termCharHeight, termErrorColor)
|
||||
}
|
||||
surface.Pop()
|
||||
@ -288,7 +257,7 @@ func (t *terminal) render(surface d2render.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) execute(command string) error {
|
||||
func (t *terminal) Execute(command string) error {
|
||||
params := parseCommand(command)
|
||||
if len(params) == 0 {
|
||||
return errors.New("invalid command")
|
||||
@ -349,16 +318,16 @@ func (t *terminal) execute(command string) error {
|
||||
actionReturnValues := actionValue.Call(paramValues)
|
||||
|
||||
if actionReturnValueCount := len(actionReturnValues); actionReturnValueCount > 0 {
|
||||
t.outputInfo("function returned %d values:", actionReturnValueCount)
|
||||
t.OutputInfo("function returned %d values:", actionReturnValueCount)
|
||||
for _, actionReturnValue := range actionReturnValues {
|
||||
t.outputInfo("%v: %s", actionReturnValue.Interface(), actionReturnValue.String())
|
||||
t.OutputInfo("%v: %s", actionReturnValue.Interface(), actionReturnValue.String())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) outputRaw(text string, category termCategory) {
|
||||
func (t *terminal) OutputRaw(text string, category d2interface.TermCategory) {
|
||||
var line string
|
||||
for _, word := range strings.Split(text, " ") {
|
||||
if len(line) > 0 {
|
||||
@ -379,44 +348,44 @@ func (t *terminal) outputRaw(text string, category termCategory) {
|
||||
t.outputHistory = append(t.outputHistory, termHistroyEntry{line, category})
|
||||
}
|
||||
|
||||
func (t *terminal) output(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryNone)
|
||||
func (t *terminal) Output(format string, params ...interface{}) {
|
||||
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryNone)
|
||||
}
|
||||
|
||||
func (t *terminal) outputInfo(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryInfo)
|
||||
func (t *terminal) OutputInfo(format string, params ...interface{}) {
|
||||
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryInfo)
|
||||
}
|
||||
|
||||
func (t *terminal) outputWarning(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryWarning)
|
||||
func (t *terminal) OutputWarning(format string, params ...interface{}) {
|
||||
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryWarning)
|
||||
}
|
||||
|
||||
func (t *terminal) outputError(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryError)
|
||||
func (t *terminal) OutputError(format string, params ...interface{}) {
|
||||
t.OutputRaw(fmt.Sprintf(format, params...), d2interface.TermCategoryError)
|
||||
}
|
||||
|
||||
func (t *terminal) outputClear() {
|
||||
func (t *terminal) OutputClear() {
|
||||
t.outputHistory = nil
|
||||
t.outputIndex = 0
|
||||
}
|
||||
|
||||
func (t *terminal) isVisible() bool {
|
||||
func (t *terminal) IsVisible() bool {
|
||||
return t.visState != termVisHidden
|
||||
}
|
||||
|
||||
func (t *terminal) hide() {
|
||||
func (t *terminal) Hide() {
|
||||
if t.visState != termVisHidden {
|
||||
t.visState = termVisHiding
|
||||
}
|
||||
}
|
||||
|
||||
func (t *terminal) show() {
|
||||
func (t *terminal) Show() {
|
||||
if t.visState != termVisShown {
|
||||
t.visState = termVisShowing
|
||||
}
|
||||
}
|
||||
|
||||
func (t *terminal) bindAction(name, description string, action interface{}) error {
|
||||
func (t *terminal) BindAction(name, description string, action interface{}) error {
|
||||
actionType := reflect.TypeOf(action)
|
||||
if actionType.Kind() != reflect.Func {
|
||||
return errors.New("action is not a function")
|
||||
@ -438,42 +407,15 @@ func (t *terminal) bindAction(name, description string, action interface{}) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) unbindAction(name string) error {
|
||||
func (t *terminal) BindLogger() {
|
||||
log.SetOutput(&terminalLogger{writer: log.Writer(), terminal: t})
|
||||
}
|
||||
|
||||
func (t *terminal) UnbindAction(name string) error {
|
||||
delete(t.actions, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
type terminalLogger struct {
|
||||
buffer bytes.Buffer
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func (t *terminalLogger) Write(p []byte) (int, error) {
|
||||
n, err := t.buffer.Write(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(&t.buffer)
|
||||
termBytes, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
line := string(termBytes[:])
|
||||
lineLower := strings.ToLower(line)
|
||||
|
||||
if strings.Index(lineLower, "error") > 0 {
|
||||
OutputError(line)
|
||||
} else if strings.Index(lineLower, "warning") > 0 {
|
||||
OutputWarning(line)
|
||||
} else {
|
||||
Output(line)
|
||||
}
|
||||
|
||||
return t.writer.Write(p)
|
||||
}
|
||||
|
||||
func easeInOut(t float64) float64 {
|
||||
t *= 2
|
||||
if t < 1 {
|
||||
@ -526,3 +468,33 @@ func parseCommand(command string) []string {
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func createTerminal() (*terminal, error) {
|
||||
terminal := &terminal{
|
||||
lineCount: termRowCount,
|
||||
actions: make(map[string]termActionEntry),
|
||||
}
|
||||
|
||||
terminal.OutputInfo("::: OpenDiablo2 Terminal :::")
|
||||
terminal.OutputInfo("type \"ls\" for a list of actions")
|
||||
|
||||
terminal.BindAction("ls", "list available actions", func() {
|
||||
var names []string
|
||||
for name := range terminal.actions {
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
sort.Strings(names)
|
||||
|
||||
terminal.OutputInfo("available actions (%d):", len(names))
|
||||
for _, name := range names {
|
||||
entry := terminal.actions[name]
|
||||
terminal.OutputInfo("%s: %s; %s", name, entry.description, reflect.TypeOf(entry.action).String())
|
||||
}
|
||||
})
|
||||
terminal.BindAction("clear", "clear terminal", func() {
|
||||
terminal.OutputClear()
|
||||
})
|
||||
|
||||
return terminal, nil
|
||||
}
|
||||
|
44
d2core/d2term/terminal_logger.go
Normal file
44
d2core/d2term/terminal_logger.go
Normal file
@ -0,0 +1,44 @@
|
||||
package d2term
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type terminalLogger struct {
|
||||
terminal *terminal
|
||||
buffer bytes.Buffer
|
||||
writer io.Writer
|
||||
}
|
||||
|
||||
func (tl *terminalLogger) Write(p []byte) (int, error) {
|
||||
n, err := tl.buffer.Write(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(&tl.buffer)
|
||||
termBytes, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
line := string(termBytes[:])
|
||||
lineLower := strings.ToLower(line)
|
||||
|
||||
if strings.Index(lineLower, "error") > 0 {
|
||||
tl.terminal.OutputError(line)
|
||||
} else if strings.Index(lineLower, "warning") > 0 {
|
||||
tl.terminal.OutputWarning(line)
|
||||
} else {
|
||||
tl.terminal.Output(line)
|
||||
}
|
||||
|
||||
return tl.writer.Write(p)
|
||||
}
|
||||
|
||||
func (tl *terminalLogger) BindToTerminal(t *terminal) {
|
||||
tl.terminal = t
|
||||
}
|
@ -47,15 +47,17 @@ type CharacterSelect struct {
|
||||
connectionType d2clientconnectiontype.ClientConnectionType
|
||||
connectionHost string
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
func CreateCharacterSelect(audioProvider d2interface.AudioProvider,
|
||||
connectionType d2clientconnectiontype.ClientConnectionType, connectionHost string) *CharacterSelect {
|
||||
connectionType d2clientconnectiontype.ClientConnectionType, connectionHost string, term d2interface.Terminal) *CharacterSelect {
|
||||
return &CharacterSelect{
|
||||
selectedCharacter: -1,
|
||||
connectionType: connectionType,
|
||||
connectionHost: connectionHost,
|
||||
audioProvider: audioProvider,
|
||||
terminal: term,
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,7 +182,7 @@ func (v *CharacterSelect) onNewCharButtonClicked() {
|
||||
}
|
||||
|
||||
func (v *CharacterSelect) onExitButtonClicked() {
|
||||
mainMenu := CreateMainMenu(v.audioProvider)
|
||||
mainMenu := CreateMainMenu(v.audioProvider, v.terminal)
|
||||
mainMenu.SetScreenMode(ScreenModeMainMenu)
|
||||
d2screen.SetNextScreen(mainMenu)
|
||||
}
|
||||
@ -311,5 +313,5 @@ func (v *CharacterSelect) onOkButtonClicked() {
|
||||
gameClient.Open("", v.gameStates[v.selectedCharacter].FilePath)
|
||||
}
|
||||
|
||||
d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient))
|
||||
d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient, v.terminal))
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ type Credits struct {
|
||||
cyclesTillNextLine int
|
||||
doneWithCredits bool
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
// CreateCredits creates an instance of the credits screen
|
||||
@ -138,7 +139,7 @@ func (v *Credits) Advance(tickTime float64) error {
|
||||
}
|
||||
|
||||
func (v *Credits) onExitButtonClicked() {
|
||||
mainMenu := CreateMainMenu(v.audioProvider)
|
||||
mainMenu := CreateMainMenu(v.audioProvider, v.terminal)
|
||||
mainMenu.SetScreenMode(ScreenModeMainMenu)
|
||||
d2screen.SetNextScreen(mainMenu)
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ type EscapeMenu struct {
|
||||
rightPent *d2gui.AnimatedSprite
|
||||
layouts []*layout
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
type layout struct {
|
||||
@ -112,9 +113,10 @@ type actionableElement interface {
|
||||
Trigger()
|
||||
}
|
||||
|
||||
func NewEscapeMenu(audioProvider d2interface.AudioProvider) *EscapeMenu {
|
||||
func NewEscapeMenu(audioProvider d2interface.AudioProvider, term d2interface.Terminal) *EscapeMenu {
|
||||
m := &EscapeMenu{
|
||||
audioProvider: audioProvider,
|
||||
terminal: term,
|
||||
}
|
||||
|
||||
m.layouts = []*layout{
|
||||
@ -339,7 +341,7 @@ func (m *EscapeMenu) showLayout(id layoutID) {
|
||||
}
|
||||
|
||||
if id == saveLayoutID {
|
||||
mainMenu := CreateMainMenu(m.audioProvider)
|
||||
mainMenu := CreateMainMenu(m.audioProvider, m.terminal)
|
||||
mainMenu.SetScreenMode(ScreenModeMainMenu)
|
||||
d2screen.SetNextScreen(mainMenu)
|
||||
return
|
||||
|
@ -27,20 +27,22 @@ type Game struct {
|
||||
localPlayer *d2mapentity.Player
|
||||
lastRegionType d2enum.RegionIdType
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
ticksSinceLevelCheck float64
|
||||
escapeMenu *EscapeMenu
|
||||
}
|
||||
|
||||
func CreateGame(audioProvider d2interface.AudioProvider, gameClient *d2client.GameClient) *Game {
|
||||
func CreateGame(audioProvider d2interface.AudioProvider, gameClient *d2client.GameClient, term d2interface.Terminal) *Game {
|
||||
result := &Game{
|
||||
gameClient: gameClient,
|
||||
gameControls: nil,
|
||||
localPlayer: nil,
|
||||
lastRegionType: d2enum.RegionNone,
|
||||
ticksSinceLevelCheck: 0,
|
||||
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine),
|
||||
escapeMenu: NewEscapeMenu(audioProvider),
|
||||
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine, term),
|
||||
escapeMenu: NewEscapeMenu(audioProvider, term),
|
||||
audioProvider: audioProvider,
|
||||
terminal: term,
|
||||
}
|
||||
result.escapeMenu.OnLoad()
|
||||
d2input.BindHandler(result.escapeMenu)
|
||||
@ -112,7 +114,7 @@ func (v *Game) Advance(tickTime float64) error {
|
||||
continue
|
||||
}
|
||||
v.localPlayer = player
|
||||
v.gameControls = d2player.NewGameControls(player, v.gameClient.MapEngine, v.mapRenderer, v)
|
||||
v.gameControls = d2player.NewGameControls(player, v.gameClient.MapEngine, v.mapRenderer, v, v.terminal)
|
||||
v.gameControls.Load()
|
||||
d2input.BindHandler(v.gameControls)
|
||||
|
||||
|
@ -71,14 +71,16 @@ type MainMenu struct {
|
||||
screenMode MainMenuScreenMode
|
||||
leftButtonHeld bool
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
// CreateMainMenu creates an instance of MainMenu
|
||||
func CreateMainMenu(audioProvider d2interface.AudioProvider) *MainMenu {
|
||||
func CreateMainMenu(audioProvider d2interface.AudioProvider, term d2interface.Terminal) *MainMenu {
|
||||
return &MainMenu{
|
||||
screenMode: ScreenModeUnknown,
|
||||
leftButtonHeld: true,
|
||||
audioProvider: audioProvider,
|
||||
terminal: term,
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +257,7 @@ func (v *MainMenu) OnLoad(loading d2screen.LoadingState) {
|
||||
}
|
||||
|
||||
func (v *MainMenu) onMapTestClicked() {
|
||||
d2screen.SetNextScreen(CreateMapEngineTest(0, 1))
|
||||
d2screen.SetNextScreen(CreateMapEngineTest(0, 1, v.terminal))
|
||||
}
|
||||
|
||||
func openbrowser(url string) {
|
||||
@ -280,7 +282,7 @@ func openbrowser(url string) {
|
||||
func (v *MainMenu) onSinglePlayerClicked() {
|
||||
// Go here only if existing characters are available to select
|
||||
if d2player.HasGameStates() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText()))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
return
|
||||
}
|
||||
d2screen.SetNextScreen(CreateSelectHeroClass(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText()))
|
||||
@ -410,7 +412,7 @@ func (v *MainMenu) onTcpIpCancelClicked() {
|
||||
}
|
||||
|
||||
func (v *MainMenu) onTcpIpHostGameClicked() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANServer, ""))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANServer, "", v.terminal))
|
||||
}
|
||||
|
||||
func (v *MainMenu) onTcpIpJoinGameClicked() {
|
||||
@ -422,5 +424,5 @@ func (v *MainMenu) onBtnTcpIpCancelClicked() {
|
||||
}
|
||||
|
||||
func (v *MainMenu) onBtnTcpIpOkClicked() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANClient, v.tcpJoinGameEntry.GetText()))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANClient, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
|
||||
@ -82,6 +83,7 @@ type MapEngineTest struct {
|
||||
gameState *d2player.PlayerState
|
||||
mapEngine *d2mapengine.MapEngine
|
||||
mapRenderer *d2maprenderer.MapRenderer
|
||||
terminal d2interface.Terminal
|
||||
|
||||
//TODO: this is region specific properties, should be refactored for multi-region rendering
|
||||
currentRegion int
|
||||
@ -92,13 +94,14 @@ type MapEngineTest struct {
|
||||
debugVisLevel int
|
||||
}
|
||||
|
||||
func CreateMapEngineTest(currentRegion int, levelPreset int) *MapEngineTest {
|
||||
func CreateMapEngineTest(currentRegion int, levelPreset int, term d2interface.Terminal) *MapEngineTest {
|
||||
result := &MapEngineTest{
|
||||
currentRegion: currentRegion,
|
||||
levelPreset: levelPreset,
|
||||
fileIndex: 0,
|
||||
regionSpec: RegionSpec{},
|
||||
filesCount: 0,
|
||||
terminal: term,
|
||||
}
|
||||
result.gameState = d2player.CreateTestGameState()
|
||||
return result
|
||||
@ -148,7 +151,7 @@ func (met *MapEngineTest) OnLoad(loading d2screen.LoadingState) {
|
||||
loading.Progress(0.2)
|
||||
met.mapEngine = d2mapengine.CreateMapEngine()
|
||||
loading.Progress(0.5)
|
||||
met.mapRenderer = d2maprenderer.CreateMapRenderer(met.mapEngine)
|
||||
met.mapRenderer = d2maprenderer.CreateMapRenderer(met.mapEngine, met.terminal)
|
||||
loading.Progress(0.7)
|
||||
met.LoadRegionByIndex(met.currentRegion, met.levelPreset, met.fileIndex)
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ type SelectHeroClass struct {
|
||||
connectionType d2clientconnectiontype.ClientConnectionType
|
||||
connectionHost string
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
func CreateSelectHeroClass(audioProvider d2interface.AudioProvider,
|
||||
@ -434,14 +435,14 @@ func (v *SelectHeroClass) OnUnload() error {
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) onExitButtonClicked() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, v.connectionType, v.connectionHost))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, v.connectionType, v.connectionHost, v.terminal))
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) onOkButtonClicked() {
|
||||
gameState := d2player.CreatePlayerState(v.heroNameTextbox.GetText(), v.selectedHero, *d2datadict.CharStats[v.selectedHero], v.hardcoreCheckbox.GetCheckState())
|
||||
gameClient, _ := d2client.Create(d2clientconnectiontype.Local)
|
||||
gameClient.Open(v.connectionHost, gameState.FilePath)
|
||||
d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient))
|
||||
d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient, v.terminal))
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) Render(screen d2render.Surface) error {
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
@ -14,7 +15,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
@ -82,8 +82,8 @@ const (
|
||||
rightSkill = ActionableType(iota)
|
||||
)
|
||||
|
||||
func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener) *GameControls {
|
||||
d2term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
|
||||
func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener, term d2interface.Terminal) *GameControls {
|
||||
term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
|
||||
missileID = id
|
||||
})
|
||||
|
||||
@ -117,7 +117,7 @@ func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine,
|
||||
},
|
||||
}
|
||||
|
||||
d2term.BindAction("freecam", "toggle free camera movement", func() {
|
||||
term.BindAction("freecam", "toggle free camera movement", func() {
|
||||
gc.FreeCam = !gc.FreeCam
|
||||
})
|
||||
|
||||
|
63
main.go
63
main.go
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
ebiten_input "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input/ebiten"
|
||||
"image"
|
||||
"image/gif"
|
||||
"image/png"
|
||||
@ -27,7 +28,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
ebiten_input "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input/ebiten"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render/ebiten"
|
||||
@ -65,6 +65,8 @@ var singleton struct {
|
||||
captureFrames []*image.RGBA
|
||||
}
|
||||
|
||||
var terminal_hack d2interface.Terminal // we need to make this available inside of advance/update/render
|
||||
|
||||
func main() {
|
||||
region := kingpin.Arg("region", "Region type id").Int()
|
||||
preset := kingpin.Arg("preset", "Level preset").Int()
|
||||
@ -81,7 +83,15 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := initialize(audioProvider); err != nil {
|
||||
|
||||
d2input.Initialize(ebiten_input.InputService{}) // TODO d2input singleton must be init before d2term
|
||||
term, err := d2term.Initialize()
|
||||
terminal_hack = term // needs to be used in advance, no easy way for that right now
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := initialize(audioProvider, term); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
run(updateInitError)
|
||||
}
|
||||
@ -96,15 +106,15 @@ func main() {
|
||||
}
|
||||
|
||||
if *region == 0 {
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateMainMenu(audioProvider))
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateMainMenu(audioProvider, term))
|
||||
} else {
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateMapEngineTest(*region, *preset))
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateMapEngineTest(*region, *preset, term))
|
||||
}
|
||||
|
||||
run(update)
|
||||
}
|
||||
|
||||
func initialize(audioProvider d2interface.AudioProvider) error {
|
||||
func initialize(audioProvider d2interface.AudioProvider, term d2interface.Terminal) error {
|
||||
singleton.timeScale = 1.0
|
||||
singleton.lastTime = d2common.Now()
|
||||
singleton.lastScreenAdvance = singleton.lastTime
|
||||
@ -116,8 +126,6 @@ func initialize(audioProvider d2interface.AudioProvider) error {
|
||||
config := d2config.Get()
|
||||
d2resource.LanguageCode = config.Language
|
||||
|
||||
d2input.Initialize(ebiten_input.InputService{})
|
||||
|
||||
renderer, err := ebiten.CreateRenderer()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -128,60 +136,57 @@ func initialize(audioProvider d2interface.AudioProvider) error {
|
||||
}
|
||||
d2render.SetWindowIcon("d2logo.png")
|
||||
|
||||
if err := d2term.Initialize(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d2term.BindLogger()
|
||||
d2term.BindAction("dumpheap", "dumps the heap to pprof/heap.pprof", func() {
|
||||
term.BindLogger()
|
||||
term.BindAction("dumpheap", "dumps the heap to pprof/heap.pprof", func() {
|
||||
os.Mkdir("./pprof/", 0755)
|
||||
fileOut, _ := os.Create("./pprof/heap.pprof")
|
||||
pprof.WriteHeapProfile(fileOut)
|
||||
fileOut.Close()
|
||||
})
|
||||
d2term.BindAction("fullscreen", "toggles fullscreen", func() {
|
||||
term.BindAction("fullscreen", "toggles fullscreen", func() {
|
||||
fullscreen := !d2render.IsFullScreen()
|
||||
d2render.SetFullScreen(fullscreen)
|
||||
d2term.OutputInfo("fullscreen is now: %v", fullscreen)
|
||||
term.OutputInfo("fullscreen is now: %v", fullscreen)
|
||||
})
|
||||
d2term.BindAction("capframe", "captures a still frame", func(path string) {
|
||||
term.BindAction("capframe", "captures a still frame", func(path string) {
|
||||
singleton.captureState = captureStateFrame
|
||||
singleton.capturePath = path
|
||||
singleton.captureFrames = nil
|
||||
})
|
||||
d2term.BindAction("capgifstart", "captures an animation (start)", func(path string) {
|
||||
term.BindAction("capgifstart", "captures an animation (start)", func(path string) {
|
||||
singleton.captureState = captureStateGif
|
||||
singleton.capturePath = path
|
||||
singleton.captureFrames = nil
|
||||
})
|
||||
d2term.BindAction("capgifstop", "captures an animation (stop)", func() {
|
||||
term.BindAction("capgifstop", "captures an animation (stop)", func() {
|
||||
singleton.captureState = captureStateNone
|
||||
})
|
||||
d2term.BindAction("vsync", "toggles vsync", func() {
|
||||
term.BindAction("vsync", "toggles vsync", func() {
|
||||
vsync := !d2render.GetVSyncEnabled()
|
||||
d2render.SetVSyncEnabled(vsync)
|
||||
d2term.OutputInfo("vsync is now: %v", vsync)
|
||||
term.OutputInfo("vsync is now: %v", vsync)
|
||||
})
|
||||
d2term.BindAction("fps", "toggle fps counter", func() {
|
||||
term.BindAction("fps", "toggle fps counter", func() {
|
||||
singleton.showFPS = !singleton.showFPS
|
||||
d2term.OutputInfo("fps counter is now: %v", singleton.showFPS)
|
||||
term.OutputInfo("fps counter is now: %v", singleton.showFPS)
|
||||
})
|
||||
d2term.BindAction("timescale", "set scalar for elapsed time", func(timeScale float64) {
|
||||
term.BindAction("timescale", "set scalar for elapsed time", func(timeScale float64) {
|
||||
if timeScale <= 0 {
|
||||
d2term.OutputError("invalid time scale value")
|
||||
term.OutputError("invalid time scale value")
|
||||
} else {
|
||||
d2term.OutputInfo("timescale changed from %f to %f", singleton.timeScale, timeScale)
|
||||
term.OutputInfo("timescale changed from %f to %f", singleton.timeScale, timeScale)
|
||||
singleton.timeScale = timeScale
|
||||
}
|
||||
})
|
||||
d2term.BindAction("quit", "exits the game", func() {
|
||||
term.BindAction("quit", "exits the game", func() {
|
||||
os.Exit(0)
|
||||
})
|
||||
d2term.BindAction("screen-gui", "enters the gui playground screen", func() {
|
||||
term.BindAction("screen-gui", "enters the gui playground screen", func() {
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateGuiTestMain())
|
||||
})
|
||||
|
||||
if err := d2asset.Initialize(); err != nil {
|
||||
if err := d2asset.Initialize(term); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -268,7 +273,7 @@ func advance(elapsed, current float64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d2term.Advance(elapsed); err != nil {
|
||||
if err := terminal_hack.Advance(elapsed); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -294,7 +299,7 @@ func render(target d2render.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d2term.Render(target); err != nil {
|
||||
if err := terminal_hack.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user