mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-02 22:57:04 -05:00
Merge pull request #1078 from gucio321/anim-data-encoder
animation data engine + encoder
This commit is contained in:
commit
fa4276156c
@ -5,7 +5,7 @@ version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/golang:1.15.8
|
||||
- image: circleci/golang:1.15.6
|
||||
working_directory: /go/src/github.com/{{ORG_NAME}}/{{REPO_NAME}}
|
||||
steps:
|
||||
- checkout
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2loader/asset/types"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2animdata"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
@ -150,12 +150,12 @@ func (a *App) initAnimationData(path string) error {
|
||||
|
||||
a.Debugf(fmtLoadAnimData, path)
|
||||
|
||||
animData, err := d2data.LoadAnimationData(animDataBytes)
|
||||
animData, err := d2animdata.Load(animDataBytes)
|
||||
if err != nil {
|
||||
a.Error(err.Error())
|
||||
}
|
||||
|
||||
a.Infof("Loaded %d animation data records", len(animData))
|
||||
a.Infof("Loaded %d animation data records", animData.GetRecordsCount())
|
||||
|
||||
a.asset.Records.Animation.Data = animData
|
||||
|
||||
|
@ -1,83 +0,0 @@
|
||||
package d2data
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
||||
)
|
||||
|
||||
const (
|
||||
numCofNameBytes = 8
|
||||
numFlagBytes = 144
|
||||
)
|
||||
|
||||
// AnimationDataRecord represents a single entry in the animation data dictionary file
|
||||
type AnimationDataRecord struct {
|
||||
// COFName is the name of the COF file used for this animation
|
||||
COFName string
|
||||
// FramesPerDirection specifies how many frames are in each direction
|
||||
FramesPerDirection int
|
||||
// AnimationSpeed represents a value of X where the rate is a ration of (x/255) at 25FPS
|
||||
AnimationSpeed int
|
||||
// Flags are used in keyframe triggers
|
||||
Flags []byte
|
||||
}
|
||||
|
||||
// AnimationData represents all of the animation data records, mapped by the COF index
|
||||
type AnimationData map[string][]*AnimationDataRecord
|
||||
|
||||
// LoadAnimationData loads the animation data table into the global AnimationData dictionary
|
||||
func LoadAnimationData(rawData []byte) (AnimationData, error) {
|
||||
animdata := make(AnimationData)
|
||||
streamReader := d2datautils.CreateStreamReader(rawData)
|
||||
|
||||
for !streamReader.EOF() {
|
||||
var dataCount int
|
||||
|
||||
b, err := streamReader.ReadInt32()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dataCount = int(b)
|
||||
|
||||
for i := 0; i < dataCount; i++ {
|
||||
cofNameBytes, err := streamReader.ReadBytes(numCofNameBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fpd, err := streamReader.ReadInt32()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
animSpeed, err := streamReader.ReadInt32()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := &AnimationDataRecord{
|
||||
COFName: strings.ReplaceAll(string(cofNameBytes), string(byte(0)), ""),
|
||||
FramesPerDirection: int(fpd),
|
||||
AnimationSpeed: int(animSpeed),
|
||||
}
|
||||
|
||||
flagBytes, err := streamReader.ReadBytes(numFlagBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data.Flags = flagBytes
|
||||
cofIndex := strings.ToLower(data.COFName)
|
||||
|
||||
if _, found := animdata[cofIndex]; !found {
|
||||
animdata[cofIndex] = make([]*AnimationDataRecord, 0)
|
||||
}
|
||||
|
||||
animdata[cofIndex] = append(animdata[cofIndex], data)
|
||||
}
|
||||
}
|
||||
|
||||
return animdata, nil
|
||||
}
|
@ -56,6 +56,11 @@ func (ad *AnimationData) GetRecords(name string) []*AnimationDataRecord {
|
||||
return ad.entries[name]
|
||||
}
|
||||
|
||||
// GetRecordsCount returns number of animation data records
|
||||
func (ad *AnimationData) GetRecordsCount() int {
|
||||
return len(ad.entries)
|
||||
}
|
||||
|
||||
// Load loads the data into an AnimationData struct
|
||||
//nolint:gocognit,funlen // can't reduce
|
||||
func Load(data []byte) (*AnimationData, error) {
|
||||
@ -143,8 +148,92 @@ func Load(data []byte) (*AnimationData, error) {
|
||||
}
|
||||
|
||||
if reader.Position() != uint64(len(data)) {
|
||||
return nil, errors.New("unable to parse animation data")
|
||||
return nil, fmt.Errorf("unable to parse animation data: %d != %d", reader.Position(), len(data))
|
||||
}
|
||||
|
||||
return animdata, nil
|
||||
}
|
||||
|
||||
// Marshal encodes animation data back into byte slice
|
||||
// basing on AnimationData.records
|
||||
func (ad *AnimationData) Marshal() []byte {
|
||||
sw := d2datautils.CreateStreamWriter()
|
||||
|
||||
// keys - all entries in animationData
|
||||
keys := make([]string, len(ad.entries))
|
||||
|
||||
// we must manually add index
|
||||
idx := 0
|
||||
|
||||
for i := range ad.entries {
|
||||
keys[idx] = i
|
||||
idx++
|
||||
}
|
||||
|
||||
// name terminates current name
|
||||
name := 0
|
||||
|
||||
// recordIdx determinates current record index
|
||||
recordIdx := 0
|
||||
|
||||
// numberOfEntries is a number of entries in all map indexes
|
||||
var numberOfEntries int = 0
|
||||
|
||||
for i := 0; i < len(keys); i++ {
|
||||
numberOfEntries += len(ad.entries[keys[i]])
|
||||
}
|
||||
|
||||
for idx := 0; idx < numBlocks; idx++ {
|
||||
// number of records (max is maxRecordsPerObject)
|
||||
l := 0
|
||||
|
||||
switch {
|
||||
// first condition: end up with all this and push 0 to dhe end
|
||||
case numberOfEntries == 0:
|
||||
sw.PushUint32(0)
|
||||
continue
|
||||
case numberOfEntries < maxRecordsPerBlock:
|
||||
// second condition - if number of entries left is smaller than
|
||||
// maxRecordsPerBlock, push...
|
||||
l = numberOfEntries
|
||||
sw.PushUint32(uint32(l))
|
||||
default:
|
||||
// else use maxRecordsPerBlock
|
||||
l = maxRecordsPerBlock
|
||||
sw.PushUint32(maxRecordsPerBlock)
|
||||
}
|
||||
|
||||
for currentRecordIdx := 0; currentRecordIdx < l; currentRecordIdx++ {
|
||||
numberOfEntries--
|
||||
|
||||
if recordIdx == len(ad.entries[keys[name]]) {
|
||||
recordIdx = 0
|
||||
name++
|
||||
}
|
||||
|
||||
animationRecord := ad.entries[keys[name]][recordIdx]
|
||||
recordIdx++
|
||||
|
||||
name := animationRecord.name
|
||||
missingZeroBytes := byteCountName - len(name)
|
||||
sw.PushBytes([]byte(name)...)
|
||||
|
||||
for i := 0; i < missingZeroBytes; i++ {
|
||||
sw.PushBytes(0)
|
||||
}
|
||||
|
||||
sw.PushUint32(animationRecord.framesPerDirection)
|
||||
sw.PushUint16(animationRecord.speed)
|
||||
|
||||
for i := 0; i < byteCountSpeedPadding; i++ {
|
||||
sw.PushBytes(0)
|
||||
}
|
||||
|
||||
for event := 0; event < numEvents; event++ {
|
||||
sw.PushBytes(byte(animationRecord.events[event]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sw.GetBytes()
|
||||
}
|
||||
|
@ -154,3 +154,58 @@ func TestAnimationDataRecord_FPS(t *testing.T) {
|
||||
t.Error("incorrect fps")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnimationDataRecord_Marshal(t *testing.T) {
|
||||
file, fileErr := os.Open("testdata/AnimData.d2")
|
||||
if fileErr != nil {
|
||||
t.Error("cannot open test data file")
|
||||
return
|
||||
}
|
||||
|
||||
data := make([]byte, 0)
|
||||
buf := make([]byte, 16)
|
||||
|
||||
for {
|
||||
numRead, err := file.Read(buf)
|
||||
|
||||
data = append(data, buf[:numRead]...)
|
||||
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ad, err := Load(data)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
newData := ad.Marshal()
|
||||
|
||||
newAd, err := Load(newData)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
keys1 := make([]string, 0)
|
||||
for i := range ad.entries {
|
||||
keys1 = append(keys1, i)
|
||||
}
|
||||
|
||||
keys2 := make([]string, 0)
|
||||
for i := range newAd.entries {
|
||||
keys2 = append(keys2, i)
|
||||
}
|
||||
|
||||
if len(keys1) != len(keys2) {
|
||||
t.Fatalf("unexpected length of keys in first and second dict: %d, %d", len(keys1), len(keys2))
|
||||
}
|
||||
|
||||
for key := range newAd.entries {
|
||||
for n, i := range newAd.entries[key] {
|
||||
if i.speed != ad.entries[key][n].speed {
|
||||
t.Fatal("unexpected record set")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,16 @@ type AnimationDataRecord struct {
|
||||
events map[int]AnimationEvent
|
||||
}
|
||||
|
||||
// FramesPerDirection returns frames per direction value
|
||||
func (r *AnimationDataRecord) FramesPerDirection() int {
|
||||
return int(r.framesPerDirection)
|
||||
}
|
||||
|
||||
// Speed returns animation's speed
|
||||
func (r *AnimationDataRecord) Speed() int {
|
||||
return int(r.speed)
|
||||
}
|
||||
|
||||
// FPS returns the frames per second for this animation record
|
||||
func (r *AnimationDataRecord) FPS() float64 {
|
||||
speedf := float64(r.speed)
|
||||
|
@ -265,9 +265,9 @@ func (c *Composite) createMode(animationMode animationMode, weaponClass string)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
animationKey := strings.ToLower(c.token + animationMode.String() + weaponClass)
|
||||
animationKey := strings.ToUpper(c.token + animationMode.String() + weaponClass)
|
||||
|
||||
animationData := c.Records.Animation.Data[animationKey]
|
||||
animationData := c.Records.Animation.Data.GetRecords(animationKey)
|
||||
if len(animationData) == 0 {
|
||||
return nil, errors.New("could not find Animation data")
|
||||
}
|
||||
@ -277,8 +277,8 @@ func (c *Composite) createMode(animationMode animationMode, weaponClass string)
|
||||
animationMode: animationMode,
|
||||
weaponClass: weaponClass,
|
||||
layers: make([]d2interface.Animation, d2enum.CompositeTypeMax),
|
||||
frameCount: animationData[0].FramesPerDirection,
|
||||
animationSpeed: 1.0 / (float64(animationData[0].AnimationSpeed) * speedUnit), //nolint:gomnd // taking inverse
|
||||
frameCount: animationData[0].FramesPerDirection(),
|
||||
animationSpeed: 1.0 / (float64(animationData[0].Speed()) * speedUnit), //nolint:gomnd // taking inverse
|
||||
}
|
||||
|
||||
for _, cofLayer := range cof.CofLayers {
|
||||
|
@ -108,8 +108,8 @@ func (f *MapEntityFactory) NewPlayer(id, name string, x, y, direction int, heroT
|
||||
result.mapEntity.uuid = id
|
||||
result.SetSpeed(baseWalkSpeed)
|
||||
result.mapEntity.directioner = result.rotate
|
||||
err = composite.SetMode(d2enum.PlayerAnimationModeTownNeutral, equipment.RightHand.GetWeaponClass())
|
||||
|
||||
err = composite.SetMode(d2enum.PlayerAnimationModeTownNeutral, equipment.RightHand.GetWeaponClass())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -5,9 +5,8 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2animdata"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
)
|
||||
@ -39,7 +38,7 @@ type RecordManager struct {
|
||||
*d2util.Logger
|
||||
boundLoaders map[string][]recordLoader // there can be more than one loader bound for a file
|
||||
Animation struct {
|
||||
Data d2data.AnimationData
|
||||
Data *d2animdata.AnimationData
|
||||
Token struct {
|
||||
Player PlayerTypes
|
||||
Composite CompositeTypes
|
||||
|
17
go.mod
17
go.mod
@ -4,19 +4,18 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20201108214237-06ea97f0c265 // indirect
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
|
||||
github.com/go-restruct/restruct v1.2.0-alpha
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/gravestench/akara v0.0.0-20210116041952-513d453f9ca8
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.6
|
||||
github.com/hajimehoshi/oto v0.7.1 // indirect
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/gravestench/akara v0.0.0-20201014060234-a64208a7fd3c
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.2
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.5.0
|
||||
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/exp v0.0.0-20210220032938-85be41e4509f // indirect
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb
|
||||
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08 // indirect
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect
|
||||
golang.org/x/exp v0.0.0-20201008143054-e3b2a7f2fdc7 // indirect
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5
|
||||
golang.org/x/sys v0.0.0-20201028215240-c5abc1b1d397 // indirect
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
)
|
||||
|
48
go.sum
48
go.sum
@ -1,39 +1,35 @@
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0 h1:tDnuU0igiBiQFjsvq1Bi7DpoUjqI76VVvW045vpeFeM=
|
||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0/go.mod h1:h/5OEGj4G+fpYxluLjSMZbFY011ZxAntO98nCl8mrCs=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
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/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-gl/glfw/v3.3/glfw v0.0.0-20201108214237-06ea97f0c265 h1:BcbKYUZo/TKPsiSh7LymK3p+TNAJJW3OfGO/21sBbiA=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20201108214237-06ea97f0c265/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc=
|
||||
github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
|
||||
github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
|
||||
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gravestench/akara v0.0.0-20210116041952-513d453f9ca8 h1:3MOT9gUiXETmJJ3UsHgVa4+okRSdUVW+eSvPD4C+ZnQ=
|
||||
github.com/gravestench/akara v0.0.0-20210116041952-513d453f9ca8/go.mod h1:uxAqdO3YanpyVIUcFAJyMfpTHbYveWgm0MbJW1JBtMM=
|
||||
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/v2 v2.1.0/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.6 h1:sHNymgI+q80xasP69oFyrpup6r2qCNsKxqwsGEh6PWE=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.6/go.mod h1:uS3OjMW3f2DRDMtWoIF7yMMmrMkv+fZ6pXcwR1pfA0Y=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.2 h1:t8HXO9hJfKlS9tNhht8Ov6xecag0gRl7AkfKgC9hcLE=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.0.2/go.mod h1:AbHP/SS226aFTex/izULVwW0D2AuGyqC4AVwilmRjOg=
|
||||
github.com/hajimehoshi/file2byteslice v0.0.0-20200812174855-0e5e8a80490e/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
|
||||
github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
|
||||
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
github.com/hajimehoshi/oto v0.6.8 h1:yRb3EJQ4lAkBgZYheqmdH6Lr77RV9nSWFsK/jwWdTNY=
|
||||
github.com/hajimehoshi/oto v0.6.8/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
github.com/hajimehoshi/oto v0.7.1 h1:I7maFPz5MBCwiutOrz++DLdbr4rTzBsbBuV2VpgU9kk=
|
||||
github.com/hajimehoshi/oto v0.7.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos=
|
||||
github.com/jakecoffman/cp v1.0.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
|
||||
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/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
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=
|
||||
@ -50,10 +46,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac h1:kYPjbEN6YPYWWHI6ky1J813KzIq/8+Wg4TO4xU7A/KU=
|
||||
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
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=
|
||||
@ -65,21 +57,18 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
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/exp v0.0.0-20210220032938-85be41e4509f h1:GrkO5AtFUU9U/1f5ctbIBXtBGeSJbWwIYfIsTcFMaX4=
|
||||
golang.org/x/exp v0.0.0-20210220032938-85be41e4509f/go.mod h1:I6l2HNBLBZEcrOoCpyKLdY2lHoRZ8lI4x60KMCQDft4=
|
||||
golang.org/x/exp v0.0.0-20201008143054-e3b2a7f2fdc7 h1:2/QncOxxpPAdiH+E00abYw/SaQG353gltz79Nl1zrYE=
|
||||
golang.org/x/exp v0.0.0-20201008143054-e3b2a7f2fdc7/go.mod h1:1phAWC201xIgDyaFpmDeZkgf70Q4Pd/CNqfRtVPtxNw=
|
||||
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-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk=
|
||||
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/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-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20210208171126-f462b3930c8f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08 h1:h+GZ3ubjuWaQjGe8owMGcmMVCqs0xYJtRG5y2bpHaqU=
|
||||
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20200801112145-973feb4309de h1:OVJ6QQUBAesB8CZijKDSsXX7xYVtUhrkY0gwMfbi4p4=
|
||||
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=
|
||||
@ -99,11 +88,10 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5vs5/gRy+XWFtZFu7NBM=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201028215240-c5abc1b1d397 h1:YZ169h3kkKEXsueizzMwOT9AaiffbOa6oXSmUFJ4vxM=
|
||||
golang.org/x/sys v0.0.0-20201028215240-c5abc1b1d397/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-20190328211700-ab21143f2384/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-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
|
Loading…
Reference in New Issue
Block a user