Minor enhancements to map loading (#202)
* Minor improvements to map loading/rendering speed. * Update region.go
This commit is contained in:
parent
5eafa9cc0b
commit
0c7f4e0647
|
@ -148,36 +148,33 @@ func (v *Engine) GenTiles(region *EngineRegion) {
|
|||
|
||||
func (v *Engine) GenTilesCache(region *EngineRegion) {
|
||||
n := 0
|
||||
for _, t := range region.Tiles {
|
||||
for tileIdx := range region.Tiles {
|
||||
t := ®ion.Tiles[tileIdx]
|
||||
if t.tileY < len(region.Region.DS1.Tiles) && t.tileX < len(region.Region.DS1.Tiles[t.tileY]) {
|
||||
tile := region.Region.DS1.Tiles[t.tileY][t.tileX]
|
||||
for i := range tile.Floors {
|
||||
if tile.Floors[i].Hidden || tile.Floors[i].Prop1 == 0 {
|
||||
continue
|
||||
}
|
||||
tileCacheIndex := fmt.Sprintf("%v-%v-%v-%v", t.tileY, t.tileX, tile.Floors[i].MainIndex, tile.Floors[i].SubIndex)
|
||||
region.Region.FloorCache[tileCacheIndex] = region.Region.generateFloorCache(tile.Floors[i])
|
||||
region.Region.generateFloorCache(tile.Floors[i])
|
||||
n++
|
||||
}
|
||||
for i, shadow := range tile.Shadows {
|
||||
if tile.Shadows[i].Hidden || tile.Shadows[i].Prop1 == 0 {
|
||||
continue
|
||||
}
|
||||
tileCacheIndex := fmt.Sprintf("%v-%v-%v-%v", t.tileY, t.tileX, shadow.MainIndex, shadow.SubIndex)
|
||||
region.Region.ShadowCache[tileCacheIndex] = region.Region.generateShadowCache(shadow)
|
||||
region.Region.generateShadowCache(shadow)
|
||||
n++
|
||||
}
|
||||
for i, wall := range tile.Walls {
|
||||
if tile.Walls[i].Hidden {
|
||||
continue
|
||||
}
|
||||
tileCacheIndex := fmt.Sprintf("%v-%v-%v-%v-%v", t.tileY, t.tileX, wall.MainIndex, wall.SubIndex, wall.Orientation)
|
||||
region.Region.WallCache[tileCacheIndex] = region.Region.generateWallCache(wall)
|
||||
region.Region.generateWallCache(wall)
|
||||
n++
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Printf("generated: %v cached tiles\n", n)
|
||||
}
|
||||
|
||||
func (v *Engine) RenderRegion(region EngineRegion, target *ebiten.Image) {
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
package d2mapengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"log"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/OpenDiablo2/D2Shared/d2data/d2dt1"
|
||||
|
@ -26,8 +24,6 @@ import (
|
|||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2render"
|
||||
|
||||
"github.com/OpenDiablo2/D2Shared/d2data"
|
||||
|
||||
"github.com/OpenDiablo2/D2Shared/d2data/d2datadict"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
|
@ -49,23 +45,19 @@ type Region struct {
|
|||
Tiles []d2dt1.Tile
|
||||
DS1 d2ds1.DS1
|
||||
Palette d2datadict.PaletteRec
|
||||
FloorCache map[string]*TileCacheRecord
|
||||
ShadowCache map[string]*TileCacheRecord
|
||||
WallCache map[string]*TileCacheRecord
|
||||
AnimationEntities []d2render.AnimatedEntity
|
||||
NPCs []*d2core.NPC
|
||||
StartX float64
|
||||
StartY float64
|
||||
imageCacheRecords map[uint32]*ebiten.Image
|
||||
}
|
||||
|
||||
func LoadRegion(seed rand.Source, levelType d2enum.RegionIdType, levelPreset int, fileProvider d2interface.FileProvider, fileIndex int) *Region {
|
||||
result := &Region{
|
||||
LevelType: d2datadict.LevelTypes[levelType],
|
||||
LevelPreset: d2datadict.LevelPresets[levelPreset],
|
||||
Tiles: make([]d2dt1.Tile, 0),
|
||||
FloorCache: make(map[string]*TileCacheRecord),
|
||||
ShadowCache: make(map[string]*TileCacheRecord),
|
||||
WallCache: make(map[string]*TileCacheRecord),
|
||||
LevelType: d2datadict.LevelTypes[levelType],
|
||||
LevelPreset: d2datadict.LevelPresets[levelPreset],
|
||||
Tiles: make([]d2dt1.Tile, 0),
|
||||
imageCacheRecords: map[uint32]*ebiten.Image{},
|
||||
}
|
||||
result.Palette = d2datadict.Palettes[d2enum.PaletteType("act"+strconv.Itoa(int(result.LevelType.Act)))]
|
||||
//bm := result.levelPreset.Dt1Mask
|
||||
|
@ -123,33 +115,27 @@ func (v *Region) loadSpecials() {
|
|||
}
|
||||
|
||||
func (v *Region) loadObjects(fileProvider d2interface.FileProvider) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(v.DS1.Objects))
|
||||
v.AnimationEntities = make([]d2render.AnimatedEntity, 0)
|
||||
v.NPCs = make([]*d2core.NPC, 0)
|
||||
for _, object := range v.DS1.Objects {
|
||||
go func(object d2data.Object) {
|
||||
defer wg.Done()
|
||||
switch object.Lookup.Type {
|
||||
case d2datadict.ObjectTypeCharacter:
|
||||
// Temp code, maybe..
|
||||
if object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" {
|
||||
return
|
||||
}
|
||||
npc := d2core.CreateNPC(object.X, object.Y, object.Lookup, fileProvider, 1)
|
||||
npc.SetPaths(object.Paths)
|
||||
v.NPCs = append(v.NPCs, npc)
|
||||
case d2datadict.ObjectTypeItem:
|
||||
if object.ObjectInfo == nil || !object.ObjectInfo.Draw || object.Lookup.Base == "" || object.Lookup.Token == "" {
|
||||
return
|
||||
}
|
||||
entity := d2render.CreateAnimatedEntity(object.X, object.Y, object.Lookup, fileProvider, d2enum.Units)
|
||||
entity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0)
|
||||
v.AnimationEntities = append(v.AnimationEntities, entity)
|
||||
switch object.Lookup.Type {
|
||||
case d2datadict.ObjectTypeCharacter:
|
||||
// Temp code, maybe..
|
||||
if object.Lookup.Base == "" || object.Lookup.Token == "" || object.Lookup.TR == "" {
|
||||
continue
|
||||
}
|
||||
}(object)
|
||||
npc := d2core.CreateNPC(object.X, object.Y, object.Lookup, fileProvider, 1)
|
||||
npc.SetPaths(object.Paths)
|
||||
v.NPCs = append(v.NPCs, npc)
|
||||
case d2datadict.ObjectTypeItem:
|
||||
if object.ObjectInfo == nil || !object.ObjectInfo.Draw || object.Lookup.Base == "" || object.Lookup.Token == "" {
|
||||
continue
|
||||
}
|
||||
entity := d2render.CreateAnimatedEntity(object.X, object.Y, object.Lookup, fileProvider, d2enum.Units)
|
||||
entity.SetMode(object.Lookup.Mode, object.Lookup.Class, 0)
|
||||
v.AnimationEntities = append(v.AnimationEntities, entity)
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (v *Region) RenderTile(offsetX, offsetY, tileX, tileY int, layerType d2enum.RegionLayerType, layerIndex int, target *ebiten.Image) {
|
||||
|
@ -203,71 +189,76 @@ func (v *Region) getTile(mainIndex, subIndex, orientation int32) *d2dt1.Tile {
|
|||
}
|
||||
|
||||
func (v *Region) renderFloor(tile d2ds1.FloorShadowRecord, offsetX, offsetY int, target *ebiten.Image, tileX, tileY int) {
|
||||
tileCacheIndex := fmt.Sprintf("%v-%v-%v-%v", tileY, tileX, tile.MainIndex, tile.SubIndex)
|
||||
tileCache, exists := v.FloorCache[tileCacheIndex]
|
||||
if !exists {
|
||||
log.Printf("floor cache missed: %v of %v", tileCacheIndex, len(v.FloorCache))
|
||||
v.FloorCache[tileCacheIndex] = v.generateFloorCache(tile)
|
||||
tileCache = v.FloorCache[tileCacheIndex]
|
||||
if tileCache == nil {
|
||||
log.Println("Could not load floor tile: " + tileCacheIndex)
|
||||
return
|
||||
}
|
||||
}
|
||||
if tileCache == nil {
|
||||
log.Println("Nil tile cache: " + tileCacheIndex)
|
||||
return
|
||||
}
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
opts.GeoM.Translate(float64(offsetX+tileCache.XOffset), float64(offsetY+tileCache.YOffset))
|
||||
target.DrawImage(tileCache.Image, opts)
|
||||
img := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 0)
|
||||
if img == nil {
|
||||
img = v.generateFloorCache(tile)
|
||||
}
|
||||
opts.GeoM.Translate(float64(offsetX), float64(offsetY))
|
||||
_ = target.DrawImage(img, opts)
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Region) renderWall(tile d2ds1.WallRecord, offsetX, offsetY int, target *ebiten.Image, tileX, tileY int) {
|
||||
tileCacheIndex := fmt.Sprintf("%v-%v-%v-%v-%v", tileY, tileX, tile.MainIndex, tile.SubIndex, tile.Orientation)
|
||||
tileCache, exists := v.WallCache[tileCacheIndex]
|
||||
if !exists {
|
||||
log.Println("wall cache missed")
|
||||
v.WallCache[tileCacheIndex] = v.generateWallCache(tile)
|
||||
if v.WallCache[tileCacheIndex] == nil {
|
||||
log.Println("Could not generate wall: " + tileCacheIndex)
|
||||
return
|
||||
}
|
||||
tileCache = v.WallCache[tileCacheIndex]
|
||||
img := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, tile.Orientation)
|
||||
if img == nil {
|
||||
img = v.generateWallCache(tile)
|
||||
}
|
||||
if tileCache == nil {
|
||||
log.Println("Nil tile cache: " + tileCacheIndex)
|
||||
tileData := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), int32(tile.Orientation))
|
||||
if tileData == nil {
|
||||
return
|
||||
}
|
||||
var newTileData *d2dt1.Tile = nil
|
||||
if tile.Orientation == 3 {
|
||||
newTileData = v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), int32(4))
|
||||
}
|
||||
tileMinY := int32(0)
|
||||
tileMaxY := int32(0)
|
||||
targetTileData := tileData
|
||||
if newTileData != nil && newTileData.Height < tileData.Height {
|
||||
targetTileData = newTileData
|
||||
}
|
||||
for _, block := range targetTileData.Blocks {
|
||||
tileMinY = d2helper.MinInt32(tileMinY, int32(block.Y))
|
||||
tileMaxY = d2helper.MaxInt32(tileMaxY, int32(block.Y+32))
|
||||
}
|
||||
|
||||
yAdjust := 0
|
||||
if tile.Orientation > 15 {
|
||||
// Lower Walls
|
||||
yAdjust = 80
|
||||
} else if tile.Orientation == 15 {
|
||||
// Roof
|
||||
yAdjust = -int(tileData.RoofHeight)
|
||||
} else {
|
||||
// Upper Walls, Special Tiles
|
||||
yAdjust = int(tileMinY) + 80
|
||||
}
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
opts.GeoM.Translate(float64(offsetX+tileCache.XOffset), float64(offsetY+tileCache.YOffset))
|
||||
target.DrawImage(tileCache.Image, opts)
|
||||
opts.GeoM.Translate(float64(offsetX), float64(offsetY+yAdjust))
|
||||
target.DrawImage(img, opts)
|
||||
}
|
||||
|
||||
func (v *Region) renderShadow(tile d2ds1.FloorShadowRecord, offsetX, offsetY int, target *ebiten.Image, tileX, tileY int) {
|
||||
tileCacheIndex := fmt.Sprintf("%v-%v-%v-%v", tileY, tileX, tile.MainIndex, tile.SubIndex)
|
||||
tileCache, exists := v.ShadowCache[tileCacheIndex]
|
||||
if !exists {
|
||||
log.Println("shadow cache missed")
|
||||
v.ShadowCache[tileCacheIndex] = v.generateShadowCache(tile)
|
||||
tileCache = v.ShadowCache[tileCacheIndex]
|
||||
if tileCache == nil {
|
||||
log.Println("Could not load shadow tile: " + tileCacheIndex)
|
||||
return
|
||||
}
|
||||
img := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 13)
|
||||
if img == nil {
|
||||
img = v.generateShadowCache(tile)
|
||||
}
|
||||
if tileCache == nil {
|
||||
log.Println("Nil tile cache: " + tileCacheIndex)
|
||||
tileData := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), 13)
|
||||
if tileData == nil {
|
||||
return
|
||||
}
|
||||
tileMinY := int32(0)
|
||||
for _, block := range tileData.Blocks {
|
||||
tileMinY = d2helper.MinInt32(tileMinY, int32(block.Y))
|
||||
}
|
||||
opts := &ebiten.DrawImageOptions{}
|
||||
opts.GeoM.Translate(float64(offsetX+tileCache.XOffset), float64(offsetY+tileCache.YOffset))
|
||||
opts.GeoM.Translate(float64(offsetX), float64(offsetY+int(tileMinY)+80))
|
||||
opts.ColorM = d2corehelper.ColorToColorM(color.RGBA{255, 255, 255, 160})
|
||||
target.DrawImage(tileCache.Image, opts)
|
||||
target.DrawImage(img, opts)
|
||||
}
|
||||
|
||||
func (v *Region) decodeTileGfxData(blocks []d2dt1.Block, pixels []byte, tileYOffset int32, tileWidth int32) {
|
||||
func (v *Region) decodeTileGfxData(blocks []d2dt1.Block, pixels *[]byte, tileYOffset int32, tileWidth int32) {
|
||||
for _, block := range blocks {
|
||||
if block.Format == d2dt1.BlockFormatIsometric {
|
||||
// 3D isometric decoding
|
||||
|
@ -288,10 +279,10 @@ func (v *Region) decodeTileGfxData(blocks []d2dt1.Block, pixels []byte, tileYOff
|
|||
if colorIndex != 0 {
|
||||
pixelColor := v.Palette.Colors[colorIndex]
|
||||
offset := 4 * (((blockY + y + tileYOffset) * tileWidth) + (blockX + x))
|
||||
pixels[offset] = pixelColor.R
|
||||
pixels[offset+1] = pixelColor.G
|
||||
pixels[offset+2] = pixelColor.B
|
||||
pixels[offset+3] = 255
|
||||
(*pixels)[offset] = pixelColor.R
|
||||
(*pixels)[offset+1] = pixelColor.G
|
||||
(*pixels)[offset+2] = pixelColor.B
|
||||
(*pixels)[offset+3] = 255
|
||||
}
|
||||
x++
|
||||
n--
|
||||
|
@ -324,10 +315,10 @@ func (v *Region) decodeTileGfxData(blocks []d2dt1.Block, pixels []byte, tileYOff
|
|||
if colorIndex != 0 {
|
||||
pixelColor := v.Palette.Colors[colorIndex]
|
||||
offset := 4 * (((blockY + y + tileYOffset) * tileWidth) + (blockX + x))
|
||||
pixels[offset] = pixelColor.R
|
||||
pixels[offset+1] = pixelColor.G
|
||||
pixels[offset+2] = pixelColor.B
|
||||
pixels[offset+3] = 255
|
||||
(*pixels)[offset] = pixelColor.R
|
||||
(*pixels)[offset+1] = pixelColor.G
|
||||
(*pixels)[offset+2] = pixelColor.B
|
||||
(*pixels)[offset+3] = 255
|
||||
|
||||
}
|
||||
idx++
|
||||
|
@ -339,7 +330,7 @@ func (v *Region) decodeTileGfxData(blocks []d2dt1.Block, pixels []byte, tileYOff
|
|||
}
|
||||
}
|
||||
|
||||
func (v *Region) generateFloorCache(tile d2ds1.FloorShadowRecord) *TileCacheRecord {
|
||||
func (v *Region) generateFloorCache(tile d2ds1.FloorShadowRecord) *ebiten.Image {
|
||||
tileData := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), 0)
|
||||
if tileData == nil {
|
||||
log.Printf("Could not locate tile Idx:%d, Sub: %d, Ori: %d\n", tile.MainIndex, tile.SubIndex, 0)
|
||||
|
@ -347,6 +338,10 @@ func (v *Region) generateFloorCache(tile d2ds1.FloorShadowRecord) *TileCacheReco
|
|||
tileData.Width = 10
|
||||
tileData.Height = 10
|
||||
}
|
||||
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 0)
|
||||
if cachedImage != nil {
|
||||
return cachedImage
|
||||
}
|
||||
tileYMinimum := int32(0)
|
||||
for _, block := range tileData.Blocks {
|
||||
tileYMinimum = d2helper.MinInt32(tileYMinimum, int32(block.Y))
|
||||
|
@ -355,16 +350,21 @@ func (v *Region) generateFloorCache(tile d2ds1.FloorShadowRecord) *TileCacheReco
|
|||
tileHeight := d2helper.AbsInt32(tileData.Height)
|
||||
image, _ := ebiten.NewImage(int(tileData.Width), int(tileHeight), ebiten.FilterNearest)
|
||||
pixels := make([]byte, 4*tileData.Width*tileHeight)
|
||||
v.decodeTileGfxData(tileData.Blocks, pixels, tileYOffset, tileData.Width)
|
||||
v.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, tileData.Width)
|
||||
image.ReplacePixels(pixels)
|
||||
return &TileCacheRecord{image, 0, 0}
|
||||
v.SetImageCacheRecord(tile.MainIndex, tile.SubIndex, 0, image)
|
||||
return image
|
||||
}
|
||||
|
||||
func (v *Region) generateShadowCache(tile d2ds1.FloorShadowRecord) *TileCacheRecord {
|
||||
func (v *Region) generateShadowCache(tile d2ds1.FloorShadowRecord) *ebiten.Image {
|
||||
tileData := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), 13)
|
||||
if tileData == nil {
|
||||
return nil
|
||||
}
|
||||
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, 13)
|
||||
if cachedImage != nil {
|
||||
return cachedImage
|
||||
}
|
||||
tileMinY := int32(0)
|
||||
tileMaxY := int32(0)
|
||||
for _, block := range tileData.Blocks {
|
||||
|
@ -375,12 +375,13 @@ func (v *Region) generateShadowCache(tile d2ds1.FloorShadowRecord) *TileCacheRec
|
|||
tileHeight := int(tileMaxY - tileMinY)
|
||||
image, _ := ebiten.NewImage(int(tileData.Width), int(tileHeight), ebiten.FilterNearest)
|
||||
pixels := make([]byte, 4*tileData.Width*int32(tileHeight))
|
||||
v.decodeTileGfxData(tileData.Blocks, pixels, tileYOffset, tileData.Width)
|
||||
v.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, tileData.Width)
|
||||
image.ReplacePixels(pixels)
|
||||
return &TileCacheRecord{image, 0, int(tileMinY) + 80}
|
||||
v.SetImageCacheRecord(tile.MainIndex, tile.SubIndex, 13, image)
|
||||
return image
|
||||
}
|
||||
|
||||
func (v *Region) generateWallCache(tile d2ds1.WallRecord) *TileCacheRecord {
|
||||
func (v *Region) generateWallCache(tile d2ds1.WallRecord) *ebiten.Image {
|
||||
tileData := v.getTile(int32(tile.MainIndex), int32(tile.SubIndex), int32(tile.Orientation))
|
||||
if tileData == nil {
|
||||
return nil
|
||||
|
@ -403,31 +404,30 @@ func (v *Region) generateWallCache(tile d2ds1.WallRecord) *TileCacheRecord {
|
|||
realHeight := d2helper.MaxInt32(d2helper.AbsInt32(tileData.Height), tileMaxY-tileMinY)
|
||||
tileYOffset := -tileMinY
|
||||
//tileHeight := int(tileMaxY - tileMinY)
|
||||
|
||||
cachedImage := v.GetImageCacheRecord(tile.MainIndex, tile.SubIndex, tile.Orientation)
|
||||
if cachedImage != nil {
|
||||
return cachedImage //, 0, yAdjust}
|
||||
}
|
||||
image, _ := ebiten.NewImage(160, int(realHeight), ebiten.FilterNearest)
|
||||
pixels := make([]byte, 4*160*realHeight)
|
||||
v.decodeTileGfxData(tileData.Blocks, pixels, tileYOffset, 160)
|
||||
v.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, 160)
|
||||
if newTileData != nil {
|
||||
v.decodeTileGfxData(newTileData.Blocks, pixels, tileYOffset, 160)
|
||||
v.decodeTileGfxData(newTileData.Blocks, &pixels, tileYOffset, 160)
|
||||
}
|
||||
yAdjust := 0
|
||||
if tile.Orientation > 15 {
|
||||
// Lower Walls
|
||||
yAdjust = 80
|
||||
} else if tile.Orientation == 15 {
|
||||
// Roof
|
||||
yAdjust = -int(tileData.RoofHeight)
|
||||
} else {
|
||||
// Upper Walls, Special Tiles
|
||||
yAdjust = int(tileMinY) + 80
|
||||
}
|
||||
|
||||
// TODO: This may also need to be an atlas, but could get pretty large...
|
||||
if err := image.ReplacePixels(pixels); err != nil {
|
||||
log.Panicf(err.Error())
|
||||
}
|
||||
return &TileCacheRecord{
|
||||
image,
|
||||
0,
|
||||
yAdjust,
|
||||
}
|
||||
v.SetImageCacheRecord(tile.MainIndex, tile.SubIndex, tile.Orientation, image)
|
||||
return image //,0,yAdjust,
|
||||
}
|
||||
|
||||
func (v *Region) GetImageCacheRecord(mainIndex, subIndex, orientation byte) *ebiten.Image {
|
||||
lookupIndex := uint32(mainIndex)<<16 | uint32(subIndex)<<8 | uint32(orientation)
|
||||
return v.imageCacheRecords[lookupIndex]
|
||||
}
|
||||
|
||||
func (v *Region) SetImageCacheRecord(mainIndex, subIndex, orientation byte, image *ebiten.Image) {
|
||||
lookupIndex := uint32(mainIndex)<<16 | uint32(subIndex)<<8 | uint32(orientation)
|
||||
v.imageCacheRecords[lookupIndex] = image
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package d2mapengine
|
||||
|
||||
import "github.com/hajimehoshi/ebiten"
|
||||
|
||||
type TileCacheRecord struct {
|
||||
Image *ebiten.Image
|
||||
XOffset int
|
||||
YOffset int
|
||||
}
|
|
@ -2,7 +2,6 @@ package d2render
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"image"
|
||||
"image/color"
|
||||
"log"
|
||||
"sync"
|
||||
|
@ -126,17 +125,18 @@ func CreateSprite(data []byte, palette d2datadict.PaletteRec) Sprite {
|
|||
x += uint32(b)
|
||||
}
|
||||
}
|
||||
var img = image.NewRGBA(image.Rect(0, 0, int(result.Frames[i].Width), int(result.Frames[i].Height)))
|
||||
var img = make([]byte, int(result.Frames[i].Width)*int(result.Frames[i].Height)*4)
|
||||
for ii := uint32(0); ii < result.Frames[i].Width*result.Frames[i].Height; ii++ {
|
||||
if result.Frames[i].ImageData[ii] < 1 { // TODO: Is this == -1 or < 1?
|
||||
continue
|
||||
}
|
||||
img.Pix[ii*4] = palette.Colors[result.Frames[i].ImageData[ii]].R
|
||||
img.Pix[(ii*4)+1] = palette.Colors[result.Frames[i].ImageData[ii]].G
|
||||
img.Pix[(ii*4)+2] = palette.Colors[result.Frames[i].ImageData[ii]].B
|
||||
img.Pix[(ii*4)+3] = 0xFF
|
||||
img[ii*4] = palette.Colors[result.Frames[i].ImageData[ii]].R
|
||||
img[(ii*4)+1] = palette.Colors[result.Frames[i].ImageData[ii]].G
|
||||
img[(ii*4)+2] = palette.Colors[result.Frames[i].ImageData[ii]].B
|
||||
img[(ii*4)+3] = 0xFF
|
||||
}
|
||||
newImage, _ := ebiten.NewImageFromImage(img, ebiten.FilterNearest)
|
||||
newImage, _ := ebiten.NewImage(int(result.Frames[i].Width), int(result.Frames[i].Height), ebiten.FilterNearest)
|
||||
newImage.ReplacePixels(img)
|
||||
result.Frames[i].Image = newImage
|
||||
img = nil
|
||||
}(i)
|
||||
|
|
2
go.mod
2
go.mod
|
@ -7,7 +7,7 @@ require (
|
|||
github.com/OpenDiablo2/D2Shared v0.0.0-20191117053631-b0c159330365
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117051038-800b98a0c66d
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117152313-63f9ac2ccc2a
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/pkg/profile v1.3.0
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -27,6 +27,8 @@ github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191116200143-acc933b7c399 h1:Uey
|
|||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191116200143-acc933b7c399/go.mod h1:52cGPFR+BqkkBap9Ue4BEKkfvICkvXoONeWCYPEFTPo=
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117051038-800b98a0c66d h1:dJL9ygMUE9U5WOEwgQ+D33t0dDRm3VkwNi2lzaoGQ6A=
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117051038-800b98a0c66d/go.mod h1:6ax6p5ui8fuQ/+00sQ79oTy4OfrythHfDEYV4yni5So=
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117152313-63f9ac2ccc2a h1:EoW3KYFBekMCBuCxnmseVGV0wh6pgmkZGJP7pRWK4ek=
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.0.20191117152313-63f9ac2ccc2a/go.mod h1:6ax6p5ui8fuQ/+00sQ79oTy4OfrythHfDEYV4yni5So=
|
||||
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
||||
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
|
||||
github.com/hajimehoshi/oto v0.5.2 h1:5FEPlejAsR2PVRqiW7h2PIwp9UWR+8zxj2And102YU4=
|
||||
|
|
Loading…
Reference in New Issue