Big fixes. Added start of video decode. Enhanced MPQ error messages.
This commit is contained in:
parent
02082925b5
commit
bf0412554f
|
@ -0,0 +1,22 @@
|
||||||
|
package Common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GameState struct {
|
||||||
|
Seed int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateGameState() *GameState {
|
||||||
|
result := &GameState{
|
||||||
|
Seed: time.Now().UnixNano(),
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadGameState(path string) *GameState {
|
||||||
|
log.Fatal("LoadGameState not implemented.")
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ type EngineConfig struct {
|
||||||
|
|
||||||
// Engine is the core OpenDiablo2 engine
|
// Engine is the core OpenDiablo2 engine
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
Settings *EngineConfig // Engine configuration settings from json file
|
Settings *EngineConfig // Engine configuration settings from json file
|
||||||
Files map[string]string // Map that defines which files are in which MPQs
|
Files map[string]string // Map that defines which files are in which MPQs
|
||||||
Palettes map[Palettes.Palette]Common.Palette // Color palettes
|
Palettes map[Palettes.Palette]Common.Palette // Color palettes
|
||||||
SoundEntries map[string]Sound.SoundEntry // Sound configurations
|
SoundEntries map[string]Sound.SoundEntry // Sound configurations
|
||||||
|
@ -72,6 +72,7 @@ func CreateEngine() *Engine {
|
||||||
loadingSpriteSizeX, loadingSpriteSizeY := result.LoadingSprite.GetSize()
|
loadingSpriteSizeX, loadingSpriteSizeY := result.LoadingSprite.GetSize()
|
||||||
result.LoadingSprite.MoveTo(int(400-(loadingSpriteSizeX/2)), int(300+(loadingSpriteSizeY/2)))
|
result.LoadingSprite.MoveTo(int(400-(loadingSpriteSizeX/2)), int(300+(loadingSpriteSizeY/2)))
|
||||||
result.SetNextScene(Scenes.CreateMainMenu(result, result, result.UIManager, result.SoundManager))
|
result.SetNextScene(Scenes.CreateMainMenu(result, result, result.UIManager, result.SoundManager))
|
||||||
|
//result.SetNextScene(Scenes.CreateBlizzardIntro(result, result))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +93,8 @@ func (v *Engine) loadConfigurationFile() {
|
||||||
if v.Settings.MpqPath[0] != '/' {
|
if v.Settings.MpqPath[0] != '/' {
|
||||||
if _, err := os.Stat(v.Settings.MpqPath); os.IsNotExist(err) {
|
if _, err := os.Stat(v.Settings.MpqPath); os.IsNotExist(err) {
|
||||||
homeDir, _ := homedir.Dir()
|
homeDir, _ := homedir.Dir()
|
||||||
newPath := strings.ReplaceAll(v.Settings.MpqPath, `C:\`, homeDir + "/.wine/drive_c/")
|
newPath := strings.ReplaceAll(v.Settings.MpqPath, `C:\`, homeDir+"/.wine/drive_c/")
|
||||||
newPath = strings.ReplaceAll(newPath, "C:/", homeDir + "/.wine/drive_c/")
|
newPath = strings.ReplaceAll(newPath, "C:/", homeDir+"/.wine/drive_c/")
|
||||||
newPath = strings.ReplaceAll(newPath, `\`, "/")
|
newPath = strings.ReplaceAll(newPath, `\`, "/")
|
||||||
if _, err := os.Stat(newPath); !os.IsNotExist(err) {
|
if _, err := os.Stat(newPath); !os.IsNotExist(err) {
|
||||||
log.Printf("Detected linux wine installation, path updated to wine prefix path.")
|
log.Printf("Detected linux wine installation, path updated to wine prefix path.")
|
||||||
|
@ -137,11 +138,13 @@ func (v *Engine) LoadFile(fileName string) []byte {
|
||||||
mpqFile := v.Files[strings.ToLower(fileName)]
|
mpqFile := v.Files[strings.ToLower(fileName)]
|
||||||
mpq, err := MPQ.Load(mpqFile)
|
mpq, err := MPQ.Load(mpqFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("Error loading file '%s'", fileName)
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
fileName = strings.ReplaceAll(fileName, `/`, `\`)[1:]
|
fileName = strings.ReplaceAll(fileName, `/`, `\`)[1:]
|
||||||
blockTableEntry, err := mpq.GetFileBlockData(fileName)
|
blockTableEntry, err := mpq.GetFileBlockData(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("Error locating block data entry for '%s' in mpq file '%s'", fileName, mpq.FileName)
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
mpqStream := MPQ.CreateStream(mpq, blockTableEntry, fileName)
|
mpqStream := MPQ.CreateStream(mpq, blockTableEntry, fileName)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
// MPQ represents an MPQ archive
|
// MPQ represents an MPQ archive
|
||||||
type MPQ struct {
|
type MPQ struct {
|
||||||
|
FileName string
|
||||||
File *os.File
|
File *os.File
|
||||||
HashTableEntries []HashTableEntry
|
HashTableEntries []HashTableEntry
|
||||||
BlockTableEntries []BlockTableEntry
|
BlockTableEntries []BlockTableEntry
|
||||||
|
@ -83,7 +84,9 @@ func (v BlockTableEntry) HasFlag(flag FileFlag) bool {
|
||||||
|
|
||||||
// Load loads an MPQ file and returns a MPQ structure
|
// Load loads an MPQ file and returns a MPQ structure
|
||||||
func Load(fileName string) (MPQ, error) {
|
func Load(fileName string) (MPQ, error) {
|
||||||
result := MPQ{}
|
result := MPQ{
|
||||||
|
FileName: fileName,
|
||||||
|
}
|
||||||
file, err := os.Open(fileName)
|
file, err := os.Open(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MPQ{}, err
|
return MPQ{}, err
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package MapEngine
|
package Map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/essial/OpenDiablo2/Common"
|
"github.com/essial/OpenDiablo2/Common"
|
|
@ -1,4 +1,4 @@
|
||||||
package MapEngine
|
package Map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
|
@ -0,0 +1,46 @@
|
||||||
|
package Map
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
|
||||||
|
"github.com/essial/OpenDiablo2/Common"
|
||||||
|
"github.com/essial/OpenDiablo2/Sound"
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EngineRegion struct {
|
||||||
|
Rect image.Rectangle
|
||||||
|
Region Region
|
||||||
|
}
|
||||||
|
|
||||||
|
type Engine struct {
|
||||||
|
soundManager *Sound.Manager
|
||||||
|
gameState *Common.GameState
|
||||||
|
fileProvider Common.FileProvider
|
||||||
|
regions []*EngineRegion
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateMapEngine(gameState *Common.GameState, soundManager *Sound.Manager, fileProvider Common.FileProvider) *Engine {
|
||||||
|
result := &Engine{
|
||||||
|
gameState: gameState,
|
||||||
|
soundManager: soundManager,
|
||||||
|
fileProvider: fileProvider,
|
||||||
|
regions: make([]*EngineRegion, 0),
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Engine) GenerateMap(regionType RegionIdType, levelPreset int) {
|
||||||
|
//randomSource := rand.NewSource(v.gameState.Seed)
|
||||||
|
//region := LoadRegion(randomSource, regionType, levelPreset, v.fileProvider)
|
||||||
|
v.soundManager.PlayBGM("/data/global/music/Act1/tristram.wav")
|
||||||
|
v.ReloadMapCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Engine) ReloadMapCache() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Engine) Render(target *ebiten.Image) {
|
||||||
|
//v.region.RenderTile(300, 300, 0, 0, Map.RegionLayerTypeFloors, 0, screen)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package MapEngine
|
package Map
|
||||||
|
|
||||||
type Orientation int32
|
type Orientation int32
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package MapEngine
|
package Map
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
@ -77,9 +77,7 @@ func LoadRegion(seed rand.Source, levelType RegionIdType, levelPreset int, fileP
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dt1 := LoadDT1("/data/global/tiles/"+levelTypeDt1, fileProvider)
|
dt1 := LoadDT1("/data/global/tiles/"+levelTypeDt1, fileProvider)
|
||||||
for _, tileData := range dt1.Tiles {
|
result.Tiles = append(result.Tiles, dt1.Tiles...)
|
||||||
result.Tiles = append(result.Tiles, tileData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
levelFilesToPick := make([]string, 0)
|
levelFilesToPick := make([]string, 0)
|
||||||
for _, fileRecord := range result.levelPreset.Files {
|
for _, fileRecord := range result.levelPreset.Files {
|
|
@ -0,0 +1,43 @@
|
||||||
|
package Scenes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/essial/OpenDiablo2/Common"
|
||||||
|
"github.com/essial/OpenDiablo2/Video"
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BlizzardIntro struct {
|
||||||
|
fileProvider Common.FileProvider
|
||||||
|
sceneProvider SceneProvider
|
||||||
|
videoDecoder *Video.BinkDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateBlizzardIntro(fileProvider Common.FileProvider, sceneProvider SceneProvider) *BlizzardIntro {
|
||||||
|
result := &BlizzardIntro{
|
||||||
|
fileProvider: fileProvider,
|
||||||
|
sceneProvider: sceneProvider,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BlizzardIntro) Load() []func() {
|
||||||
|
return []func(){
|
||||||
|
func() {
|
||||||
|
videoBytes := v.fileProvider.LoadFile("/data/local/video/BlizNorth640x480.bik")
|
||||||
|
v.videoDecoder = Video.CreateBinkDecoder(videoBytes)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BlizzardIntro) Unload() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BlizzardIntro) Render(screen *ebiten.Image) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BlizzardIntro) Update(tickTime float64) {
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,8 @@
|
||||||
package Scenes
|
package Scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/essial/OpenDiablo2/Common"
|
"github.com/essial/OpenDiablo2/Common"
|
||||||
"github.com/essial/OpenDiablo2/MapEngine"
|
"github.com/essial/OpenDiablo2/Map"
|
||||||
"github.com/essial/OpenDiablo2/Sound"
|
"github.com/essial/OpenDiablo2/Sound"
|
||||||
"github.com/essial/OpenDiablo2/UI"
|
"github.com/essial/OpenDiablo2/UI"
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
@ -16,7 +13,9 @@ type MapEngineTest struct {
|
||||||
soundManager *Sound.Manager
|
soundManager *Sound.Manager
|
||||||
fileProvider Common.FileProvider
|
fileProvider Common.FileProvider
|
||||||
sceneProvider SceneProvider
|
sceneProvider SceneProvider
|
||||||
region *MapEngine.Region
|
//region *Map.Region
|
||||||
|
gameState *Common.GameState
|
||||||
|
mapEngine *Map.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateMapEngineTest(fileProvider Common.FileProvider, sceneProvider SceneProvider, uiManager *UI.Manager, soundManager *Sound.Manager) *MapEngineTest {
|
func CreateMapEngineTest(fileProvider Common.FileProvider, sceneProvider SceneProvider, uiManager *UI.Manager, soundManager *Sound.Manager) *MapEngineTest {
|
||||||
|
@ -26,16 +25,18 @@ func CreateMapEngineTest(fileProvider Common.FileProvider, sceneProvider ScenePr
|
||||||
soundManager: soundManager,
|
soundManager: soundManager,
|
||||||
sceneProvider: sceneProvider,
|
sceneProvider: sceneProvider,
|
||||||
}
|
}
|
||||||
|
result.gameState = Common.CreateGameState()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MapEngineTest) Load() []func() {
|
func (v *MapEngineTest) Load() []func() {
|
||||||
// TODO: Game seed comes from the game state object
|
// TODO: Game seed comes from the game state object
|
||||||
randomSource := rand.NewSource(time.Now().UnixNano())
|
|
||||||
v.soundManager.PlayBGM("")
|
v.soundManager.PlayBGM("")
|
||||||
return []func(){
|
return []func(){
|
||||||
func() {
|
func() {
|
||||||
v.region = MapEngine.LoadRegion(randomSource, MapEngine.RegionAct1Tristram, 300, v.fileProvider)
|
v.mapEngine = Map.CreateMapEngine(v.gameState, v.soundManager, v.fileProvider)
|
||||||
|
v.mapEngine.GenerateMap(Map.RegionAct1Tristram, 300)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ func (v *MapEngineTest) Unload() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
func (v *MapEngineTest) Render(screen *ebiten.Image) {
|
||||||
v.region.RenderTile(300, 300, 0, 0, MapEngine.RegionLayerTypeFloors, 0, screen)
|
v.mapEngine.Render(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MapEngineTest) Update(tickTime float64) {
|
func (v *MapEngineTest) Update(tickTime float64) {
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package Video
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/essial/OpenDiablo2/Common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BinkVideoMode uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
BinkVideoModeNormal BinkVideoMode = 0
|
||||||
|
BinkVideoModeHeightDoubled BinkVideoMode = 1
|
||||||
|
BinkVideoModeHeightInterlaced BinkVideoMode = 2
|
||||||
|
BinkVideoModeWidthDoubled BinkVideoMode = 3
|
||||||
|
BinkVideoModeWidthAndHeightDoubled BinkVideoMode = 4
|
||||||
|
BinkVideoModeWidthAndHeightInterlaced BinkVideoMode = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
type BinkAudioAlgorithm uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
BinkAudioAlgorithmFFT BinkAudioAlgorithm = 0
|
||||||
|
BinkAudioAlgorithmDCT BinkAudioAlgorithm = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
type BinkAudioTrack struct {
|
||||||
|
AudioChannels uint16
|
||||||
|
AudioSampleRateHz uint16
|
||||||
|
Stereo bool
|
||||||
|
Algorithm BinkAudioAlgorithm
|
||||||
|
AudioTrackId uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type BinkDecoder struct {
|
||||||
|
videoCodecRevision byte
|
||||||
|
fileSize uint32
|
||||||
|
numberOfFrames uint32
|
||||||
|
largestFrameSizeBytes uint32
|
||||||
|
VideoWidth uint32
|
||||||
|
VideoHeight uint32
|
||||||
|
FPS uint32
|
||||||
|
FrameTimeMS uint32
|
||||||
|
streamReader *Common.StreamReader
|
||||||
|
VideoMode BinkVideoMode
|
||||||
|
HasAlphaPlane bool
|
||||||
|
Grayscale bool
|
||||||
|
AudioTracks []BinkAudioTrack
|
||||||
|
FrameIndexTable []uint32 // Mask bit 0, as this is defined as a keyframe
|
||||||
|
frameIndex uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateBinkDecoder(source []byte) *BinkDecoder {
|
||||||
|
result := &BinkDecoder{
|
||||||
|
streamReader: Common.CreateStreamReader(source),
|
||||||
|
}
|
||||||
|
result.loadHeaderInformation()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BinkDecoder) GetNextFrame() {
|
||||||
|
//v.streamReader.SetPosition(uint64(v.FrameIndexTable[i] & 0xFFFFFFFE))
|
||||||
|
lengthOfAudioPackets := v.streamReader.GetUInt32() - 4
|
||||||
|
samplesInPacket := v.streamReader.GetUInt32()
|
||||||
|
v.streamReader.SkipBytes(int(lengthOfAudioPackets))
|
||||||
|
log.Printf("Frame %d:\tSamp: %d", v.frameIndex, samplesInPacket)
|
||||||
|
|
||||||
|
v.frameIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *BinkDecoder) loadHeaderInformation() {
|
||||||
|
v.streamReader.SetPosition(0)
|
||||||
|
headerBytes, _ := v.streamReader.ReadBytes(3)
|
||||||
|
if string(headerBytes) != "BIK" {
|
||||||
|
log.Fatal("Invalid header for bink video")
|
||||||
|
}
|
||||||
|
v.videoCodecRevision = v.streamReader.GetByte()
|
||||||
|
v.fileSize = v.streamReader.GetUInt32()
|
||||||
|
v.numberOfFrames = v.streamReader.GetUInt32()
|
||||||
|
v.largestFrameSizeBytes = v.streamReader.GetUInt32()
|
||||||
|
v.streamReader.SkipBytes(4) // Number of frames again?
|
||||||
|
v.VideoWidth = v.streamReader.GetUInt32()
|
||||||
|
v.VideoHeight = v.streamReader.GetUInt32()
|
||||||
|
fpsDividend := v.streamReader.GetUInt32()
|
||||||
|
fpsDivider := v.streamReader.GetUInt32()
|
||||||
|
v.FPS = uint32(float32(fpsDividend) / float32(fpsDivider))
|
||||||
|
v.FrameTimeMS = 1000 / v.FPS
|
||||||
|
videoFlags := v.streamReader.GetUInt32()
|
||||||
|
v.VideoMode = BinkVideoMode((videoFlags >> 28) & 0x0F)
|
||||||
|
v.HasAlphaPlane = ((videoFlags >> 20) & 0x1) == 1
|
||||||
|
v.Grayscale = ((videoFlags >> 17) & 0x1) == 1
|
||||||
|
numberOfAudioTracks := v.streamReader.GetUInt32()
|
||||||
|
v.AudioTracks = make([]BinkAudioTrack, numberOfAudioTracks)
|
||||||
|
for i := 0; i < int(numberOfAudioTracks); i++ {
|
||||||
|
v.streamReader.SkipBytes(2) // Unknown
|
||||||
|
v.AudioTracks[i].AudioChannels = v.streamReader.GetUInt16()
|
||||||
|
}
|
||||||
|
for i := 0; i < int(numberOfAudioTracks); i++ {
|
||||||
|
v.AudioTracks[i].AudioSampleRateHz = v.streamReader.GetUInt16()
|
||||||
|
flags := v.streamReader.GetUInt16()
|
||||||
|
v.AudioTracks[i].Stereo = ((flags >> 13) & 0x1) == 1
|
||||||
|
v.AudioTracks[i].Algorithm = BinkAudioAlgorithm((flags >> 12) & 0x1)
|
||||||
|
}
|
||||||
|
for i := 0; i < int(numberOfAudioTracks); i++ {
|
||||||
|
v.AudioTracks[i].AudioTrackId = v.streamReader.GetUInt32()
|
||||||
|
}
|
||||||
|
v.FrameIndexTable = make([]uint32, v.numberOfFrames+1)
|
||||||
|
for i := 0; i < int(v.numberOfFrames+1); i++ {
|
||||||
|
v.FrameIndexTable[i] = v.streamReader.GetUInt32()
|
||||||
|
}
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -4,6 +4,7 @@ go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
|
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
|
||||||
|
github.com/giorgisio/goav v0.1.0
|
||||||
github.com/hajimehoshi/ebiten v1.9.3
|
github.com/hajimehoshi/ebiten v1.9.3
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
)
|
)
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,7 @@
|
||||||
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0 h1:tDnuU0igiBiQFjsvq1Bi7DpoUjqI76VVvW045vpeFeM=
|
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/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0/go.mod h1:h/5OEGj4G+fpYxluLjSMZbFY011ZxAntO98nCl8mrCs=
|
||||||
|
github.com/giorgisio/goav v0.1.0 h1:ZyfG3NfX7PMSimv4ulhmnQJf/XeHpMdGCn+afRmY5Oc=
|
||||||
|
github.com/giorgisio/goav v0.1.0/go.mod h1:RtH8HyxLRLU1iY0pjfhWBKRhnbsnmfoI+FxMwb5bfEo=
|
||||||
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f h1:7MsFMbSn8Lcw0blK4+NEOf8DuHoOBDhJsHz04yh13pM=
|
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f h1:7MsFMbSn8Lcw0blK4+NEOf8DuHoOBDhJsHz04yh13pM=
|
||||||
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/gofrs/flock v0.7.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.7.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
|
@ -11,6 +13,8 @@ github.com/gopherjs/gopherwasm v0.1.1/go.mod h1:kx4n9a+MzHH0BJJhvlsQ65hqLFXDO/m2
|
||||||
github.com/gopherjs/gopherwasm v1.0.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
|
github.com/gopherjs/gopherwasm v1.0.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
|
||||||
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
|
github.com/gopherjs/gopherwasm v1.1.0 h1:fA2uLoctU5+T3OhOn2vYP0DVT6pxc7xhTlBB1paATqQ=
|
||||||
github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
|
github.com/gopherjs/gopherwasm v1.1.0/go.mod h1:SkZ8z7CWBz5VXbhJel8TxCmAcsQqzgWGR/8nMhyhZSI=
|
||||||
|
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||||
|
github.com/gosuri/uiprogress v0.0.0-20170224063937-d0567a9d84a1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0=
|
||||||
github.com/hajimehoshi/bitmapfont v1.1.1/go.mod h1:Hamfxgney7tDSmVOSDh2AWzoDH70OaC+P24zc02Gum4=
|
github.com/hajimehoshi/bitmapfont v1.1.1/go.mod h1:Hamfxgney7tDSmVOSDh2AWzoDH70OaC+P24zc02Gum4=
|
||||||
github.com/hajimehoshi/ebiten v1.9.3 h1:YijWGMBwH2XA1ZytUQFy33UDHeCSS6d4JZKH1wq38O0=
|
github.com/hajimehoshi/ebiten v1.9.3 h1:YijWGMBwH2XA1ZytUQFy33UDHeCSS6d4JZKH1wq38O0=
|
||||||
github.com/hajimehoshi/ebiten v1.9.3/go.mod h1:XxiJ4Eltvb1KmcD0i6F81eIB1asJhK47y5DC+FPkyso=
|
github.com/hajimehoshi/ebiten v1.9.3/go.mod h1:XxiJ4Eltvb1KmcD0i6F81eIB1asJhK47y5DC+FPkyso=
|
||||||
|
|
Loading…
Reference in New Issue