mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-11 11:57:44 -05:00
migrate to ebiten v2.0 API (#860)
* migrate to ebiten v2.0 API * fixed lint errors
This commit is contained in:
parent
79c147866e
commit
6e31cfb52a
62
d2app/app.go
62
d2app/app.go
@ -111,6 +111,10 @@ func Create(gitBranch, gitCommit string,
|
||||
return result
|
||||
}
|
||||
|
||||
func updateNOOP() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run executes the application and kicks off the entire game process
|
||||
func (a *App) Run() error {
|
||||
profileOption := kingpin.Flag("profile", "Profiles the program, one of (cpu, mem, block, goroutine, trace, thread, mutex)").String()
|
||||
@ -126,7 +130,8 @@ func (a *App) Run() error {
|
||||
windowTitle := fmt.Sprintf("OpenDiablo2 (%s)", a.gitBranch)
|
||||
// If we fail to initialize, we will show the error screen
|
||||
if err := a.initialize(); err != nil {
|
||||
if gameErr := a.renderer.Run(updateInitError, 800, 600, windowTitle); gameErr != nil {
|
||||
if gameErr := a.renderer.Run(updateInitError, updateNOOP, 800, 600,
|
||||
windowTitle); gameErr != nil {
|
||||
return gameErr
|
||||
}
|
||||
|
||||
@ -135,7 +140,7 @@ func (a *App) Run() error {
|
||||
|
||||
a.ToMainMenu()
|
||||
|
||||
if err := a.renderer.Run(a.update, 800, 600, windowTitle); err != nil {
|
||||
if err := a.renderer.Run(a.update, a.advance, 800, 600, windowTitle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -212,9 +217,9 @@ func (a *App) loadStrings() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) renderDebug(target d2interface.Surface) error {
|
||||
func (a *App) renderDebug(target d2interface.Surface) {
|
||||
if !a.showFPS {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
vsyncEnabled := a.renderer.GetVSyncEnabled()
|
||||
@ -241,8 +246,6 @@ func (a *App) renderDebug(target d2interface.Surface) error {
|
||||
target.PushTranslation(0, debugLineHeight)
|
||||
target.DrawTextf("Coords " + strconv.FormatInt(int64(cx), 10) + "," + strconv.FormatInt(int64(cy), 10))
|
||||
target.PopN(debugPopN)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) renderCapture(target d2interface.Surface) error {
|
||||
@ -274,35 +277,33 @@ func (a *App) renderCapture(target d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) render(target d2interface.Surface) error {
|
||||
if err := a.screen.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *App) render(target d2interface.Surface) {
|
||||
a.screen.Render(target)
|
||||
a.ui.Render(target)
|
||||
|
||||
if err := a.guiManager.Render(target); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
if err := a.renderDebug(target); err != nil {
|
||||
return err
|
||||
}
|
||||
a.renderDebug(target)
|
||||
|
||||
if err := a.renderCapture(target); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
if err := a.terminal.Render(target); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) advance(elapsed, elapsedUnscaled, current float64) error {
|
||||
elapsedLastScreenAdvance := (current - a.lastScreenAdvance) * a.timeScale
|
||||
func (a *App) advance() error {
|
||||
current := d2util.Now()
|
||||
elapsedUnscaled := current - a.lastTime
|
||||
elapsed := elapsedUnscaled * a.timeScale
|
||||
|
||||
a.lastTime = current
|
||||
|
||||
elapsedLastScreenAdvance := (current - a.lastScreenAdvance) * a.timeScale
|
||||
a.lastScreenAdvance = current
|
||||
|
||||
if err := a.screen.Advance(elapsedLastScreenAdvance); err != nil {
|
||||
@ -327,18 +328,7 @@ func (a *App) advance(elapsed, elapsedUnscaled, current float64) error {
|
||||
}
|
||||
|
||||
func (a *App) update(target d2interface.Surface) error {
|
||||
currentTime := d2util.Now()
|
||||
elapsedTimeUnscaled := currentTime - a.lastTime
|
||||
elapsedTime := elapsedTimeUnscaled * a.timeScale
|
||||
a.lastTime = currentTime
|
||||
|
||||
if err := a.advance(elapsedTime, elapsedTimeUnscaled, currentTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
a.render(target)
|
||||
|
||||
if target.GetDepth() > 0 {
|
||||
return errors.New("detected surface stack leak")
|
||||
@ -572,11 +562,7 @@ func enableProfiler(profileOption string) interface{ Stop() } {
|
||||
}
|
||||
|
||||
func updateInitError(target d2interface.Surface) error {
|
||||
err := target.Clear(colornames.Darkred)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
target.Clear(colornames.Darkred)
|
||||
target.PushTranslation(errMsgPadding, errMsgPadding)
|
||||
target.DrawTextf(`Could not find the MPQ files in the directory:
|
||||
%s\nPlease put the files and re-run the game.`, d2config.Config.MpqPath)
|
||||
|
@ -9,13 +9,13 @@ import (
|
||||
|
||||
// Animation is an animation
|
||||
type Animation interface {
|
||||
BindRenderer(Renderer) error
|
||||
BindRenderer(Renderer)
|
||||
Clone() Animation
|
||||
SetSubLoop(startFrame, EndFrame int)
|
||||
Advance(elapsed float64) error
|
||||
Render(target Surface) error
|
||||
RenderFromOrigin(target Surface, shadow bool) error
|
||||
RenderSection(sfc Surface, bound image.Rectangle) error
|
||||
Render(target Surface)
|
||||
RenderFromOrigin(target Surface, shadow bool)
|
||||
RenderSection(sfc Surface, bound image.Rectangle)
|
||||
GetFrameSize(frameIndex int) (int, int, error)
|
||||
GetCurrentFrameSize() (int, int)
|
||||
GetFrameBounds() (int, int)
|
||||
|
@ -1,15 +1,17 @@
|
||||
package d2interface
|
||||
|
||||
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
type renderCallback = func(Surface) error
|
||||
|
||||
type updateCallback = func() error
|
||||
|
||||
// Renderer interface defines the functionality of a renderer
|
||||
type Renderer interface {
|
||||
GetRendererName() string
|
||||
SetWindowIcon(fileName string)
|
||||
Run(f func(Surface) error, width, height int, title string) error
|
||||
Run(r renderCallback, u updateCallback, width, height int, title string) error
|
||||
IsDrawingSkipped() bool
|
||||
CreateSurface(surface Surface) (Surface, error)
|
||||
NewSurface(width, height int, filter d2enum.Filter) (Surface, error)
|
||||
NewSurface(width, height int) Surface
|
||||
IsFullScreen() bool
|
||||
SetFullScreen(fullScreen bool)
|
||||
SetVSyncEnabled(vsync bool)
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
// Surface represents a renderable surface.
|
||||
type Surface interface {
|
||||
Renderer() Renderer
|
||||
Clear(color color.Color) error
|
||||
Clear(color color.Color)
|
||||
DrawRect(width, height int, color color.Color)
|
||||
DrawLine(x, y int, color color.Color)
|
||||
DrawTextf(format string, params ...interface{})
|
||||
@ -26,9 +26,9 @@ type Surface interface {
|
||||
PushScale(x, y float64)
|
||||
PushBrightness(brightness float64)
|
||||
PushSaturation(saturation float64)
|
||||
Render(surface Surface) error
|
||||
Render(surface Surface)
|
||||
// Renders a section of the surface enclosed by bounds
|
||||
RenderSection(surface Surface, bound image.Rectangle) error
|
||||
ReplacePixels(pixels []byte) error
|
||||
RenderSection(surface Surface, bound image.Rectangle)
|
||||
ReplacePixels(pixels []byte)
|
||||
Screenshot() *image.RGBA
|
||||
}
|
||||
|
@ -2,11 +2,10 @@ package d2util
|
||||
|
||||
import (
|
||||
"image"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util/assets"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -19,10 +18,7 @@ var DebugPrinter = NewDebugPrinter() //nolint:gochecknoglobals // currently glob
|
||||
|
||||
// NewDebugPrinter creates a new debug printer
|
||||
func NewDebugPrinter() *GlyphPrinter {
|
||||
img, err := ebiten.NewImageFromImage(assets.CreateTextImage(), ebiten.FilterDefault)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
img := ebiten.NewImageFromImage(assets.CreateTextImage())
|
||||
|
||||
printer := &GlyphPrinter{
|
||||
glyphImageTable: img,
|
||||
@ -91,11 +87,7 @@ func (p *GlyphPrinter) drawDebugText(target *ebiten.Image, str string, ox, oy in
|
||||
op.GeoM.Translate(float64(ox+1), float64(oy))
|
||||
|
||||
op.CompositeMode = ebiten.CompositeModeLighter
|
||||
err := target.DrawImage(s, op)
|
||||
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
target.DrawImage(s, op)
|
||||
|
||||
x += cw
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ type animationDirection struct {
|
||||
frames []animationFrame
|
||||
}
|
||||
|
||||
// static check that we implement the animation interface
|
||||
var _ d2interface.Animation = &Animation{}
|
||||
|
||||
// Animation has directionality, play modes, and frame counting
|
||||
type Animation struct {
|
||||
renderer d2interface.Renderer
|
||||
@ -123,7 +126,7 @@ const (
|
||||
zero = 0.0
|
||||
)
|
||||
|
||||
func (a *Animation) renderShadow(target d2interface.Surface) error {
|
||||
func (a *Animation) renderShadow(target d2interface.Surface) {
|
||||
direction := a.directions[a.directionIndex]
|
||||
frame := direction.frames[a.frameIndex]
|
||||
|
||||
@ -145,16 +148,13 @@ func (a *Animation) renderShadow(target d2interface.Surface) error {
|
||||
target.PushBrightness(zero)
|
||||
defer target.Pop()
|
||||
|
||||
return target.Render(frame.image)
|
||||
target.Render(frame.image)
|
||||
}
|
||||
|
||||
// Render renders the animation to the given surface
|
||||
func (a *Animation) Render(target d2interface.Surface) error {
|
||||
func (a *Animation) Render(target d2interface.Surface) {
|
||||
if a.renderer == nil {
|
||||
err := a.BindRenderer(target.Renderer())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.BindRenderer(target.Renderer())
|
||||
}
|
||||
|
||||
direction := a.directions[a.directionIndex]
|
||||
@ -169,26 +169,25 @@ func (a *Animation) Render(target d2interface.Surface) error {
|
||||
target.PushColor(a.colorMod)
|
||||
defer target.Pop()
|
||||
|
||||
return target.Render(frame.image)
|
||||
target.Render(frame.image)
|
||||
}
|
||||
|
||||
// BindRenderer binds the given renderer to the animation so that it can initialize
|
||||
// the required surfaces
|
||||
func (a *Animation) BindRenderer(r d2interface.Renderer) error {
|
||||
func (a *Animation) BindRenderer(r d2interface.Renderer) {
|
||||
if a.onBindRenderer == nil {
|
||||
return errors.New("the Animation does not have a onBindRenderer handler")
|
||||
return
|
||||
}
|
||||
|
||||
return a.onBindRenderer(r)
|
||||
if err := a.onBindRenderer(r); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
// RenderFromOrigin renders the animation from the animation origin
|
||||
func (a *Animation) RenderFromOrigin(target d2interface.Surface, shadow bool) error {
|
||||
func (a *Animation) RenderFromOrigin(target d2interface.Surface, shadow bool) {
|
||||
if a.renderer == nil {
|
||||
err := a.BindRenderer(target.Renderer())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.BindRenderer(target.Renderer())
|
||||
}
|
||||
|
||||
if a.originAtBottom {
|
||||
@ -207,19 +206,18 @@ func (a *Animation) RenderFromOrigin(target d2interface.Surface, shadow bool) er
|
||||
target.PushTranslation(-halfHeight, 0)
|
||||
defer target.Pop()
|
||||
|
||||
return a.renderShadow(target)
|
||||
a.renderShadow(target)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return a.Render(target)
|
||||
a.Render(target)
|
||||
}
|
||||
|
||||
// RenderSection renders the section of the animation frame enclosed by bounds
|
||||
func (a *Animation) RenderSection(target d2interface.Surface, bound image.Rectangle) error {
|
||||
func (a *Animation) RenderSection(target d2interface.Surface, bound image.Rectangle) {
|
||||
if a.renderer == nil {
|
||||
err := a.BindRenderer(target.Renderer())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.BindRenderer(target.Renderer())
|
||||
}
|
||||
|
||||
direction := a.directions[a.directionIndex]
|
||||
@ -234,7 +232,7 @@ func (a *Animation) RenderSection(target d2interface.Surface, bound image.Rectan
|
||||
target.PushColor(a.colorMod)
|
||||
defer target.Pop()
|
||||
|
||||
return target.RenderSection(frame.image, bound)
|
||||
target.RenderSection(frame.image, bound)
|
||||
}
|
||||
|
||||
// GetFrameSize gets the Size(width, height) of a indexed frame.
|
||||
@ -398,9 +396,9 @@ func (a *Animation) SetShadow(shadow bool) {
|
||||
}
|
||||
|
||||
// Clone creates a copy of the Animation
|
||||
func (a *Animation) Clone() Animation {
|
||||
func (a *Animation) Clone() d2interface.Animation {
|
||||
clone := *a
|
||||
copy(clone.directions, a.directions)
|
||||
|
||||
return clone
|
||||
return &clone
|
||||
}
|
||||
|
@ -70,18 +70,14 @@ func (c *Composite) Render(target d2interface.Surface) error {
|
||||
layer := c.mode.layers[layerIndex]
|
||||
|
||||
if layer != nil {
|
||||
if err := layer.RenderFromOrigin(target, true); err != nil {
|
||||
return err
|
||||
}
|
||||
layer.RenderFromOrigin(target, true)
|
||||
}
|
||||
}
|
||||
|
||||
for _, layerIndex := range c.mode.cof.Priority[direction][c.mode.frameIndex] {
|
||||
layer := c.mode.layers[layerIndex]
|
||||
if layer != nil {
|
||||
if err := layer.RenderFromOrigin(target, false); err != nil {
|
||||
return err
|
||||
}
|
||||
layer.RenderFromOrigin(target, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ func newDC6Animation(
|
||||
palette: pal,
|
||||
}
|
||||
|
||||
anim := Animation{
|
||||
anim := &Animation{
|
||||
playLength: defaultPlayLength,
|
||||
playLoop: true,
|
||||
originAtBottom: true,
|
||||
@ -39,7 +39,7 @@ func newDC6Animation(
|
||||
},
|
||||
}
|
||||
|
||||
DC6.Animation = anim
|
||||
DC6.Animation = *anim
|
||||
|
||||
err := DC6.init()
|
||||
if err != nil {
|
||||
@ -174,14 +174,9 @@ func (a *DC6Animation) createFrameSurface(directionIndex, frameIndex int) (d2int
|
||||
return nil, errors.New("no renderer")
|
||||
}
|
||||
|
||||
sfc, err := a.renderer.NewSurface(int(dc6Frame.Width), int(dc6Frame.Height), d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sfc := a.renderer.NewSurface(int(dc6Frame.Width), int(dc6Frame.Height))
|
||||
|
||||
if err := sfc.ReplacePixels(colorData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sfc.ReplacePixels(colorData)
|
||||
|
||||
return sfc, nil
|
||||
}
|
||||
@ -189,7 +184,7 @@ func (a *DC6Animation) createFrameSurface(directionIndex, frameIndex int) (d2int
|
||||
// Clone creates a copy of the animation
|
||||
func (a *DC6Animation) Clone() d2interface.Animation {
|
||||
clone := &DC6Animation{}
|
||||
clone.Animation = a.Animation.Clone()
|
||||
clone.Animation = *a.Animation.Clone().(*Animation)
|
||||
clone.dc6 = a.dc6.Clone()
|
||||
clone.palette = a.palette
|
||||
|
||||
|
@ -27,7 +27,7 @@ func newDCCAnimation(
|
||||
palette: pal,
|
||||
}
|
||||
|
||||
anim := Animation{
|
||||
anim := &Animation{
|
||||
playLength: defaultPlayLength,
|
||||
playLoop: true,
|
||||
effect: effect,
|
||||
@ -41,7 +41,7 @@ func newDCCAnimation(
|
||||
},
|
||||
}
|
||||
|
||||
DCC.Animation = anim
|
||||
DCC.Animation = *anim
|
||||
|
||||
err := DCC.init()
|
||||
if err != nil {
|
||||
@ -73,7 +73,7 @@ func (a *DCCAnimation) init() error {
|
||||
// Clone creates a copy of the animation
|
||||
func (a *DCCAnimation) Clone() d2interface.Animation {
|
||||
clone := &DCCAnimation{}
|
||||
clone.Animation = a.Animation.Clone()
|
||||
clone.Animation = *a.Animation.Clone().(*Animation)
|
||||
clone.dcc = a.dcc.Clone()
|
||||
clone.palette = a.palette
|
||||
|
||||
@ -207,14 +207,9 @@ func (a *DCCAnimation) createFrameSurface(directionIndex, frameIndex int) (d2int
|
||||
return nil, errors.New("no renderer")
|
||||
}
|
||||
|
||||
sfc, err := a.renderer.NewSurface(animFrame.width, animFrame.height, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sfc := a.renderer.NewSurface(animFrame.width, animFrame.height)
|
||||
|
||||
if err := sfc.ReplacePixels(colorData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sfc.ReplacePixels(colorData)
|
||||
|
||||
return sfc, nil
|
||||
}
|
||||
|
@ -60,11 +60,7 @@ func (f *Font) GetTextMetrics(text string) (width, height int) {
|
||||
// RenderText prints a text using its configured style on a Surface (multi-lines are left-aligned, use label otherwise)
|
||||
func (f *Font) RenderText(text string, target d2interface.Surface) error {
|
||||
if f.glyphs == nil {
|
||||
err := f.sheet.BindRenderer(target.Renderer())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.sheet.BindRenderer(target.Renderer())
|
||||
f.initGlyphs()
|
||||
}
|
||||
|
||||
@ -88,9 +84,7 @@ func (f *Font) RenderText(text string, target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.sheet.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
f.sheet.Render(target)
|
||||
|
||||
lineHeight = d2math.MaxInt(lineHeight, glyph.height)
|
||||
lineLength++
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/audio"
|
||||
"github.com/hajimehoshi/ebiten/audio/wav"
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
"github.com/hajimehoshi/ebiten/v2/audio/wav"
|
||||
)
|
||||
|
||||
const sampleRate = 44100
|
||||
@ -16,20 +16,14 @@ const sampleRate = 44100
|
||||
var _ d2interface.AudioProvider = &AudioProvider{} // Static check to confirm struct conforms to interface
|
||||
|
||||
// CreateAudio creates an instance of ebiten's audio provider
|
||||
func CreateAudio(am *d2asset.AssetManager) (*AudioProvider, error) {
|
||||
func CreateAudio(am *d2asset.AssetManager) *AudioProvider {
|
||||
result := &AudioProvider{
|
||||
asset: am,
|
||||
}
|
||||
|
||||
var err error
|
||||
result.audioContext, err = audio.NewContext(sampleRate)
|
||||
result.audioContext = audio.NewContext(sampleRate)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return result
|
||||
}
|
||||
|
||||
// AudioProvider represents a provider capable of playing audio
|
||||
@ -51,10 +45,7 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
||||
eap.lastBgm = song
|
||||
|
||||
if song == "" && eap.bgmAudio != nil && eap.bgmAudio.IsPlaying() {
|
||||
err := eap.bgmAudio.Pause()
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
eap.bgmAudio.Pause()
|
||||
|
||||
return
|
||||
}
|
||||
@ -95,11 +86,7 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = eap.bgmAudio.Play()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
eap.bgmAudio.Play()
|
||||
}
|
||||
|
||||
// LoadSound loads a sound affect so that it canb e played
|
||||
|
@ -1,13 +1,14 @@
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/audio"
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
)
|
||||
|
||||
type panStream struct {
|
||||
audio.ReadSeekCloser
|
||||
io.ReadSeeker
|
||||
pan float64 // -1: left; 0: center; 1: right
|
||||
}
|
||||
|
||||
@ -15,15 +16,15 @@ const (
|
||||
bitsPerByte = 8
|
||||
)
|
||||
|
||||
func newPanStreamFromReader(src audio.ReadSeekCloser) *panStream {
|
||||
func newPanStreamFromReader(src io.ReadSeeker) *panStream {
|
||||
return &panStream{
|
||||
ReadSeekCloser: src,
|
||||
pan: 0,
|
||||
ReadSeeker: src,
|
||||
pan: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *panStream) Read(p []byte) (n int, err error) {
|
||||
n, err = s.ReadSeekCloser.Read(p)
|
||||
n, err = s.ReadSeeker.Read(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -74,18 +75,10 @@ func (v *SoundEffect) Play() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = v.player.Play()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.player.Play()
|
||||
}
|
||||
|
||||
// Stop stops the sound effect
|
||||
func (v *SoundEffect) Stop() {
|
||||
err := v.player.Pause()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
v.player.Pause()
|
||||
}
|
||||
|
@ -44,8 +44,8 @@ func (b *Button) onMouseLeave(_ d2interface.MouseMoveEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Button) render(target d2interface.Surface) error {
|
||||
return target.Render(b.surfaces[b.state])
|
||||
func (b *Button) render(target d2interface.Surface) {
|
||||
target.Render(b.surfaces[b.state])
|
||||
}
|
||||
|
||||
func (b *Button) getSize() (width, height int) {
|
||||
|
@ -20,13 +20,9 @@ func renderSegmented(animation d2interface.Animation, segmentsX, segmentsY, fram
|
||||
}
|
||||
|
||||
target.PushTranslation(x+currentX, y+currentY)
|
||||
err := animation.Render(target)
|
||||
animation.Render(target)
|
||||
target.Pop()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
width, height := animation.GetCurrentFrameSize()
|
||||
maxHeight = d2math.MaxInt(maxHeight, height)
|
||||
currentX += width
|
||||
|
@ -91,29 +91,21 @@ func (m *GuiManager) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||
// Render renders the GuiManager to the given surface
|
||||
func (m *GuiManager) Render(target d2interface.Surface) error {
|
||||
if m.loading {
|
||||
if err := m.renderLoadScreen(target); err != nil {
|
||||
return err
|
||||
}
|
||||
m.renderLoadScreen(target)
|
||||
} else if m.layout != nil {
|
||||
m.layout.SetSize(target.GetSize())
|
||||
if err := m.layout.render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
m.layout.render(target)
|
||||
}
|
||||
|
||||
if m.cursorVisible {
|
||||
if err := m.renderCursor(target); err != nil {
|
||||
return err
|
||||
}
|
||||
m.renderCursor(target)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GuiManager) renderLoadScreen(target d2interface.Surface) error {
|
||||
if clearErr := target.Clear(color.Black); clearErr != nil {
|
||||
return clearErr
|
||||
}
|
||||
func (m *GuiManager) renderLoadScreen(target d2interface.Surface) {
|
||||
target.Clear(color.Black)
|
||||
|
||||
pushCount := 0
|
||||
|
||||
@ -128,10 +120,10 @@ func (m *GuiManager) renderLoadScreen(target d2interface.Surface) error {
|
||||
|
||||
defer target.PopN(pushCount)
|
||||
|
||||
return m.loadingAnim.Render(target)
|
||||
m.loadingAnim.Render(target)
|
||||
}
|
||||
|
||||
func (m *GuiManager) renderCursor(target d2interface.Surface) error {
|
||||
func (m *GuiManager) renderCursor(target d2interface.Surface) {
|
||||
_, height := m.cursorAnim.GetCurrentFrameSize()
|
||||
pushCount := 0
|
||||
|
||||
@ -143,7 +135,7 @@ func (m *GuiManager) renderCursor(target d2interface.Surface) error {
|
||||
|
||||
defer target.PopN(pushCount)
|
||||
|
||||
return m.cursorAnim.Render(target)
|
||||
m.cursorAnim.Render(target)
|
||||
}
|
||||
|
||||
// Advance advances the GuiManager state
|
||||
|
@ -3,7 +3,6 @@ package d2gui
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
@ -35,8 +34,8 @@ func createLabel(renderer d2interface.Renderer, text string, font *d2asset.Font)
|
||||
return label
|
||||
}
|
||||
|
||||
func (l *Label) render(target d2interface.Surface) error {
|
||||
return target.Render(l.surface)
|
||||
func (l *Label) render(target d2interface.Surface) {
|
||||
target.Render(l.surface)
|
||||
}
|
||||
|
||||
func (l *Label) getSize() (width, height int) {
|
||||
@ -60,10 +59,7 @@ func (l *Label) SetText(text string) error {
|
||||
func (l *Label) setText(text string) error {
|
||||
width, height := l.font.GetTextMetrics(text)
|
||||
|
||||
surface, err := l.renderer.NewSurface(width, height, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
surface := l.renderer.NewSurface(width, height)
|
||||
|
||||
if err := l.font.RenderText(text, surface); err != nil {
|
||||
return err
|
||||
|
@ -3,7 +3,6 @@ package d2gui
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -49,6 +48,9 @@ const (
|
||||
PositionTypeHorizontal
|
||||
)
|
||||
|
||||
// static check that Layout implements a widget
|
||||
var _ widget = &Layout{}
|
||||
|
||||
// Layout is a gui element container which will automatically position/align gui elements.
|
||||
// Layouts are gui elements as well, so they can be nested in other layouts.
|
||||
type Layout struct {
|
||||
@ -179,7 +181,7 @@ func (l *Layout) Clear() {
|
||||
l.entries = nil
|
||||
}
|
||||
|
||||
func (l *Layout) render(target d2interface.Surface) error {
|
||||
func (l *Layout) render(target d2interface.Surface) {
|
||||
l.AdjustEntryPlacement()
|
||||
|
||||
for _, entry := range l.entries {
|
||||
@ -187,18 +189,12 @@ func (l *Layout) render(target d2interface.Surface) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := l.renderEntry(entry, target); err != nil {
|
||||
return err
|
||||
}
|
||||
l.renderEntry(entry, target)
|
||||
|
||||
if layoutDebug {
|
||||
if err := l.renderEntryDebug(entry, target); err != nil {
|
||||
return err
|
||||
}
|
||||
l.renderEntryDebug(entry, target)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Layout) advance(elapsed float64) error {
|
||||
@ -211,14 +207,14 @@ func (l *Layout) advance(elapsed float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Layout) renderEntry(entry *layoutEntry, target d2interface.Surface) error {
|
||||
func (l *Layout) renderEntry(entry *layoutEntry, target d2interface.Surface) {
|
||||
target.PushTranslation(entry.x, entry.y)
|
||||
defer target.Pop()
|
||||
|
||||
return entry.widget.render(target)
|
||||
entry.widget.render(target)
|
||||
}
|
||||
|
||||
func (l *Layout) renderEntryDebug(entry *layoutEntry, target d2interface.Surface) error {
|
||||
func (l *Layout) renderEntryDebug(entry *layoutEntry, target d2interface.Surface) {
|
||||
target.PushTranslation(entry.x, entry.y)
|
||||
defer target.Pop()
|
||||
|
||||
@ -244,8 +240,6 @@ func (l *Layout) renderEntryDebug(entry *layoutEntry, target d2interface.Surface
|
||||
target.PushTranslation(0, entry.height)
|
||||
target.DrawLine(entry.width, 0, drawColor)
|
||||
target.Pop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Layout) getContentSize() (width, height int) {
|
||||
@ -471,10 +465,7 @@ func (l *Layout) createButton(renderer d2interface.Renderer, text string,
|
||||
surfaces := make([]d2interface.Surface, surfaceCount)
|
||||
|
||||
for i := 0; i < surfaceCount; i++ {
|
||||
surface, surfaceErr := renderer.NewSurface(buttonWidth, buttonHeight, d2enum.FilterNearest)
|
||||
if surfaceErr != nil {
|
||||
return nil, surfaceErr
|
||||
}
|
||||
surface := renderer.NewSurface(buttonWidth, buttonHeight)
|
||||
|
||||
segX, segY, frame := config.segmentsX, config.segmentsY, i
|
||||
if segErr := renderSegmented(animation, segX, segY, frame, surface); segErr != nil {
|
||||
@ -492,7 +483,7 @@ func (l *Layout) createButton(renderer d2interface.Renderer, text string,
|
||||
}
|
||||
|
||||
surface.PushTranslation(textX+textOffsetX, textY+textOffsetY)
|
||||
surfaceErr = font.RenderText(text, surface)
|
||||
surfaceErr := font.RenderText(text, surface)
|
||||
surface.Pop()
|
||||
|
||||
if surfaceErr != nil {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package d2gui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
@ -15,6 +17,9 @@ const (
|
||||
DirectionBackward
|
||||
)
|
||||
|
||||
// static check that Sprite implements widget
|
||||
var _ widget = &Sprite{}
|
||||
|
||||
// Sprite is an image
|
||||
type Sprite struct {
|
||||
widgetBase
|
||||
@ -67,13 +72,13 @@ func createAnimatedSprite(
|
||||
return sprite, nil
|
||||
}
|
||||
|
||||
func (s *AnimatedSprite) render(target d2interface.Surface) error {
|
||||
func (s *AnimatedSprite) render(target d2interface.Surface) {
|
||||
_, frameHeight := s.animation.GetCurrentFrameSize()
|
||||
|
||||
target.PushTranslation(s.x, s.y-frameHeight)
|
||||
defer target.Pop()
|
||||
|
||||
return s.animation.Render(target)
|
||||
s.animation.Render(target)
|
||||
}
|
||||
|
||||
// SetSegmented sets the segment properties of the sprite
|
||||
@ -83,8 +88,11 @@ func (s *Sprite) SetSegmented(segmentsX, segmentsY, frameOffset int) {
|
||||
s.frameOffset = frameOffset
|
||||
}
|
||||
|
||||
func (s *Sprite) render(target d2interface.Surface) error {
|
||||
return renderSegmented(s.animation, s.segmentsX, s.segmentsY, s.frameOffset, target)
|
||||
func (s *Sprite) render(target d2interface.Surface) {
|
||||
err := renderSegmented(s.animation, s.segmentsX, s.segmentsY, s.frameOffset, target)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sprite) advance(elapsed float64) error {
|
||||
|
@ -11,7 +11,7 @@ type MouseHandler func(d2interface.MouseEvent)
|
||||
type MouseMoveHandler func(d2interface.MouseMoveEvent)
|
||||
|
||||
type widget interface {
|
||||
render(target d2interface.Surface) error
|
||||
render(target d2interface.Surface)
|
||||
advance(elapsed float64) error
|
||||
|
||||
onMouseMove(event d2interface.MouseMoveEvent) bool
|
||||
@ -130,9 +130,7 @@ func (w *widgetBase) isExpanding() bool {
|
||||
return w.expanding
|
||||
}
|
||||
|
||||
func (w *widgetBase) render(_ d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
func (w *widgetBase) render(_ d2interface.Surface) { /* NOOP */ }
|
||||
|
||||
func (w *widgetBase) advance(_ float64) error {
|
||||
return nil
|
||||
|
@ -2,8 +2,8 @@
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/inpututil"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
)
|
||||
|
@ -50,9 +50,7 @@ func (ae *AnimatedEntity) Render(target d2interface.Surface) {
|
||||
ae.highlight = false
|
||||
}
|
||||
|
||||
if err := ae.animation.Render(target); err != nil {
|
||||
fmt.Printf("failed to render animated entity, err: %v\n", err)
|
||||
}
|
||||
ae.animation.Render(target)
|
||||
}
|
||||
|
||||
// GetDirection returns the current facing direction of this entity.
|
||||
|
@ -373,9 +373,7 @@ func (mr *MapRenderer) renderFloor(tile d2ds1.FloorShadowRecord, target d2interf
|
||||
target.PushTranslation(mr.viewport.GetTranslationScreen())
|
||||
defer target.Pop()
|
||||
|
||||
if err := target.Render(img); err != nil {
|
||||
fmt.Printf("failed to render the floor, err: %v\n", err)
|
||||
}
|
||||
target.Render(img)
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) renderWall(tile d2ds1.WallRecord, viewport *Viewport, target d2interface.Surface) {
|
||||
@ -391,9 +389,7 @@ func (mr *MapRenderer) renderWall(tile d2ds1.WallRecord, viewport *Viewport, tar
|
||||
target.PushTranslation(viewport.GetTranslationScreen())
|
||||
defer target.Pop()
|
||||
|
||||
if err := target.Render(img); err != nil {
|
||||
fmt.Printf("failed to render the wall, err: %v\n", err)
|
||||
}
|
||||
target.Render(img)
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) renderShadow(tile d2ds1.FloorShadowRecord, target d2interface.Surface) {
|
||||
@ -411,9 +407,7 @@ func (mr *MapRenderer) renderShadow(tile d2ds1.FloorShadowRecord, target d2inter
|
||||
target.PushColor(color.RGBA{R: 255, G: 255, B: 255, A: 160}) //nolint:gomnd // Not a magic number...
|
||||
defer target.Pop()
|
||||
|
||||
if err := target.Render(img); err != nil {
|
||||
fmt.Printf("failed to render the shadow, err: %v\n", err)
|
||||
}
|
||||
target.Render(img)
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) renderMapDebug(mapDebugVisLevel int, target d2interface.Surface, startX, startY, endX, endY int) {
|
||||
|
@ -100,20 +100,13 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord) {
|
||||
|
||||
tileYOffset := d2math.AbsInt32(tileYMinimum)
|
||||
tileHeight := d2math.AbsInt32(tileData[i].Height)
|
||||
image, err := mr.renderer.NewSurface(int(tileData[i].Width), int(tileHeight), d2enum.FilterNearest)
|
||||
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
image := mr.renderer.NewSurface(int(tileData[i].Width), int(tileHeight))
|
||||
|
||||
indexData := make([]byte, tileData[i].Width*tileHeight)
|
||||
d2dt1.DecodeTileGfxData(tileData[i].Blocks, &indexData, tileYOffset, tileData[i].Width)
|
||||
pixels := d2util.ImgIndexToRGBA(indexData, mr.palette)
|
||||
|
||||
err = image.ReplacePixels(pixels)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
image.ReplacePixels(pixels)
|
||||
|
||||
mr.setImageCacheRecord(tile.Style, tile.Sequence, 0, tileIndex, image)
|
||||
}
|
||||
@ -151,19 +144,13 @@ func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord) {
|
||||
return
|
||||
}
|
||||
|
||||
image, err := mr.renderer.NewSurface(int(tileData.Width), tileHeight, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
image := mr.renderer.NewSurface(int(tileData.Width), tileHeight)
|
||||
|
||||
indexData := make([]byte, tileData.Width*int32(tileHeight))
|
||||
d2dt1.DecodeTileGfxData(tileData.Blocks, &indexData, tileYOffset, tileData.Width)
|
||||
pixels := d2util.ImgIndexToRGBA(indexData, mr.palette)
|
||||
|
||||
err = image.ReplacePixels(pixels)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
image.ReplacePixels(pixels)
|
||||
|
||||
mr.setImageCacheRecord(tile.Style, tile.Sequence, d2enum.TileShadow, tile.RandomIndex, image)
|
||||
}
|
||||
@ -222,10 +209,7 @@ func (mr *MapRenderer) generateWallCache(tile *d2ds1.WallRecord) {
|
||||
return
|
||||
}
|
||||
|
||||
image, err := mr.renderer.NewSurface(tileSurfaceWidth, int(realHeight), d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
image := mr.renderer.NewSurface(tileSurfaceWidth, int(realHeight))
|
||||
|
||||
indexData := make([]byte, tileSurfaceWidth*realHeight)
|
||||
|
||||
@ -237,9 +221,7 @@ func (mr *MapRenderer) generateWallCache(tile *d2ds1.WallRecord) {
|
||||
|
||||
pixels := d2util.ImgIndexToRGBA(indexData, mr.palette)
|
||||
|
||||
if err := image.ReplacePixels(pixels); err != nil {
|
||||
log.Panicf(err.Error())
|
||||
}
|
||||
image.ReplacePixels(pixels)
|
||||
|
||||
mr.setImageCacheRecord(tile.Style, tile.Sequence, tile.Type, tile.RandomIndex, image)
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
@ -22,19 +23,41 @@ const (
|
||||
defaultScaleY = 1.0
|
||||
)
|
||||
|
||||
type renderCallback = func(surface d2interface.Surface) error
|
||||
|
||||
type updateCallback = func() error
|
||||
|
||||
// static check that we implement our renderer interface
|
||||
var _ d2interface.Renderer = &Renderer{}
|
||||
|
||||
// Renderer is an implementation of a renderer
|
||||
type Renderer struct {
|
||||
renderCallback func(surface d2interface.Surface) error
|
||||
updateCallback
|
||||
renderCallback
|
||||
lastRenderError error
|
||||
}
|
||||
|
||||
// Update updates the screen with the given *ebiten.Image
|
||||
func (r *Renderer) Update(screen *ebiten.Image) error {
|
||||
err := r.renderCallback(createEbitenSurface(r, screen))
|
||||
if err != nil {
|
||||
return err
|
||||
// Update calls the game's logical update function (the `Advance` method)
|
||||
func (r *Renderer) Update() error {
|
||||
if r.updateCallback == nil {
|
||||
return errors.New("no update callback defined for ebiten renderer")
|
||||
}
|
||||
|
||||
return nil
|
||||
return r.updateCallback()
|
||||
}
|
||||
|
||||
const drawError = "no render callback defined for ebiten renderer"
|
||||
|
||||
// Draw updates the screen with the given *ebiten.Image
|
||||
func (r *Renderer) Draw(screen *ebiten.Image) {
|
||||
r.lastRenderError = nil
|
||||
|
||||
if r.renderCallback == nil {
|
||||
r.lastRenderError = errors.New(drawError)
|
||||
return
|
||||
}
|
||||
|
||||
r.lastRenderError = r.renderCallback(createEbitenSurface(r, screen))
|
||||
}
|
||||
|
||||
// Layout returns the renderer screen width and height
|
||||
@ -64,7 +87,7 @@ func (*Renderer) GetRendererName() string {
|
||||
|
||||
// SetWindowIcon sets the icon for the window, visible in the chrome of the window
|
||||
func (*Renderer) SetWindowIcon(fileName string) {
|
||||
_, iconImage, err := ebitenutil.NewImageFromFile(fileName, ebiten.FilterLinear)
|
||||
_, iconImage, err := ebitenutil.NewImageFromFile(fileName)
|
||||
if err == nil {
|
||||
ebiten.SetWindowIcon([]image.Image{iconImage})
|
||||
}
|
||||
@ -72,12 +95,13 @@ func (*Renderer) SetWindowIcon(fileName string) {
|
||||
|
||||
// IsDrawingSkipped returns a bool for whether or not the drawing has been skipped
|
||||
func (r *Renderer) IsDrawingSkipped() bool {
|
||||
return ebiten.IsDrawingSkipped()
|
||||
return r.lastRenderError != nil
|
||||
}
|
||||
|
||||
// Run initializes the renderer
|
||||
func (r *Renderer) Run(f func(surface d2interface.Surface) error, width, height int, title string) error {
|
||||
func (r *Renderer) Run(f renderCallback, u updateCallback, width, height int, title string) error {
|
||||
r.renderCallback = f
|
||||
r.updateCallback = u
|
||||
|
||||
ebiten.SetWindowTitle(title)
|
||||
ebiten.SetWindowResizable(true)
|
||||
@ -105,15 +129,10 @@ func (r *Renderer) CreateSurface(surface d2interface.Surface) (d2interface.Surfa
|
||||
}
|
||||
|
||||
// NewSurface creates a new surface
|
||||
func (r *Renderer) NewSurface(width, height int, filter d2enum.Filter) (d2interface.Surface, error) {
|
||||
ebitenFilter := d2ToEbitenFilter(filter)
|
||||
img, err := ebiten.NewImage(width, height, ebitenFilter)
|
||||
func (r *Renderer) NewSurface(width, height int) d2interface.Surface {
|
||||
img := ebiten.NewImage(width, height)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createEbitenSurface(r, img), nil
|
||||
return createEbitenSurface(r, img)
|
||||
}
|
||||
|
||||
// IsFullScreen returns a boolean for whether or not the renderer is currently set to fullscreen
|
||||
|
@ -6,14 +6,17 @@ import (
|
||||
"image/color"
|
||||
"math"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
)
|
||||
|
||||
// static check that we implement our interface
|
||||
var _ d2interface.Surface = &ebitenSurface{}
|
||||
|
||||
const (
|
||||
maxAlpha = 0xff
|
||||
cacheLimit = 512
|
||||
@ -135,7 +138,7 @@ func (s *ebitenSurface) PopN(n int) {
|
||||
}
|
||||
|
||||
// Render renders the given surface
|
||||
func (s *ebitenSurface) Render(sfc d2interface.Surface) error {
|
||||
func (s *ebitenSurface) Render(sfc d2interface.Surface) {
|
||||
opts := s.createDrawImageOptions()
|
||||
|
||||
if s.stateCurrent.brightness != 1 || s.stateCurrent.saturation != 1 {
|
||||
@ -144,11 +147,11 @@ func (s *ebitenSurface) Render(sfc d2interface.Surface) error {
|
||||
|
||||
s.handleStateEffect(opts)
|
||||
|
||||
return s.image.DrawImage(sfc.(*ebitenSurface).image, opts)
|
||||
s.image.DrawImage(sfc.(*ebitenSurface).image, opts)
|
||||
}
|
||||
|
||||
// Renders the section of the surface, given the bounds
|
||||
func (s *ebitenSurface) RenderSection(sfc d2interface.Surface, bound image.Rectangle) error {
|
||||
func (s *ebitenSurface) RenderSection(sfc d2interface.Surface, bound image.Rectangle) {
|
||||
opts := s.createDrawImageOptions()
|
||||
|
||||
if s.stateCurrent.brightness != 0 {
|
||||
@ -157,7 +160,7 @@ func (s *ebitenSurface) RenderSection(sfc d2interface.Surface, bound image.Recta
|
||||
|
||||
s.handleStateEffect(opts)
|
||||
|
||||
return s.image.DrawImage(sfc.(*ebitenSurface).image.SubImage(bound).(*ebiten.Image), opts)
|
||||
s.image.DrawImage(sfc.(*ebitenSurface).image.SubImage(bound).(*ebiten.Image), opts)
|
||||
}
|
||||
|
||||
func (s *ebitenSurface) createDrawImageOptions() *ebiten.DrawImageOptions {
|
||||
@ -233,8 +236,8 @@ func (s *ebitenSurface) DrawRect(width, height int, fillColor color.Color) {
|
||||
}
|
||||
|
||||
// Clear clears the entire surface, filling with the given color
|
||||
func (s *ebitenSurface) Clear(fillColor color.Color) error {
|
||||
return s.image.Fill(fillColor)
|
||||
func (s *ebitenSurface) Clear(fillColor color.Color) {
|
||||
s.image.Fill(fillColor)
|
||||
}
|
||||
|
||||
// GetSize gets the size of the surface
|
||||
@ -248,8 +251,8 @@ func (s *ebitenSurface) GetDepth() int {
|
||||
}
|
||||
|
||||
// ReplacePixels replaces pixels in the surface with the given pixels
|
||||
func (s *ebitenSurface) ReplacePixels(pixels []byte) error {
|
||||
return s.image.ReplacePixels(pixels)
|
||||
func (s *ebitenSurface) ReplacePixels(pixels []byte) {
|
||||
s.image.ReplacePixels(pixels)
|
||||
}
|
||||
|
||||
// Screenshot returns an *image.RGBA of the surface
|
||||
|
@ -1,22 +1,18 @@
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
)
|
||||
|
||||
func d2ToEbitenFilter(filter d2enum.Filter) ebiten.Filter {
|
||||
switch filter {
|
||||
case d2enum.FilterDefault:
|
||||
return ebiten.FilterDefault
|
||||
case d2enum.FilterLinear:
|
||||
return ebiten.FilterLinear
|
||||
case d2enum.FilterNearest:
|
||||
return ebiten.FilterNearest
|
||||
default:
|
||||
return ebiten.FilterLinear
|
||||
}
|
||||
|
||||
return ebiten.FilterDefault
|
||||
}
|
||||
|
||||
// func ebitenToD2Filter(filter ebiten.Filter) d2enum.Filter {
|
||||
|
@ -3,7 +3,7 @@ package ebiten
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
)
|
||||
|
@ -22,7 +22,7 @@ type ScreenUnloadHandler interface {
|
||||
|
||||
// ScreenRenderHandler is an exported interface
|
||||
type ScreenRenderHandler interface {
|
||||
Render(target d2interface.Surface) error
|
||||
Render(target d2interface.Surface)
|
||||
}
|
||||
|
||||
// ScreenAdvanceHandler is an exported interface
|
||||
|
@ -93,12 +93,8 @@ func (sm *ScreenManager) Advance(elapsed float64) error {
|
||||
}
|
||||
|
||||
// Render renders the UI by a given surface
|
||||
func (sm *ScreenManager) Render(surface d2interface.Surface) error {
|
||||
func (sm *ScreenManager) Render(surface d2interface.Surface) {
|
||||
if handler, ok := sm.currentScreen.(ScreenRenderHandler); ok {
|
||||
if err := handler.Render(surface); err != nil {
|
||||
return err
|
||||
}
|
||||
handler.Render(surface)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -312,11 +312,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
||||
}
|
||||
}
|
||||
|
||||
btn.normalSurface, err = ui.renderer.NewSurface(btn.width, btn.height, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil
|
||||
}
|
||||
btn.normalSurface = ui.renderer.NewSurface(btn.width, btn.height)
|
||||
|
||||
buttonSprite.SetPosition(0, 0)
|
||||
buttonSprite.SetEffect(d2enum.DrawEffectModulate)
|
||||
@ -336,13 +332,12 @@ type buttonStateDescriptor struct {
|
||||
}
|
||||
|
||||
func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, label *Label) {
|
||||
var err error
|
||||
|
||||
numButtonStates := btnSprite.GetFrameCount() / (btnLayout.XSegments * btnLayout.YSegments)
|
||||
|
||||
// buttons always have a base image
|
||||
if v.buttonLayout.HasImage {
|
||||
err = btnSprite.RenderSegmented(v.normalSurface, btnLayout.XSegments, btnLayout.YSegments, btnLayout.BaseFrame)
|
||||
err := btnSprite.RenderSegmented(v.normalSurface, btnLayout.XSegments,
|
||||
btnLayout.YSegments, btnLayout.BaseFrame)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to render button normalSurface, err: %v\n", err)
|
||||
}
|
||||
@ -364,7 +359,7 @@ func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, lab
|
||||
buttonStateConfigs := make([]*buttonStateDescriptor, 0)
|
||||
|
||||
// pressed button
|
||||
if numButtonStates >= buttonStatePressed {
|
||||
if numButtonStates > buttonStatePressed {
|
||||
state := &buttonStateDescriptor{
|
||||
baseFrame + buttonStatePressed,
|
||||
xOffset - pressedButtonOffset, textY + pressedButtonOffset,
|
||||
@ -376,7 +371,7 @@ func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, lab
|
||||
}
|
||||
|
||||
// toggle button
|
||||
if numButtonStates >= buttonStateToggled {
|
||||
if numButtonStates > buttonStateToggled {
|
||||
buttonStateConfigs = append(buttonStateConfigs, &buttonStateDescriptor{
|
||||
baseFrame + buttonStateToggled,
|
||||
xOffset, textY,
|
||||
@ -386,7 +381,7 @@ func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, lab
|
||||
}
|
||||
|
||||
// pressed+toggled
|
||||
if numButtonStates >= buttonStatePressedToggled {
|
||||
if numButtonStates > buttonStatePressedToggled {
|
||||
buttonStateConfigs = append(buttonStateConfigs, &buttonStateDescriptor{
|
||||
baseFrame + buttonStatePressedToggled,
|
||||
xOffset, textY,
|
||||
@ -410,21 +405,18 @@ func (v *Button) prerenderStates(btnSprite *Sprite, btnLayout *ButtonLayout, lab
|
||||
for stateIdx, w, h := 0, v.width, v.height; stateIdx < len(buttonStateConfigs); stateIdx++ {
|
||||
state := buttonStateConfigs[stateIdx]
|
||||
|
||||
if stateIdx >= 2 && btnLayout.ResourceName == d2resource.BuySellButton {
|
||||
if stateIdx > 1 && btnLayout.ResourceName == d2resource.BuySellButton {
|
||||
// Without returning early, the button UI gets all subsequent (unrelated) frames
|
||||
// stacked on top. Only 2 frames from this sprite are applicable to the button
|
||||
// in question. The presentation is incorrect without this hack!
|
||||
continue
|
||||
}
|
||||
|
||||
surface, err := v.manager.renderer.NewSurface(w, h, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
surface := v.manager.renderer.NewSurface(w, h)
|
||||
|
||||
*state.prerenderdestination = surface
|
||||
|
||||
err = btnSprite.RenderSegmented(*state.prerenderdestination, xSeg, ySeg, state.baseFrame)
|
||||
err := btnSprite.RenderSegmented(*state.prerenderdestination, xSeg, ySeg, state.baseFrame)
|
||||
if err != nil {
|
||||
fmt.Printf(state.fmtErr, err)
|
||||
}
|
||||
@ -461,29 +453,23 @@ func (v *Button) Render(target d2interface.Surface) error {
|
||||
target.PushTranslation(v.x, v.y)
|
||||
defer target.Pop()
|
||||
|
||||
var err error
|
||||
|
||||
switch {
|
||||
case !v.enabled:
|
||||
target.PushColor(d2util.Color(lightGreyAlpha75))
|
||||
defer target.Pop()
|
||||
err = target.Render(v.disabledSurface)
|
||||
target.Render(v.disabledSurface)
|
||||
case v.toggled && v.pressed:
|
||||
err = target.Render(v.pressedToggledSurface)
|
||||
target.Render(v.pressedToggledSurface)
|
||||
case v.pressed:
|
||||
if v.buttonLayout.AllowFrameChange {
|
||||
err = target.Render(v.pressedSurface)
|
||||
target.Render(v.pressedSurface)
|
||||
} else {
|
||||
err = target.Render(v.normalSurface)
|
||||
target.Render(v.normalSurface)
|
||||
}
|
||||
case v.toggled:
|
||||
err = target.Render(v.toggledSurface)
|
||||
target.Render(v.toggledSurface)
|
||||
default:
|
||||
err = target.Render(v.normalSurface)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("failed to render button surface, err: %v\n", err)
|
||||
target.Render(v.normalSurface)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -49,11 +49,7 @@ func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
|
||||
|
||||
checkboxSprite.SetPosition(0, 0)
|
||||
|
||||
result.Image, err = ui.renderer.NewSurface(result.width, result.height, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil
|
||||
}
|
||||
result.Image = ui.renderer.NewSurface(result.width, result.height)
|
||||
|
||||
err = checkboxSprite.RenderSegmented(result.Image, 1, 1, 0)
|
||||
if err != nil {
|
||||
@ -61,11 +57,7 @@ func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
|
||||
return nil
|
||||
}
|
||||
|
||||
result.checkedImage, err = ui.renderer.NewSurface(result.width, result.height, d2enum.FilterNearest)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
return nil
|
||||
}
|
||||
result.checkedImage = ui.renderer.NewSurface(result.width, result.height)
|
||||
|
||||
err = checkboxSprite.RenderSegmented(result.checkedImage, 1, 1, 1)
|
||||
if err != nil {
|
||||
@ -85,8 +77,6 @@ func (v *Checkbox) bindManager(manager *UIManager) {
|
||||
|
||||
// Render renders the checkbox
|
||||
func (v *Checkbox) Render(target d2interface.Surface) error {
|
||||
var err error
|
||||
|
||||
target.PushTranslation(v.x, v.y)
|
||||
defer target.Pop()
|
||||
|
||||
@ -94,15 +84,9 @@ func (v *Checkbox) Render(target d2interface.Surface) error {
|
||||
defer target.Pop()
|
||||
|
||||
if v.checkState {
|
||||
err = target.Render(v.checkedImage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target.Render(v.checkedImage)
|
||||
} else {
|
||||
err = target.Render(v.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target.Render(v.Image)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -225,9 +225,7 @@ func (u *UIFrame) renderFramePiece(sfc d2interface.Surface, x, y, idx int) error
|
||||
|
||||
u.frame.SetPosition(x, y)
|
||||
|
||||
if err := u.frame.Render(sfc); err != nil {
|
||||
return err
|
||||
}
|
||||
u.frame.Render(sfc)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -29,30 +29,27 @@ func (ui *UIManager) NewSprite(animationPath, palettePath string) (*Sprite, erro
|
||||
return nil, fmt.Errorf(errNoAnimation)
|
||||
}
|
||||
|
||||
err = animation.BindRenderer(ui.renderer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
animation.BindRenderer(ui.renderer)
|
||||
|
||||
return &Sprite{animation: animation}, nil
|
||||
}
|
||||
|
||||
// Render renders the sprite on the given surface
|
||||
func (s *Sprite) Render(target d2interface.Surface) error {
|
||||
func (s *Sprite) Render(target d2interface.Surface) {
|
||||
_, frameHeight := s.animation.GetCurrentFrameSize()
|
||||
|
||||
target.PushTranslation(s.x, s.y-frameHeight)
|
||||
defer target.Pop()
|
||||
|
||||
return s.animation.Render(target)
|
||||
s.animation.Render(target)
|
||||
}
|
||||
|
||||
// RenderSection renders the section of the sprite enclosed by bounds
|
||||
func (s *Sprite) RenderSection(sfc d2interface.Surface, bound image.Rectangle) error {
|
||||
func (s *Sprite) RenderSection(sfc d2interface.Surface, bound image.Rectangle) {
|
||||
sfc.PushTranslation(s.x, s.y-bound.Dy())
|
||||
defer sfc.Pop()
|
||||
|
||||
return s.animation.RenderSection(sfc, bound)
|
||||
s.animation.RenderSection(sfc, bound)
|
||||
}
|
||||
|
||||
// RenderSegmented renders a sprite that is internally segmented as frames
|
||||
@ -69,13 +66,9 @@ func (s *Sprite) RenderSegmented(target d2interface.Surface, segmentsX, segments
|
||||
}
|
||||
|
||||
target.PushTranslation(s.x+currentX, s.y+currentY)
|
||||
err := s.animation.Render(target)
|
||||
s.animation.Render(target)
|
||||
target.Pop()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frameWidth, frameHeight := s.GetCurrentFrameSize()
|
||||
maxFrameHeight = d2math.MaxInt(maxFrameHeight, frameHeight)
|
||||
currentX += frameWidth
|
||||
|
@ -59,10 +59,7 @@ func (v *TextBox) Render(target d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := v.bgSprite.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.bgSprite.Render(target)
|
||||
v.textLabel.Render(target)
|
||||
|
||||
if (time.Now().UnixNano()/1e6)&(1<<8) > 0 {
|
||||
|
@ -360,9 +360,9 @@ func (v *CharacterSelect) onExitButtonClicked() {
|
||||
}
|
||||
|
||||
// Render renders the Character Select screen
|
||||
func (v *CharacterSelect) Render(screen d2interface.Surface) error {
|
||||
func (v *CharacterSelect) Render(screen d2interface.Surface) {
|
||||
if err := v.background.RenderSegmented(screen, 4, 3, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
v.d2HeroTitle.Render(screen)
|
||||
@ -370,7 +370,7 @@ func (v *CharacterSelect) Render(screen d2interface.Surface) error {
|
||||
|
||||
if v.selectedCharacter > -1 && actualSelectionIndex >= 0 && actualSelectionIndex < 8 {
|
||||
if err := v.selectionBox.RenderSegmented(screen, 2, 1, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,13 +395,11 @@ func (v *CharacterSelect) Render(screen d2interface.Surface) error {
|
||||
screen.DrawRect(screenWidth, screenHeight, rgbaColor(blackHalfOpacity))
|
||||
|
||||
if err := v.okCancelBox.RenderSegmented(screen, 2, 1, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
v.deleteCharConfirmLabel.Render(screen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *CharacterSelect) moveSelectionBox() {
|
||||
|
@ -128,10 +128,10 @@ func (v *Credits) OnLoad(loading d2screen.LoadingState) {
|
||||
}
|
||||
|
||||
// Render renders the credits screen
|
||||
func (v *Credits) Render(screen d2interface.Surface) error {
|
||||
func (v *Credits) Render(screen d2interface.Surface) {
|
||||
err := v.creditsBackground.RenderSegmented(screen, 4, 3, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
for _, label := range v.labels {
|
||||
@ -141,8 +141,6 @@ func (v *Credits) Render(screen d2interface.Surface) error {
|
||||
|
||||
label.Label.Render(screen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Advance runs the update logic on the credits screen
|
||||
|
@ -196,17 +196,14 @@ func (v *Game) OnUnload() error {
|
||||
}
|
||||
|
||||
// Render renders the Gameplay screen
|
||||
func (v *Game) Render(screen d2interface.Surface) error {
|
||||
func (v *Game) Render(screen d2interface.Surface) {
|
||||
if v.gameClient.RegenMap {
|
||||
v.gameClient.RegenMap = false
|
||||
v.mapRenderer.RegenerateTileCache()
|
||||
v.gameClient.MapEngine.IsLoading = false
|
||||
}
|
||||
|
||||
if err := screen.Clear(color.Black); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
screen.Clear(color.Black)
|
||||
v.mapRenderer.Render(screen)
|
||||
|
||||
if v.gameControls != nil {
|
||||
@ -215,11 +212,9 @@ func (v *Game) Render(screen d2interface.Surface) error {
|
||||
}
|
||||
|
||||
if err := v.gameControls.Render(screen); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Advance runs the update logic on the Gameplay screen
|
||||
|
@ -94,9 +94,7 @@ func (g *GuiTestMain) OnLoad(loading d2screen.LoadingState) {
|
||||
}
|
||||
|
||||
// Render does nothing for the GuiTestMain screen
|
||||
func (g *GuiTestMain) Render(_ d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
func (g *GuiTestMain) Render(_ d2interface.Surface) { /* NOOP */ }
|
||||
|
||||
// Advance does nothing for the GuiTestMain screen
|
||||
func (g *GuiTestMain) Advance(_ float64) error {
|
||||
|
@ -406,69 +406,44 @@ func (v *MainMenu) onCreditsButtonClicked() {
|
||||
}
|
||||
|
||||
// Render renders the main menu
|
||||
func (v *MainMenu) Render(screen d2interface.Surface) error {
|
||||
if err := v.renderBackgrounds(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.renderLogos(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.renderLabels(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
func (v *MainMenu) Render(screen d2interface.Surface) {
|
||||
v.renderBackgrounds(screen)
|
||||
v.renderLogos(screen)
|
||||
v.renderLabels(screen)
|
||||
}
|
||||
|
||||
func (v *MainMenu) renderBackgrounds(screen d2interface.Surface) error {
|
||||
func (v *MainMenu) renderBackgrounds(screen d2interface.Surface) {
|
||||
switch v.screenMode {
|
||||
case ScreenModeTrademark:
|
||||
if err := v.trademarkBackground.RenderSegmented(screen, 4, 3, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
case ScreenModeServerIP:
|
||||
if err := v.serverIPBackground.RenderSegmented(screen, 2, 1, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
case ScreenModeTCPIP:
|
||||
if err := v.tcpIPBackground.RenderSegmented(screen, 4, 3, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
default:
|
||||
if err := v.background.RenderSegmented(screen, 4, 3, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *MainMenu) renderLogos(screen d2interface.Surface) error {
|
||||
func (v *MainMenu) renderLogos(screen d2interface.Surface) {
|
||||
switch v.screenMode {
|
||||
case ScreenModeTrademark, ScreenModeMainMenu, ScreenModeMultiplayer:
|
||||
if err := v.diabloLogoLeftBack.Render(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.diabloLogoRightBack.Render(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.diabloLogoLeft.Render(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.diabloLogoRight.Render(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
v.diabloLogoLeftBack.Render(screen)
|
||||
v.diabloLogoRightBack.Render(screen)
|
||||
v.diabloLogoLeft.Render(screen)
|
||||
v.diabloLogoRight.Render(screen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *MainMenu) renderLabels(screen d2interface.Surface) error {
|
||||
func (v *MainMenu) renderLabels(screen d2interface.Surface) {
|
||||
switch v.screenMode {
|
||||
case ScreenModeServerIP:
|
||||
v.tcpIPOptionsLabel.Render(screen)
|
||||
@ -483,8 +458,6 @@ func (v *MainMenu) renderLabels(screen d2interface.Surface) error {
|
||||
v.versionLabel.Render(screen)
|
||||
v.commitLabel.Render(screen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Advance runs the update logic on the main menu
|
||||
|
@ -239,7 +239,7 @@ const (
|
||||
)
|
||||
|
||||
// Render renders the Map Engine Test screen
|
||||
func (met *MapEngineTest) Render(screen d2interface.Surface) error {
|
||||
func (met *MapEngineTest) Render(screen d2interface.Surface) {
|
||||
met.mapRenderer.Render(screen)
|
||||
|
||||
screen.PushTranslation(0, lineNormalOffsetY)
|
||||
@ -265,14 +265,10 @@ func (met *MapEngineTest) Render(screen d2interface.Surface) error {
|
||||
screen.PushTranslation(0, lineNormalOffsetY)
|
||||
defer screen.Pop()
|
||||
|
||||
if err := met.renderTileInfo(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
met.renderTileInfo(screen)
|
||||
}
|
||||
|
||||
func (met *MapEngineTest) renderTileInfo(screen d2interface.Surface) error {
|
||||
func (met *MapEngineTest) renderTileInfo(screen d2interface.Surface) {
|
||||
if met.selectedTile == nil {
|
||||
screen.PushTranslation(lineNormalIndentX, lineNormalOffsetY)
|
||||
defer screen.Pop()
|
||||
@ -371,8 +367,6 @@ func (met *MapEngineTest) renderTileInfo(screen d2interface.Surface) error {
|
||||
}
|
||||
screen.PopN(tpop)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnMouseMove is the mouse move handler
|
||||
|
@ -511,9 +511,9 @@ func (v *SelectHeroClass) onOkButtonClicked() {
|
||||
}
|
||||
|
||||
// Render renders the Select Hero Class screen
|
||||
func (v *SelectHeroClass) Render(screen d2interface.Surface) error {
|
||||
func (v *SelectHeroClass) Render(screen d2interface.Surface) {
|
||||
if err := v.bgImage.RenderSegmented(screen, 4, 3, 0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
v.headingLabel.Render(screen)
|
||||
@ -537,17 +537,13 @@ func (v *SelectHeroClass) Render(screen d2interface.Surface) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := v.campfire.Render(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
v.campfire.Render(screen)
|
||||
|
||||
if v.heroNameTextbox.GetVisible() {
|
||||
v.heroNameLabel.Render(screen)
|
||||
v.expansionCharLabel.Render(screen)
|
||||
v.hardcoreCharLabel.Render(screen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Advance runs the update logic on the Select Hero Class screen
|
||||
@ -744,10 +740,7 @@ func setSpriteToFirstFrame(sprite *d2ui.Sprite) {
|
||||
|
||||
func drawSprite(sprite *d2ui.Sprite, target d2interface.Surface) {
|
||||
if sprite != nil {
|
||||
if err := sprite.Render(target); err != nil {
|
||||
x, y := sprite.GetPosition()
|
||||
fmt.Printf("could not render the sprite to the position(x: %d, y: %d)\n", x, y)
|
||||
}
|
||||
sprite.Render(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -964,16 +964,12 @@ func (g *GameControls) renderForSelectableEntitiesHovered(target d2interface.Sur
|
||||
}
|
||||
|
||||
func (g *GameControls) renderPanels(target d2interface.Surface) error {
|
||||
if err := g.heroStatsPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.heroStatsPanel.Render(target)
|
||||
g.inventory.Render(target)
|
||||
|
||||
if err := g.inventory.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := g.skilltree.Render(target); err != nil {
|
||||
return err
|
||||
err := g.skilltree.Render(target)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -1104,10 +1100,7 @@ func (g *GameControls) renderPanel(x, y int, target d2interface.Surface) error {
|
||||
}
|
||||
|
||||
g.mainPanel.SetPosition(x, y)
|
||||
|
||||
if err := g.mainPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.mainPanel.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1123,9 +1116,7 @@ func (g *GameControls) renderHealthGlobe(x, y int, target d2interface.Surface) e
|
||||
g.hpManaStatusSprite.SetPosition(x+healthStatusOffsetX, y+healthStatusOffsetY)
|
||||
|
||||
healthMaskRect := image.Rect(0, globeHeight-hpBarHeight, globeWidth, globeHeight)
|
||||
if err := g.hpManaStatusSprite.RenderSection(target, healthMaskRect); err != nil {
|
||||
return err
|
||||
}
|
||||
g.hpManaStatusSprite.RenderSection(target, healthMaskRect)
|
||||
|
||||
// Left globe
|
||||
if err := g.globeSprite.SetCurrentFrame(frameHealthStatus); err != nil {
|
||||
@ -1133,10 +1124,7 @@ func (g *GameControls) renderHealthGlobe(x, y int, target d2interface.Surface) e
|
||||
}
|
||||
|
||||
g.globeSprite.SetPosition(x+globeSpriteOffsetX, y+globeSpriteOffsetY)
|
||||
|
||||
if err := g.globeSprite.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.globeSprite.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1153,10 +1141,7 @@ func (g *GameControls) renderLeftSkill(x, y int, target d2interface.Surface) err
|
||||
}
|
||||
|
||||
g.leftSkillResource.SkillIcon.SetPosition(x, y)
|
||||
|
||||
if err := g.leftSkillResource.SkillIcon.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.leftSkillResource.SkillIcon.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1167,10 +1152,7 @@ func (g *GameControls) renderNewStatsButton(x, y int, target d2interface.Surface
|
||||
}
|
||||
|
||||
g.mainPanel.SetPosition(x, y)
|
||||
|
||||
if err := g.mainPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.mainPanel.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1181,10 +1163,7 @@ func (g *GameControls) renderStamina(x, y int, target d2interface.Surface) error
|
||||
}
|
||||
|
||||
g.mainPanel.SetPosition(x, y)
|
||||
|
||||
if err := g.mainPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.mainPanel.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1235,14 +1214,8 @@ func (g *GameControls) renderMiniPanel(target d2interface.Surface) error {
|
||||
buttonX, buttonY := (width>>1)+miniPanelButtonOffsetX, height+miniPanelButtonOffsetY
|
||||
|
||||
g.menuButton.SetPosition(buttonX, buttonY)
|
||||
|
||||
if err := g.menuButton.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := g.miniPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.menuButton.Render(target)
|
||||
g.miniPanel.Render(target)
|
||||
|
||||
miniPanelButtons := map[actionableType]string{
|
||||
miniPanelCharacter: "minipanelchar",
|
||||
@ -1292,10 +1265,7 @@ func (g *GameControls) renderPotions(x, _ int, target d2interface.Surface) error
|
||||
}
|
||||
|
||||
g.mainPanel.SetPosition(x, height)
|
||||
|
||||
if err := g.mainPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.mainPanel.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1308,10 +1278,7 @@ func (g *GameControls) renderNewSkillsButton(x, _ int, target d2interface.Surfac
|
||||
}
|
||||
|
||||
g.mainPanel.SetPosition(x, height)
|
||||
|
||||
if err := g.mainPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.mainPanel.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1330,10 +1297,7 @@ func (g *GameControls) renderRightSkill(x, _ int, target d2interface.Surface) er
|
||||
}
|
||||
|
||||
g.rightSkillResource.SkillIcon.SetPosition(x, height)
|
||||
|
||||
if err := g.rightSkillResource.SkillIcon.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.rightSkillResource.SkillIcon.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1347,9 +1311,7 @@ func (g *GameControls) renderManaGlobe(x, _ int, target d2interface.Surface) err
|
||||
|
||||
g.mainPanel.SetPosition(x, height)
|
||||
|
||||
if err := g.mainPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.mainPanel.Render(target)
|
||||
|
||||
// Mana status bar
|
||||
manaPercent := float64(g.hero.Stats.Mana) / float64(g.hero.Stats.MaxMana)
|
||||
@ -1362,9 +1324,7 @@ func (g *GameControls) renderManaGlobe(x, _ int, target d2interface.Surface) err
|
||||
g.hpManaStatusSprite.SetPosition(x+manaStatusOffsetX, height+manaStatusOffsetY)
|
||||
|
||||
manaMaskRect := image.Rect(0, globeHeight-manaBarHeight, globeWidth, globeHeight)
|
||||
if err := g.hpManaStatusSprite.RenderSection(target, manaMaskRect); err != nil {
|
||||
return err
|
||||
}
|
||||
g.hpManaStatusSprite.RenderSection(target, manaMaskRect)
|
||||
|
||||
// Right globe
|
||||
if err := g.globeSprite.SetCurrentFrame(frameRightGlobe); err != nil {
|
||||
@ -1373,13 +1333,8 @@ func (g *GameControls) renderManaGlobe(x, _ int, target d2interface.Surface) err
|
||||
|
||||
g.globeSprite.SetPosition(x+rightGlobeOffsetX, height+rightGlobeOffsetY)
|
||||
|
||||
if err := g.globeSprite.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := g.globeSprite.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.globeSprite.Render(target)
|
||||
g.globeSprite.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -602,10 +602,7 @@ func (h *Overlay) Render(target d2interface.Surface) error {
|
||||
}
|
||||
|
||||
for _, f := range h.frames {
|
||||
err := f.Render(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Render(target)
|
||||
}
|
||||
|
||||
for _, t := range h.text {
|
||||
|
@ -174,34 +174,27 @@ func (s *HeroStatsPanel) SetOnCloseCb(cb func()) {
|
||||
}
|
||||
|
||||
// Render renders the hero status panel
|
||||
func (s *HeroStatsPanel) Render(target d2interface.Surface) error {
|
||||
func (s *HeroStatsPanel) Render(target d2interface.Surface) {
|
||||
if !s.isOpen {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
if s.staticMenuImageCache == nil {
|
||||
frameWidth, frameHeight := s.frame.GetFrameBounds()
|
||||
framesCount := s.frame.GetFrameCount()
|
||||
surface, err := s.renderer.NewSurface(frameWidth*framesCount, frameHeight*framesCount, d2enum.FilterNearest)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
surface := s.renderer.NewSurface(frameWidth*framesCount, frameHeight*framesCount)
|
||||
|
||||
s.staticMenuImageCache = &surface
|
||||
|
||||
if err := s.renderStaticMenu(*s.staticMenuImageCache); err != nil {
|
||||
return err
|
||||
err := s.renderStaticMenu(*s.staticMenuImageCache)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := target.Render(*s.staticMenuImageCache); err != nil {
|
||||
return err
|
||||
}
|
||||
target.Render(*s.staticMenuImageCache)
|
||||
|
||||
s.renderStatValues(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
@ -249,9 +242,7 @@ func (s *HeroStatsPanel) renderStaticPanelFrames(target d2interface.Surface) err
|
||||
s.panel.SetPosition(currentX-w, currentY+h)
|
||||
}
|
||||
|
||||
if err := s.panel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
s.panel.Render(target)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -2,6 +2,7 @@ package d2player
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
||||
|
||||
@ -158,20 +159,18 @@ func (g *Inventory) Load() {
|
||||
}
|
||||
|
||||
// Render draws the inventory onto the given surface
|
||||
func (g *Inventory) Render(target d2interface.Surface) error {
|
||||
func (g *Inventory) Render(target d2interface.Surface) {
|
||||
if !g.isOpen {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
if err := g.renderFrame(target); err != nil {
|
||||
return err
|
||||
err := g.renderFrame(target)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
g.grid.Render(target)
|
||||
|
||||
g.renderItemHover(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Inventory) renderFrame(target d2interface.Surface) error {
|
||||
@ -197,10 +196,7 @@ func (g *Inventory) renderFrame(target d2interface.Surface) error {
|
||||
w, h := g.panel.GetCurrentFrameSize()
|
||||
|
||||
g.panel.SetPosition(x, y+h)
|
||||
|
||||
if err := g.panel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
g.panel.Render(target)
|
||||
|
||||
switch frame {
|
||||
case frameInventoryTopLeft:
|
||||
|
@ -234,11 +234,7 @@ func (g *ItemGrid) renderItem(item InventoryItem, target d2interface.Surface, x,
|
||||
if itemSprite != nil {
|
||||
itemSprite.SetPosition(x, y)
|
||||
itemSprite.GetCurrentFrameSize()
|
||||
|
||||
err := itemSprite.Render(target)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
itemSprite.Render(target)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,13 +89,13 @@ func (m *miniPanel) Close() {
|
||||
m.isOpen = false
|
||||
}
|
||||
|
||||
func (m *miniPanel) Render(target d2interface.Surface) error {
|
||||
func (m *miniPanel) Render(target d2interface.Surface) {
|
||||
if !m.isOpen {
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
if err := m.container.SetCurrentFrame(0); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
width, height := target.GetSize()
|
||||
@ -104,9 +104,7 @@ func (m *miniPanel) Render(target d2interface.Surface) error {
|
||||
|
||||
m.container.SetPosition(x, y)
|
||||
|
||||
if err := m.container.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
m.container.Render(target)
|
||||
|
||||
buttonWidth, _ := m.button.GetCurrentFrameSize()
|
||||
buttonWidth++
|
||||
@ -117,22 +115,17 @@ func (m *miniPanel) Render(target d2interface.Surface) error {
|
||||
}
|
||||
|
||||
if err := m.button.SetCurrentFrame(j); err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
offsetX := buttonOffsetX + (buttonWidth * i)
|
||||
x, y := halfW+offsetX, height+buttonOffsetY
|
||||
|
||||
m.button.SetPosition(x, y)
|
||||
|
||||
if err := m.button.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
m.button.Render(target)
|
||||
|
||||
j += 2
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *miniPanel) isInRect(x, y int) bool {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2tbl"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
@ -124,11 +123,7 @@ func (s *SkillPanel) Render(target d2interface.Surface) error {
|
||||
rowOffsetY := skillPanelOffsetY - (renderedRows * skillIconHeight)
|
||||
|
||||
target.PushTranslation(startX, rowOffsetY)
|
||||
|
||||
if err := target.Render(skillListRow.cachedImage); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
target.Render(skillListRow.cachedImage)
|
||||
target.Pop()
|
||||
|
||||
renderedRows++
|
||||
@ -222,11 +217,7 @@ func (s *SkillPanel) generateSkillRowImageCache() error {
|
||||
}
|
||||
|
||||
func (s *SkillPanel) createSkillListImage(skillsListRow *SkillListRow) (d2interface.Surface, error) {
|
||||
surface, err := s.renderer.NewSurface(len(skillsListRow.Skills)*skillIconWidth, skillIconHeight, d2enum.FilterNearest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
surface := s.renderer.NewSurface(len(skillsListRow.Skills)*skillIconWidth, skillIconHeight)
|
||||
|
||||
lastSkillResourcePath := d2resource.GenericSkills
|
||||
skillSprite, _ := s.ui.NewSprite(s.getSkillResourceByClass(""), d2resource.PaletteSky)
|
||||
@ -250,11 +241,7 @@ func (s *SkillPanel) createSkillListImage(skillsListRow *SkillListRow) (d2interf
|
||||
}
|
||||
|
||||
surface.PushTranslation(idx*skillIconWidth, 50)
|
||||
|
||||
if err := skillSprite.Render(surface); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
skillSprite.Render(surface)
|
||||
surface.Pop()
|
||||
}
|
||||
|
||||
|
@ -376,9 +376,7 @@ func (s *skillTree) renderPanelSegment(
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.resources.skillPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
s.resources.skillPanel.Render(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -520,10 +518,7 @@ func (s *skillTree) renderSkillIcons(target d2interface.Surface, tab int) error
|
||||
y := skillIconYOff + skill.SkillRow*skillIconDistY
|
||||
|
||||
skillIcon.SetPosition(x, y)
|
||||
|
||||
if err := skillIcon.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
skillIcon.Render(target)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
3
go.mod
3
go.mod
@ -10,10 +10,11 @@ require (
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/gravestench/akara v0.0.0-20201014060234-a64208a7fd3c
|
||||
github.com/hajimehoshi/ebiten v1.11.4
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.0
|
||||
github.com/pkg/profile v1.5.0
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
)
|
||||
|
47
go.sum
47
go.sum
@ -7,88 +7,95 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2c
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2 h1:Ac1OEHHkbAZ6EUnJahF0GKcU0FjPc/V8F1DvjhKngFE=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-restruct/restruct v0.0.0-20191227155143-5734170a48a1 h1:LoN2wx/aN8JPGebG+2DaUyk4M+xRcqJXfuIbs8AWHdE=
|
||||
github.com/go-restruct/restruct v0.0.0-20191227155143-5734170a48a1/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
|
||||
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
|
||||
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
|
||||
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gravestench/akara v0.0.0-20201014060234-a64208a7fd3c h1:WopE590cKxkcKXcOee4gPXHqtzwbarLClCaWNCdLqgI=
|
||||
github.com/gravestench/akara v0.0.0-20201014060234-a64208a7fd3c/go.mod h1:fTeda1SogMg5Lkd4lXMEd/Pk/a5/gQuLGaAI2rn1PBQ=
|
||||
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU=
|
||||
github.com/hajimehoshi/bitmapfont/v2 v2.1.0/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
|
||||
github.com/hajimehoshi/ebiten v1.11.4 h1:ngYF0NxKjFBsY/Bol6V0X/b0hoCCTi9nJRg7Dv8+ePc=
|
||||
github.com/hajimehoshi/ebiten v1.11.4/go.mod h1:aDEhx0K9gSpXw3Cxf2hCXDxPSoF8vgjNqKxrZa/B4Dg=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.0 h1:G8mhkKFtnDPPZ/ChaGWx4Bm0NusYEcafGCJ8QLxEaYs=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.0/go.mod h1:hpZZQ/kk8DZqft7QsQ5hZLRQXHSZPdKnaa0tcJ3CZFE=
|
||||
github.com/hajimehoshi/file2byteslice v0.0.0-20200812174855-0e5e8a80490e/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
|
||||
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
||||
github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
|
||||
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
|
||||
github.com/hajimehoshi/oto v0.5.4 h1:Dn+WcYeF310xqStKm0tnvoruYUV5Sce8+sfUaIvWGkE=
|
||||
github.com/hajimehoshi/oto v0.5.4/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
github.com/hajimehoshi/oto v0.6.6/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
|
||||
github.com/jakecoffman/cp v1.0.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
|
||||
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM=
|
||||
github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk=
|
||||
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.5.0 h1:042Buzk+NhDI+DeSAA62RwJL8VAuZUMQZUjCsRz1Mug=
|
||||
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA=
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0 h1:nZASbxDuz7CO3227BWCCf0MC6ynyvKh6eMDoLcNXAk0=
|
||||
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201009162240-fcf82128ed91/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
Loading…
Reference in New Issue
Block a user