mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 07:27:19 -05:00
Event-based input manager with priority system (#274)
This commit is contained in:
parent
1653ffc362
commit
8de0cde818
@ -8,6 +8,7 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2audio"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2corecommon/d2coreinterface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2player"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2mapengine"
|
||||
@ -80,11 +81,13 @@ func (v *Game) Load() []func() {
|
||||
func() {
|
||||
v.gameControls = d2player.NewGameControls(v.hero, v.mapEngine)
|
||||
v.gameControls.Load()
|
||||
d2input.BindHandler(v.gameControls)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Game) Unload() {
|
||||
d2input.UnbindHandler(v.gameControls)
|
||||
}
|
||||
|
||||
func (v Game) Render(screen *d2surface.Surface) {
|
||||
@ -98,6 +101,4 @@ func (v *Game) Advance(tickTime float64) {
|
||||
|
||||
rx, ry := v.mapEngine.WorldToOrtho(v.hero.AnimatedEntity.LocationX/5, v.hero.AnimatedEntity.LocationY/5)
|
||||
v.mapEngine.MoveCameraTo(rx, ry)
|
||||
|
||||
v.gameControls.Update(tickTime)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2corecommon/d2coreinterface"
|
||||
|
||||
@ -13,8 +14,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2mapengine"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2surface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2ui"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
)
|
||||
|
||||
type RegionSpec struct {
|
||||
@ -145,7 +144,7 @@ func (v *MapEngineTest) LoadRegionByIndex(n int, levelPreset, fileIndex int) {
|
||||
|
||||
func (v *MapEngineTest) Load() []func() {
|
||||
// TODO: Game seed comes from the game state object
|
||||
|
||||
d2input.BindHandler(v)
|
||||
v.soundManager.PlayBGM("")
|
||||
return []func(){
|
||||
func() {
|
||||
@ -156,7 +155,7 @@ func (v *MapEngineTest) Load() []func() {
|
||||
}
|
||||
|
||||
func (v *MapEngineTest) Unload() {
|
||||
|
||||
d2input.UnbindHandler(v)
|
||||
}
|
||||
|
||||
func (v *MapEngineTest) Render(screen *d2surface.Surface) {
|
||||
@ -208,77 +207,85 @@ func (v *MapEngineTest) Render(screen *d2surface.Surface) {
|
||||
|
||||
func (v *MapEngineTest) Advance(tickTime float64) {
|
||||
v.mapEngine.Advance(tickTime)
|
||||
}
|
||||
|
||||
ctrlPressed := v.uiManager.KeyPressed(ebiten.KeyControl)
|
||||
shiftPressed := v.uiManager.KeyPressed(ebiten.KeyShift)
|
||||
|
||||
var moveSpeed float64 = 800
|
||||
if v.uiManager.KeyPressed(ebiten.KeyShift) {
|
||||
moveSpeed = 200
|
||||
func (met *MapEngineTest) OnKeyRepeat(event d2input.KeyEvent) bool {
|
||||
var moveSpeed float64 = 8
|
||||
if event.KeyMod == d2input.KeyModShift {
|
||||
moveSpeed *= 2
|
||||
}
|
||||
|
||||
if v.uiManager.KeyPressed(ebiten.KeyDown) {
|
||||
v.mapEngine.MoveCameraBy(0, moveSpeed*tickTime)
|
||||
}
|
||||
if v.uiManager.KeyPressed(ebiten.KeyUp) {
|
||||
v.mapEngine.MoveCameraBy(0, -moveSpeed*tickTime)
|
||||
}
|
||||
if v.uiManager.KeyPressed(ebiten.KeyLeft) {
|
||||
v.mapEngine.MoveCameraBy(-moveSpeed*tickTime, 0)
|
||||
}
|
||||
if v.uiManager.KeyPressed(ebiten.KeyRight) {
|
||||
v.mapEngine.MoveCameraBy(moveSpeed*tickTime, 0)
|
||||
if event.Key == d2input.KeyDown {
|
||||
met.mapEngine.MoveCameraBy(0, moveSpeed)
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyF7) {
|
||||
if v.debugVisLevel < 2 {
|
||||
v.debugVisLevel++
|
||||
if event.Key == d2input.KeyUp {
|
||||
met.mapEngine.MoveCameraBy(0, -moveSpeed)
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyRight {
|
||||
met.mapEngine.MoveCameraBy(moveSpeed, 0)
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyLeft {
|
||||
met.mapEngine.MoveCameraBy(-moveSpeed, 0)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (met *MapEngineTest) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
if event.Key == d2input.KeyEscape {
|
||||
os.Exit(0)
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyN {
|
||||
if event.KeyMod == d2input.KeyModControl {
|
||||
met.fileIndex = increment(met.fileIndex, 0, met.filesCount-1)
|
||||
met.sceneProvider.SetNextScene(met)
|
||||
} else if event.KeyMod == d2input.KeyModShift {
|
||||
met.levelPreset = increment(met.levelPreset, met.regionSpec.startPresetIndex, met.regionSpec.endPresetIndex)
|
||||
met.sceneProvider.SetNextScene(met)
|
||||
} else {
|
||||
v.debugVisLevel = 0
|
||||
met.currentRegion = increment(met.currentRegion, 0, len(regions))
|
||||
met.sceneProvider.SetNextScene(met)
|
||||
}
|
||||
|
||||
v.mapEngine.SetDebugVisLevel(v.debugVisLevel)
|
||||
return true
|
||||
}
|
||||
|
||||
if v.uiManager.KeyPressed(ebiten.KeyEscape) {
|
||||
os.Exit(0)
|
||||
if event.Key == d2input.KeyP {
|
||||
if event.KeyMod == d2input.KeyModControl {
|
||||
met.fileIndex = decrement(met.fileIndex, 0, met.filesCount-1)
|
||||
met.sceneProvider.SetNextScene(met)
|
||||
} else if event.KeyMod == d2input.KeyModShift {
|
||||
met.levelPreset = decrement(met.levelPreset, met.regionSpec.startPresetIndex, met.regionSpec.endPresetIndex)
|
||||
met.sceneProvider.SetNextScene(met)
|
||||
} else {
|
||||
met.currentRegion = decrement(met.currentRegion, 0, len(regions))
|
||||
met.sceneProvider.SetNextScene(met)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyN) && ctrlPressed {
|
||||
v.fileIndex = increment(v.fileIndex, 0, v.filesCount-1)
|
||||
v.sceneProvider.SetNextScene(v)
|
||||
return
|
||||
if event.Key == d2input.KeyF7 {
|
||||
if met.debugVisLevel < 2 {
|
||||
met.debugVisLevel++
|
||||
} else {
|
||||
met.debugVisLevel = 0
|
||||
}
|
||||
|
||||
met.mapEngine.SetDebugVisLevel(met.debugVisLevel)
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyP) && ctrlPressed {
|
||||
v.fileIndex = decrement(v.fileIndex, 0, v.filesCount-1)
|
||||
v.sceneProvider.SetNextScene(v)
|
||||
return
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyN) && shiftPressed {
|
||||
v.levelPreset = increment(v.levelPreset, v.regionSpec.startPresetIndex, v.regionSpec.endPresetIndex)
|
||||
v.sceneProvider.SetNextScene(v)
|
||||
return
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyP) && shiftPressed {
|
||||
v.levelPreset = decrement(v.levelPreset, v.regionSpec.startPresetIndex, v.regionSpec.endPresetIndex)
|
||||
v.sceneProvider.SetNextScene(v)
|
||||
return
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
|
||||
v.currentRegion = increment(v.currentRegion, 0, len(regions))
|
||||
v.sceneProvider.SetNextScene(v)
|
||||
return
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyP) {
|
||||
v.currentRegion = decrement(v.currentRegion, 0, len(regions))
|
||||
v.sceneProvider.SetNextScene(v)
|
||||
return
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func increment(v, min, max int) int {
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/OpenDiablo2/D2Shared/d2helper"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2corecommon/d2coreinterface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2term"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render"
|
||||
@ -28,7 +29,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2ui"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
)
|
||||
|
||||
// Engine is the core OpenDiablo2 engine
|
||||
@ -44,7 +44,6 @@ type Engine struct {
|
||||
UIManager *d2ui.Manager // The UI manager
|
||||
SoundManager *d2audio.Manager // The sound manager
|
||||
nextScene d2coreinterface.Scene // The next scene to be loaded at the end of the game loop
|
||||
fullscreenKey bool // When true, the fullscreen toggle is still being pressed
|
||||
lastTime float64 // Last time we updated the scene
|
||||
showFPS bool
|
||||
timeScale float64
|
||||
@ -96,6 +95,8 @@ func CreateEngine() *Engine {
|
||||
}
|
||||
})
|
||||
|
||||
d2input.BindHandler(result)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -140,25 +141,27 @@ func (v *Engine) updateScene() {
|
||||
v.ResetLoading()
|
||||
}
|
||||
|
||||
func (e *Engine) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
if event.Key == d2input.KeyEnter && event.KeyMod == d2input.KeyModAlt {
|
||||
ebiten.SetFullscreen(!ebiten.IsFullscreen())
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyF6 {
|
||||
e.showFPS = !e.showFPS
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyF8 {
|
||||
ebiten.SetVsyncEnabled(!ebiten.IsVsyncEnabled())
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Advance updates the internal state of the engine
|
||||
func (v *Engine) Advance() {
|
||||
if ebiten.IsKeyPressed(ebiten.KeyAlt) && ebiten.IsKeyPressed(ebiten.KeyEnter) {
|
||||
if !v.fullscreenKey {
|
||||
ebiten.SetFullscreen(!ebiten.IsFullscreen())
|
||||
}
|
||||
v.fullscreenKey = true
|
||||
} else {
|
||||
v.fullscreenKey = false
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyF6) {
|
||||
v.showFPS = !v.showFPS
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyF8) {
|
||||
ebiten.SetVsyncEnabled(!ebiten.IsVsyncEnabled())
|
||||
}
|
||||
|
||||
v.updateScene()
|
||||
if v.CurrentScene == nil {
|
||||
log.Fatal("no scene loaded")
|
||||
@ -174,7 +177,9 @@ func (v *Engine) Advance() {
|
||||
|
||||
v.CurrentScene.Advance(deltaTime)
|
||||
v.UIManager.Advance(deltaTime)
|
||||
|
||||
d2term.Advance(deltaTime)
|
||||
d2input.Advance(deltaTime)
|
||||
}
|
||||
|
||||
// Draw draws the game
|
||||
|
250
d2input/d2input.go
Normal file
250
d2input/d2input.go
Normal file
@ -0,0 +1,250 @@
|
||||
package d2input
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHasInit error = errors.New("input system is already initialized")
|
||||
ErrNotInit error = errors.New("input system is not initialized")
|
||||
ErrHasReg error = errors.New("input system already has provided handler")
|
||||
ErrNotReg error = errors.New("input system does not have provided handler")
|
||||
)
|
||||
|
||||
type Priority int
|
||||
|
||||
const (
|
||||
PriorityLow Priority = iota
|
||||
PriorityDefault
|
||||
PriorityHigh
|
||||
)
|
||||
|
||||
type Key int
|
||||
|
||||
const (
|
||||
Key0 Key = Key(ebiten.Key0)
|
||||
Key1 Key = Key(ebiten.Key1)
|
||||
Key2 Key = Key(ebiten.Key2)
|
||||
Key3 Key = Key(ebiten.Key3)
|
||||
Key4 Key = Key(ebiten.Key4)
|
||||
Key5 Key = Key(ebiten.Key5)
|
||||
Key6 Key = Key(ebiten.Key6)
|
||||
Key7 Key = Key(ebiten.Key7)
|
||||
Key8 Key = Key(ebiten.Key8)
|
||||
Key9 Key = Key(ebiten.Key9)
|
||||
KeyA Key = Key(ebiten.KeyA)
|
||||
KeyB Key = Key(ebiten.KeyB)
|
||||
KeyC Key = Key(ebiten.KeyC)
|
||||
KeyD Key = Key(ebiten.KeyD)
|
||||
KeyE Key = Key(ebiten.KeyE)
|
||||
KeyF Key = Key(ebiten.KeyF)
|
||||
KeyG Key = Key(ebiten.KeyG)
|
||||
KeyH Key = Key(ebiten.KeyH)
|
||||
KeyI Key = Key(ebiten.KeyI)
|
||||
KeyJ Key = Key(ebiten.KeyJ)
|
||||
KeyK Key = Key(ebiten.KeyK)
|
||||
KeyL Key = Key(ebiten.KeyL)
|
||||
KeyM Key = Key(ebiten.KeyM)
|
||||
KeyN Key = Key(ebiten.KeyN)
|
||||
KeyO Key = Key(ebiten.KeyO)
|
||||
KeyP Key = Key(ebiten.KeyP)
|
||||
KeyQ Key = Key(ebiten.KeyQ)
|
||||
KeyR Key = Key(ebiten.KeyR)
|
||||
KeyS Key = Key(ebiten.KeyS)
|
||||
KeyT Key = Key(ebiten.KeyT)
|
||||
KeyU Key = Key(ebiten.KeyU)
|
||||
KeyV Key = Key(ebiten.KeyV)
|
||||
KeyW Key = Key(ebiten.KeyW)
|
||||
KeyX Key = Key(ebiten.KeyX)
|
||||
KeyY Key = Key(ebiten.KeyY)
|
||||
KeyZ Key = Key(ebiten.KeyZ)
|
||||
KeyApostrophe Key = Key(ebiten.KeyApostrophe)
|
||||
KeyBackslash Key = Key(ebiten.KeyBackslash)
|
||||
KeyBackspace Key = Key(ebiten.KeyBackspace)
|
||||
KeyCapsLock Key = Key(ebiten.KeyCapsLock)
|
||||
KeyComma Key = Key(ebiten.KeyComma)
|
||||
KeyDelete Key = Key(ebiten.KeyDelete)
|
||||
KeyDown Key = Key(ebiten.KeyDown)
|
||||
KeyEnd Key = Key(ebiten.KeyEnd)
|
||||
KeyEnter Key = Key(ebiten.KeyEnter)
|
||||
KeyEqual Key = Key(ebiten.KeyEqual)
|
||||
KeyEscape Key = Key(ebiten.KeyEscape)
|
||||
KeyF1 Key = Key(ebiten.KeyF1)
|
||||
KeyF2 Key = Key(ebiten.KeyF2)
|
||||
KeyF3 Key = Key(ebiten.KeyF3)
|
||||
KeyF4 Key = Key(ebiten.KeyF4)
|
||||
KeyF5 Key = Key(ebiten.KeyF5)
|
||||
KeyF6 Key = Key(ebiten.KeyF6)
|
||||
KeyF7 Key = Key(ebiten.KeyF7)
|
||||
KeyF8 Key = Key(ebiten.KeyF8)
|
||||
KeyF9 Key = Key(ebiten.KeyF9)
|
||||
KeyF10 Key = Key(ebiten.KeyF10)
|
||||
KeyF11 Key = Key(ebiten.KeyF11)
|
||||
KeyF12 Key = Key(ebiten.KeyF12)
|
||||
KeyGraveAccent Key = Key(ebiten.KeyGraveAccent)
|
||||
KeyHome Key = Key(ebiten.KeyHome)
|
||||
KeyInsert Key = Key(ebiten.KeyInsert)
|
||||
KeyKP0 Key = Key(ebiten.KeyKP0)
|
||||
KeyKP1 Key = Key(ebiten.KeyKP1)
|
||||
KeyKP2 Key = Key(ebiten.KeyKP2)
|
||||
KeyKP3 Key = Key(ebiten.KeyKP3)
|
||||
KeyKP4 Key = Key(ebiten.KeyKP4)
|
||||
KeyKP5 Key = Key(ebiten.KeyKP5)
|
||||
KeyKP6 Key = Key(ebiten.KeyKP6)
|
||||
KeyKP7 Key = Key(ebiten.KeyKP7)
|
||||
KeyKP8 Key = Key(ebiten.KeyKP8)
|
||||
KeyKP9 Key = Key(ebiten.KeyKP9)
|
||||
KeyKPAdd Key = Key(ebiten.KeyKPAdd)
|
||||
KeyKPDecimal Key = Key(ebiten.KeyKPDecimal)
|
||||
KeyKPDivide Key = Key(ebiten.KeyKPDivide)
|
||||
KeyKPEnter Key = Key(ebiten.KeyKPEnter)
|
||||
KeyKPEqual Key = Key(ebiten.KeyKPEqual)
|
||||
KeyKPMultiply Key = Key(ebiten.KeyKPMultiply)
|
||||
KeyKPSubtract Key = Key(ebiten.KeyKPSubtract)
|
||||
KeyLeft Key = Key(ebiten.KeyLeft)
|
||||
KeyLeftBracket Key = Key(ebiten.KeyLeftBracket)
|
||||
KeyMenu Key = Key(ebiten.KeyMenu)
|
||||
KeyMinus Key = Key(ebiten.KeyMinus)
|
||||
KeyNumLock Key = Key(ebiten.KeyNumLock)
|
||||
KeyPageDown Key = Key(ebiten.KeyPageDown)
|
||||
KeyPageUp Key = Key(ebiten.KeyPageUp)
|
||||
KeyPause Key = Key(ebiten.KeyPause)
|
||||
KeyPeriod Key = Key(ebiten.KeyPeriod)
|
||||
KeyPrintScreen Key = Key(ebiten.KeyPrintScreen)
|
||||
KeyRight Key = Key(ebiten.KeyRight)
|
||||
KeyRightBracket Key = Key(ebiten.KeyRightBracket)
|
||||
KeyScrollLock Key = Key(ebiten.KeyScrollLock)
|
||||
KeySemicolon Key = Key(ebiten.KeySemicolon)
|
||||
KeySlash Key = Key(ebiten.KeySlash)
|
||||
KeySpace Key = Key(ebiten.KeySpace)
|
||||
KeyTab Key = Key(ebiten.KeyTab)
|
||||
KeyUp Key = Key(ebiten.KeyUp)
|
||||
KeyAlt Key = Key(ebiten.KeyAlt)
|
||||
KeyControl Key = Key(ebiten.KeyControl)
|
||||
KeyShift Key = Key(ebiten.KeyShift)
|
||||
)
|
||||
|
||||
type KeyMod int
|
||||
|
||||
const (
|
||||
KeyModAlt = 1 << iota
|
||||
KeyModControl
|
||||
KeyModShift
|
||||
)
|
||||
|
||||
type MouseButton int
|
||||
|
||||
const (
|
||||
MouseButtonLeft MouseButton = MouseButton(ebiten.MouseButtonLeft)
|
||||
MouseButtonMiddle MouseButton = MouseButton(ebiten.MouseButtonMiddle)
|
||||
MouseButtonRight MouseButton = MouseButton(ebiten.MouseButtonRight)
|
||||
)
|
||||
|
||||
type MouseButtonMod int
|
||||
|
||||
const (
|
||||
MouseButtonModLeft MouseButtonMod = 1 << iota
|
||||
MouseButtonModMiddle
|
||||
MouseButtonModRight
|
||||
)
|
||||
|
||||
type HandlerEvent struct {
|
||||
KeyMod KeyMod
|
||||
ButtonMod MouseButtonMod
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
|
||||
type KeyEvent struct {
|
||||
HandlerEvent
|
||||
Key Key
|
||||
}
|
||||
|
||||
type KeyCharsEvent struct {
|
||||
HandlerEvent
|
||||
Chars []rune
|
||||
}
|
||||
|
||||
type MouseEvent struct {
|
||||
HandlerEvent
|
||||
Button MouseButton
|
||||
}
|
||||
|
||||
type MouseMoveEvent struct {
|
||||
HandlerEvent
|
||||
}
|
||||
|
||||
type Handler interface{}
|
||||
|
||||
type KeyDownHandler interface {
|
||||
OnKeyDown(event KeyEvent) bool
|
||||
}
|
||||
|
||||
type KeyRepeatHandler interface {
|
||||
OnKeyRepeat(event KeyEvent) bool
|
||||
}
|
||||
|
||||
type KeyUpHandler interface {
|
||||
OnKeyUp(event KeyEvent) bool
|
||||
}
|
||||
|
||||
type KeyCharsHandler interface {
|
||||
OnKeyChars(event KeyCharsEvent) bool
|
||||
}
|
||||
|
||||
type MouseButtonDownHandler interface {
|
||||
OnMouseButtonDown(event MouseEvent) bool
|
||||
}
|
||||
|
||||
type MouseButtonUpHandler interface {
|
||||
OnMouseButtonUp(event MouseEvent) bool
|
||||
}
|
||||
|
||||
type MouseMoveHandler interface {
|
||||
OnMouseMove(event MouseMoveEvent) bool
|
||||
}
|
||||
|
||||
var singleton *inputManager
|
||||
|
||||
func Initialize() error {
|
||||
if singleton != nil {
|
||||
return ErrHasInit
|
||||
}
|
||||
|
||||
singleton = &inputManager{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Shutdown() {
|
||||
singleton = nil
|
||||
}
|
||||
|
||||
func Advance(elapsed float64) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.advance(elapsed)
|
||||
}
|
||||
|
||||
func BindHandlerWithPriority(handler Handler, priority Priority) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.bindHandler(handler, priority)
|
||||
}
|
||||
|
||||
func BindHandler(handler Handler) error {
|
||||
return BindHandlerWithPriority(handler, PriorityDefault)
|
||||
}
|
||||
|
||||
func UnbindHandler(handler Handler) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.unbindHandler(handler)
|
||||
}
|
197
d2input/input_manager.go
Normal file
197
d2input/input_manager.go
Normal file
@ -0,0 +1,197 @@
|
||||
package d2input
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
)
|
||||
|
||||
type handlerEntry struct {
|
||||
handler Handler
|
||||
priority Priority
|
||||
}
|
||||
|
||||
type handlerEntryList []handlerEntry
|
||||
|
||||
func (lel handlerEntryList) Len() int {
|
||||
return len(lel)
|
||||
}
|
||||
|
||||
func (lel handlerEntryList) Swap(i, j int) {
|
||||
lel[i], lel[j] = lel[j], lel[i]
|
||||
}
|
||||
|
||||
func (lel handlerEntryList) Less(i, j int) bool {
|
||||
return lel[i].priority > lel[j].priority
|
||||
}
|
||||
|
||||
type inputManager struct {
|
||||
cursorX int
|
||||
cursorY int
|
||||
|
||||
buttonMod MouseButtonMod
|
||||
keyMod KeyMod
|
||||
|
||||
entries handlerEntryList
|
||||
}
|
||||
|
||||
func (im *inputManager) advance(elapsed float64) error {
|
||||
cursorX, cursorY := ebiten.CursorPosition()
|
||||
|
||||
im.keyMod = 0
|
||||
if ebiten.IsKeyPressed(ebiten.KeyAlt) {
|
||||
im.keyMod |= KeyModAlt
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyControl) {
|
||||
im.keyMod |= KeyModControl
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyShift) {
|
||||
im.keyMod |= KeyModShift
|
||||
}
|
||||
|
||||
im.buttonMod = 0
|
||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||
im.buttonMod |= MouseButtonModLeft
|
||||
}
|
||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonMiddle) {
|
||||
im.buttonMod |= MouseButtonModMiddle
|
||||
}
|
||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonRight) {
|
||||
im.buttonMod |= MouseButtonModRight
|
||||
}
|
||||
|
||||
eventBase := HandlerEvent{
|
||||
im.keyMod,
|
||||
im.buttonMod,
|
||||
cursorX,
|
||||
cursorY,
|
||||
}
|
||||
|
||||
for key := ebiten.Key0; key < ebiten.KeyMax; key++ {
|
||||
if inpututil.IsKeyJustPressed(key) {
|
||||
event := KeyEvent{eventBase, Key(key)}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(KeyDownHandler); ok {
|
||||
return l.OnKeyDown(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
if ebiten.IsKeyPressed(key) {
|
||||
event := KeyEvent{eventBase, Key(key)}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(KeyRepeatHandler); ok {
|
||||
return l.OnKeyRepeat(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustReleased(key) {
|
||||
event := KeyEvent{eventBase, Key(key)}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(KeyUpHandler); ok {
|
||||
return l.OnKeyUp(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if chars := ebiten.InputChars(); len(chars) > 0 {
|
||||
event := KeyCharsEvent{eventBase, chars}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(KeyCharsHandler); ok {
|
||||
l.OnKeyChars(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
for button := ebiten.MouseButtonLeft; button < ebiten.MouseButtonMiddle; button++ {
|
||||
if inpututil.IsMouseButtonJustPressed(button) {
|
||||
event := MouseEvent{eventBase, MouseButton(button)}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(MouseButtonDownHandler); ok {
|
||||
return l.OnMouseButtonDown(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
if inpututil.IsMouseButtonJustReleased(button) {
|
||||
event := MouseEvent{eventBase, MouseButton(button)}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(MouseButtonUpHandler); ok {
|
||||
return l.OnMouseButtonUp(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if im.cursorX != cursorX || im.cursorY != cursorY {
|
||||
event := MouseMoveEvent{eventBase}
|
||||
im.propagate(func(handler Handler) bool {
|
||||
if l, ok := handler.(MouseMoveHandler); ok {
|
||||
return l.OnMouseMove(event)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
im.cursorX, im.cursorY = cursorX, cursorY
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (im *inputManager) bindHandler(handler Handler, priority Priority) error {
|
||||
for _, entry := range im.entries {
|
||||
if entry.handler == handler {
|
||||
return ErrHasReg
|
||||
}
|
||||
}
|
||||
|
||||
im.entries = append(im.entries, handlerEntry{handler, priority})
|
||||
sort.Sort(im.entries)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (im *inputManager) unbindHandler(handler Handler) error {
|
||||
for i, entry := range im.entries {
|
||||
if entry.handler == handler {
|
||||
copy(im.entries[i:], im.entries[i+1:])
|
||||
im.entries = im.entries[:len(im.entries)-1]
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return ErrNotReg
|
||||
}
|
||||
|
||||
func (im *inputManager) propagate(callback func(Handler) bool) {
|
||||
var priority Priority
|
||||
var handled bool
|
||||
|
||||
for _, entry := range im.entries {
|
||||
if priority > entry.priority && handled {
|
||||
break
|
||||
}
|
||||
|
||||
if callback(entry.handler) {
|
||||
handled = true
|
||||
}
|
||||
|
||||
priority = entry.priority
|
||||
}
|
||||
}
|
@ -3,11 +3,10 @@ package d2player
|
||||
import (
|
||||
"github.com/OpenDiablo2/D2Shared/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2mapengine"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2surface"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
)
|
||||
|
||||
type Panel interface {
|
||||
@ -37,41 +36,23 @@ func NewGameControls(hero *d2core.Hero, mapEngine *d2mapengine.MapEngine) *GameC
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GameControls) Update(tickTime float64) {
|
||||
|
||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||
px, py := g.mapEngine.ScreenToWorld(ebiten.CursorPosition())
|
||||
g.hero.AnimatedEntity.SetTarget(px*5, py*5, 1)
|
||||
}
|
||||
|
||||
arrowDistance := 1.0
|
||||
moveX := 0.0
|
||||
moveY := 0.0
|
||||
if ebiten.IsKeyPressed(ebiten.KeyW) || ebiten.IsKeyPressed(ebiten.KeyUp) {
|
||||
moveY -= arrowDistance
|
||||
moveX -= arrowDistance
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyS) || ebiten.IsKeyPressed(ebiten.KeyDown) {
|
||||
moveY += arrowDistance
|
||||
moveX += arrowDistance
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyA) || ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
||||
moveY += arrowDistance
|
||||
moveX -= arrowDistance
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyD) || ebiten.IsKeyPressed(ebiten.KeyRight) {
|
||||
moveY -= arrowDistance
|
||||
moveX += arrowDistance
|
||||
}
|
||||
|
||||
if moveY != 0 || moveX != 0 {
|
||||
g.hero.AnimatedEntity.SetTarget(g.hero.AnimatedEntity.LocationX+moveX, g.hero.AnimatedEntity.LocationY+moveY, 1)
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyI) {
|
||||
func (g *GameControls) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
if event.Key == d2input.KeyI {
|
||||
g.inventory.Toggle()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
||||
if event.Button == d2input.MouseButtonLeft {
|
||||
px, py := g.mapEngine.ScreenToWorld(event.X, event.Y)
|
||||
g.hero.AnimatedEntity.SetTarget(px*5, py*5, 1)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *GameControls) Load() {
|
||||
|
114
d2term/d2term.go
Normal file
114
d2term/d2term.go
Normal file
@ -0,0 +1,114 @@
|
||||
package d2term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2surface"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHasInit error = errors.New("terminal system is already initialized")
|
||||
ErrNotInit error = errors.New("terminal system is not initialized")
|
||||
)
|
||||
|
||||
var singleton *terminal
|
||||
|
||||
func Initialize() error {
|
||||
if singleton != nil {
|
||||
return ErrHasInit
|
||||
}
|
||||
|
||||
terminal, err := createTerminal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d2input.BindHandlerWithPriority(terminal, d2input.PriorityHigh); err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
singleton = terminal
|
||||
return nil
|
||||
}
|
||||
|
||||
func Shutdown() {
|
||||
if singleton != nil {
|
||||
d2input.UnbindHandler(singleton)
|
||||
singleton = nil
|
||||
}
|
||||
}
|
||||
|
||||
func Advance(elapsed float64) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
if singleton != nil {
|
||||
return singleton.advance(elapsed)
|
||||
}
|
||||
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
func Output(format string, params ...interface{}) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.output(format, params...)
|
||||
}
|
||||
|
||||
func OutputInfo(format string, params ...interface{}) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.outputInfo(format, params...)
|
||||
}
|
||||
|
||||
func OutputWarning(format string, params ...interface{}) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.outputWarning(format, params...)
|
||||
}
|
||||
|
||||
func OutputError(format string, params ...interface{}) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.outputError(format, params...)
|
||||
}
|
||||
|
||||
func BindAction(name, description string, action interface{}) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.bindAction(name, description, action)
|
||||
}
|
||||
|
||||
func UnbindAction(name string) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.unbindAction(name)
|
||||
}
|
||||
|
||||
func Render(surface *d2surface.Surface) error {
|
||||
if singleton == nil {
|
||||
return ErrNotInit
|
||||
}
|
||||
|
||||
return singleton.render(surface)
|
||||
}
|
||||
|
||||
func BindLogger() {
|
||||
log.SetOutput(&terminalLogger{writer: log.Writer()})
|
||||
}
|
@ -7,7 +7,6 @@ import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
@ -15,9 +14,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/D2Shared/d2helper"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2surface"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -111,15 +109,6 @@ func createTerminal() (*terminal, error) {
|
||||
}
|
||||
|
||||
func (t *terminal) advance(elapsed float64) error {
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyGraveAccent) {
|
||||
switch t.visState {
|
||||
case termVisShowing, termVisShown:
|
||||
t.hide()
|
||||
case termVisHiding, termVisHidden:
|
||||
t.show()
|
||||
}
|
||||
}
|
||||
|
||||
switch t.visState {
|
||||
case termVisShowing:
|
||||
t.visAnim = math.Min(1.0, t.visAnim+elapsed/termAnimLength)
|
||||
@ -137,34 +126,56 @@ func (t *terminal) advance(elapsed float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) OnKeyDown(event d2input.KeyEvent) bool {
|
||||
maxOutputIndex := d2helper.MaxInt(0, len(t.outputHistory)-t.lineCount)
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyHome) {
|
||||
if event.Key == d2input.KeyGraveAccent {
|
||||
switch t.visState {
|
||||
case termVisShowing, termVisShown:
|
||||
t.hide()
|
||||
case termVisHiding, termVisHidden:
|
||||
t.show()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyEscape {
|
||||
t.command = ""
|
||||
return true
|
||||
}
|
||||
|
||||
if event.Key == d2input.KeyHome {
|
||||
t.outputIndex = maxOutputIndex
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEnd) {
|
||||
if event.Key == d2input.KeyEnd {
|
||||
t.outputIndex = 0
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyPageUp) {
|
||||
if event.Key == d2input.KeyPageUp {
|
||||
if t.outputIndex += t.lineCount; t.outputIndex >= maxOutputIndex {
|
||||
t.outputIndex = maxOutputIndex
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyPageDown) {
|
||||
if event.Key == d2input.KeyPageDown {
|
||||
if t.outputIndex -= t.lineCount; t.outputIndex < 0 {
|
||||
t.outputIndex = 0
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
|
||||
t.command = ""
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyUp) {
|
||||
if ebiten.IsKeyPressed(ebiten.KeyControl) {
|
||||
if event.Key == d2input.KeyUp {
|
||||
if event.KeyMod == d2input.KeyModControl {
|
||||
t.lineCount = d2helper.MaxInt(0, t.lineCount-1)
|
||||
} else if len(t.commandHistory) > 0 {
|
||||
t.command = t.commandHistory[t.commandIndex]
|
||||
@ -174,17 +185,16 @@ func (t *terminal) advance(elapsed float64) error {
|
||||
t.commandIndex--
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyDown) && ebiten.IsKeyPressed(ebiten.KeyControl) {
|
||||
if event.Key == d2input.KeyDown && event.KeyMod == d2input.KeyModControl {
|
||||
t.lineCount = d2helper.MinInt(t.lineCount+1, termRowCountMax)
|
||||
return true
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyBackspace) && len(t.command) > 0 {
|
||||
t.command = t.command[:len(t.command)-1]
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) && len(t.command) > 0 {
|
||||
if event.Key == d2input.KeyEnter && len(t.command) > 0 {
|
||||
var commandHistory []string
|
||||
for _, command := range t.commandHistory {
|
||||
if command != t.command {
|
||||
@ -201,15 +211,28 @@ func (t *terminal) advance(elapsed float64) error {
|
||||
|
||||
t.commandIndex = len(t.commandHistory) - 1
|
||||
t.command = ""
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
for _, c := range ebiten.InputChars() {
|
||||
if event.Key == d2input.KeyBackspace && len(t.command) > 0 {
|
||||
t.command = t.command[:len(t.command)-1]
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *terminal) OnKeyChars(event d2input.KeyCharsEvent) bool {
|
||||
var handled bool
|
||||
for _, c := range event.Chars {
|
||||
if c != '`' {
|
||||
t.command += string(c)
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return handled
|
||||
}
|
||||
|
||||
func (t *terminal) render(surface *d2surface.Surface) error {
|
||||
@ -328,7 +351,7 @@ func (t *terminal) execute(command string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) outputRaw(text string, category termCategory) {
|
||||
func (t *terminal) outputRaw(text string, category termCategory) error {
|
||||
var line string
|
||||
for _, word := range strings.Split(text, " ") {
|
||||
if len(line) > 0 {
|
||||
@ -347,22 +370,23 @@ func (t *terminal) outputRaw(text string, category termCategory) {
|
||||
}
|
||||
|
||||
t.outputHistory = append(t.outputHistory, termHistroyEntry{line, category})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) output(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryNone)
|
||||
func (t *terminal) output(format string, params ...interface{}) error {
|
||||
return t.outputRaw(fmt.Sprintf(format, params...), termCategoryNone)
|
||||
}
|
||||
|
||||
func (t *terminal) outputInfo(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryInfo)
|
||||
func (t *terminal) outputInfo(format string, params ...interface{}) error {
|
||||
return t.outputRaw(fmt.Sprintf(format, params...), termCategoryInfo)
|
||||
}
|
||||
|
||||
func (t *terminal) outputWarning(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryWarning)
|
||||
func (t *terminal) outputWarning(format string, params ...interface{}) error {
|
||||
return t.outputRaw(fmt.Sprintf(format, params...), termCategoryWarning)
|
||||
}
|
||||
|
||||
func (t *terminal) outputError(format string, params ...interface{}) {
|
||||
t.outputRaw(fmt.Sprintf(format, params...), termCategoryError)
|
||||
func (t *terminal) outputError(format string, params ...interface{}) error {
|
||||
return t.outputRaw(fmt.Sprintf(format, params...), termCategoryError)
|
||||
}
|
||||
|
||||
func (t *terminal) outputClear() {
|
||||
@ -409,71 +433,8 @@ func (t *terminal) bindAction(name, description string, action interface{}) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *terminal) unbindAction(name string) {
|
||||
func (t *terminal) unbindAction(name string) error {
|
||||
delete(t.actions, name)
|
||||
}
|
||||
|
||||
var singleton *terminal
|
||||
|
||||
func Initialize() error {
|
||||
if singleton != nil {
|
||||
return errors.New("terminal system is already initialized")
|
||||
}
|
||||
|
||||
var err error
|
||||
singleton, err = createTerminal()
|
||||
return err
|
||||
}
|
||||
|
||||
func Advance(elapsed float64) error {
|
||||
if singleton != nil {
|
||||
return singleton.advance(elapsed)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Output(format string, params ...interface{}) {
|
||||
if singleton != nil {
|
||||
singleton.output(format, params...)
|
||||
}
|
||||
}
|
||||
|
||||
func OutputInfo(format string, params ...interface{}) {
|
||||
if singleton != nil {
|
||||
singleton.outputInfo(format, params...)
|
||||
}
|
||||
}
|
||||
|
||||
func OutputWarning(format string, params ...interface{}) {
|
||||
if singleton != nil {
|
||||
singleton.outputWarning(format, params...)
|
||||
}
|
||||
}
|
||||
|
||||
func OutputError(format string, params ...interface{}) {
|
||||
if singleton != nil {
|
||||
singleton.outputError(format, params...)
|
||||
}
|
||||
}
|
||||
|
||||
func BindAction(name, description string, action interface{}) {
|
||||
if singleton != nil {
|
||||
singleton.bindAction(name, description, action)
|
||||
}
|
||||
}
|
||||
|
||||
func UnbindAction(name string) {
|
||||
if singleton != nil {
|
||||
singleton.unbindAction(name)
|
||||
}
|
||||
}
|
||||
|
||||
func Render(surface *d2surface.Surface) error {
|
||||
if singleton != nil {
|
||||
return singleton.render(surface)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -508,10 +469,6 @@ func (t *terminalLogger) Write(p []byte) (int, error) {
|
||||
return t.writer.Write(p)
|
||||
}
|
||||
|
||||
func BindLogger() {
|
||||
log.SetOutput(&terminalLogger{writer: log.Writer()})
|
||||
}
|
||||
|
||||
func easeInOut(t float64) float64 {
|
||||
t *= 2
|
||||
if t < 1 {
|
||||
|
2
main.go
2
main.go
@ -5,6 +5,7 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render/d2surface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2term"
|
||||
|
||||
@ -29,6 +30,7 @@ var region = kingpin.Arg("region", "Region type id").Int()
|
||||
var preset = kingpin.Arg("preset", "Level preset").Int()
|
||||
|
||||
func main() {
|
||||
d2input.Initialize()
|
||||
d2term.Initialize()
|
||||
d2term.BindLogger()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user