Animation manager abstraction (#544)

* abstracted palettes, colors, and palette manager

* make asset manager use the palette manager interface

* added BGRA setter/getter, fixed lint errors

* abstraction for animation and animation manager
This commit is contained in:
dk 2020-07-05 10:01:44 -07:00 committed by GitHub
parent 8809fb2c22
commit c1a88c9cf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 293 additions and 88 deletions

View File

@ -1,11 +1,22 @@
package d2dat
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
const (
// index offset helpers
b = iota
g
r
o
)
// Load loads a DAT file.
func Load(data []byte) (*DATPalette, error) {
func Load(data []byte) (d2interface.Palette, error) {
palette := &DATPalette{}
for i := 0; i < 256; i++ {
palette.Colors[i] = DATColor{B: data[i*3], G: data[i*3+1], R: data[i*3+2]}
// offsets look like i*3+n, where n is 0,1,2
palette.colors[i] = &DATColor{b: data[i*o+b], g: data[i*o+g], r: data[i*o+r]}
}
return palette, nil

View File

@ -2,7 +2,76 @@ package d2dat
// DATColor represents a single color in a DAT file.
type DATColor struct {
R uint8
G uint8
B uint8
r uint8
g uint8
b uint8
a uint8
}
const (
colorBits = 8
mask = 0xff
)
const (
bitShift0 = iota*colorBits
bitShift8
bitShift16
bitShift24
)
// R gets the red component
func (c *DATColor) R() uint8 {
return c.r
}
// G gets the green component
func (c *DATColor) G() uint8 {
return c.g
}
// B gets the blue component
func (c *DATColor) B() uint8 {
return c.b
}
// A gets the alpha component
func (c *DATColor) A() uint8 {
return mask
}
// RGBA gets the combination of the color components (0xRRGGBBAA)
func (c *DATColor) RGBA() uint32 {
return toComposite(c.r, c.g, c.b, c.a)
}
// SetRGBA sets the color components using the given RGBA form
func (c *DATColor) SetRGBA(rgba uint32) {
c.r, c.g, c.b, c.a = toComponent(rgba)
}
func (c *DATColor) BGRA() uint32 {
return toComposite(c.b, c.g, c.r, c.a)
}
func (c *DATColor) SetBGRA(bgra uint32) {
c.b, c.g, c.r, c.a = toComponent(bgra)
}
func toComposite (w,x,y,z uint8) uint32 {
composite := uint32(w)<<bitShift24
composite += uint32(x)<<bitShift16
composite += uint32(y)<<bitShift8
composite += uint32(z)<<bitShift0
return composite
}
func toComponent (wxyz uint32) (w,x,y,z uint8){
w = uint8(wxyz>>bitShift24 & mask)
x = uint8(wxyz>>bitShift16 & mask)
y = uint8(wxyz>>bitShift8 & mask)
z = uint8(wxyz>>bitShift0 & mask)
return w, x, y, z
}

View File

@ -1,6 +1,34 @@
package d2dat
import (
"fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
)
const (
numColors = 256
)
// DATPalette represents a 256 color palette.
type DATPalette struct {
Colors [256]DATColor
colors [numColors]d2interface.Color
}
// NumColors returns the number of colors in the palette
func (p *DATPalette) NumColors() int {
return len(p.colors)
}
// GetColors returns the slice of colors in the palette
func (p *DATPalette) GetColors() [numColors]d2interface.Color {
return p.colors
}
// GetColor returns a color by index
func (p *DATPalette) GetColor(idx int) (d2interface.Color, error) {
if color := p.colors[idx]; color != nil {
return color, nil
}
return nil, fmt.Errorf("cannot find color index '%d in palette'", idx)
}

View File

@ -0,0 +1,39 @@
package d2interface
import (
"image"
"image/color"
)
// Animation is an animation
type Animation interface {
Clone() Animation
SetSubLoop(startFrame, EndFrame int)
Advance(elapsed float64) error
Render(target Surface) error
RenderFromOrigin(target Surface) error
RenderSection(sfc Surface, bound image.Rectangle) error
GetFrameSize(frameIndex int) (int, int, error)
GetCurrentFrameSize() (int, int)
GetFrameBounds() (int, int)
GetCurrentFrame() int
GetFrameCount() int
IsOnFirstFrame() bool
IsOnLastFrame() bool
GetDirectionCount() int
SetDirection(directionIndex int) error
GetDirection() int
SetCurrentFrame(frameIndex int) error
Rewind()
PlayForward()
PlayBackward()
Pause()
SetPlayLoop(loop bool)
SetPlaySpeed(playSpeed float64)
SetPlayLength(playLength float64)
SetPlayLengthMs(playLengthMs int)
SetColorMod(colorMod color.Color)
GetPlayedCount() int
ResetPlayedCount()
SetBlend(blend bool)
}

View File

@ -0,0 +1,6 @@
package d2interface
type ArchivedAnimationManager interface {
Cacher
LoadAnimation(animationPath, palettePath string, transparency int) (Animation, error)
}

View File

@ -0,0 +1,5 @@
package d2interface
type ArchivedPaletteManager interface {
LoadPalette(palettePath string) (Palette, error)
}

View File

@ -0,0 +1,22 @@
package d2interface
const numColors = 256
// Color represents a color
type Color interface {
R() uint8
G() uint8
B() uint8
A() uint8
RGBA() uint32
SetRGBA(uint32)
BGRA() uint32
SetBGRA(uint32)
}
// Palette is a color palette
type Palette interface {
NumColors() int
GetColors() [256]Color
GetColor(idx int) (Color, error)
}

View File

@ -8,10 +8,9 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
d2iface "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dc6"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dcc"
)
@ -32,7 +31,7 @@ type animationFrame struct {
offsetX int
offsetY int
image d2interface.Surface
image d2iface.Surface
}
type animationDirection struct {
@ -41,27 +40,25 @@ type animationDirection struct {
// Animation has directionality, play modes, and frame counting
type Animation struct {
directions []*animationDirection
frameIndex int
directionIndex int
lastFrameTime float64
playedCount int
compositeMode d2enum.CompositeMode
colorMod color.Color
originAtBottom bool
directions []*animationDirection
colorMod color.Color
frameIndex int
directionIndex int
lastFrameTime float64
playedCount int
compositeMode d2enum.CompositeMode
playMode playMode
playLength float64
playLoop bool
hasSubLoop bool // runs after first animation ends
subStartingFrame int
subEndingFrame int
originAtBottom bool
playLoop bool
hasSubLoop bool // runs after first animation ends
}
// CreateAnimationFromDCC creates an animation from d2dcc.DCC and d2dat.DATPalette
func CreateAnimationFromDCC(renderer d2interface.Renderer, dcc *d2dcc.DCC, palette *d2dat.DATPalette,
transparency int) (*Animation, error) {
func CreateAnimationFromDCC(renderer d2iface.Renderer, dcc *d2dcc.DCC, palette d2iface.Palette,
transparency int) (d2iface.Animation, error) {
animation := &Animation{
playLength: defaultPlayLength,
playLoop: true,
@ -87,18 +84,22 @@ func CreateAnimationFromDCC(renderer d2interface.Renderer, dcc *d2dcc.DCC, palet
for y := 0; y < frameHeight; y++ {
for x := 0; x < frameWidth; x++ {
if paletteIndex := dccFrame.PixelData[y*frameWidth+x]; paletteIndex != 0 {
palColor := palette.Colors[paletteIndex]
offset := (x + y*frameWidth) * bytesPerPixel
pixels[offset] = palColor.R
pixels[offset+1] = palColor.G
pixels[offset+2] = palColor.B
pixels[offset+3] = byte(transparency)
paletteIndex := dccFrame.PixelData[y*frameWidth+x]
if paletteIndex == 0 {
continue
}
palColor := palette.GetColors()[paletteIndex]
offset := (x + y*frameWidth) * bytesPerPixel
pixels[offset] = palColor.R()
pixels[offset+1] = palColor.G()
pixels[offset+2] = palColor.B()
pixels[offset+3] = byte(transparency)
}
}
sfc, err := renderer.NewSurface(frameWidth, frameHeight, d2interface.FilterNearest)
sfc, err := renderer.NewSurface(frameWidth, frameHeight, d2iface.FilterNearest)
if err != nil {
return nil, err
}
@ -126,7 +127,8 @@ func CreateAnimationFromDCC(renderer d2interface.Renderer, dcc *d2dcc.DCC, palet
}
// CreateAnimationFromDC6 creates an Animation from d2dc6.DC6 and d2dat.DATPalette
func CreateAnimationFromDC6(renderer d2interface.Renderer, dc6 *d2dc6.DC6, palette *d2dat.DATPalette) (*Animation, error) {
func CreateAnimationFromDC6(renderer d2iface.Renderer, dc6 *d2dc6.DC6,
palette d2iface.Palette) (d2iface.Animation, error) {
animation := &Animation{
playLength: defaultPlayLength,
playLoop: true,
@ -134,7 +136,8 @@ func CreateAnimationFromDC6(renderer d2interface.Renderer, dc6 *d2dc6.DC6, palet
}
for frameIndex, dc6Frame := range dc6.Frames {
sfc, err := renderer.NewSurface(int(dc6Frame.Width), int(dc6Frame.Height), d2interface.FilterNearest)
sfc, err := renderer.NewSurface(int(dc6Frame.Width), int(dc6Frame.Height),
d2iface.FilterNearest)
if err != nil {
return nil, err
}
@ -177,14 +180,16 @@ func CreateAnimationFromDC6(renderer d2interface.Renderer, dc6 *d2dc6.DC6, palet
colorData := make([]byte, int(dc6Frame.Width)*int(dc6Frame.Height)*bytesPerPixel)
for i := 0; i < int(dc6Frame.Width*dc6Frame.Height); i++ {
if indexData[i] < 1 { // TODO: Is this == -1 or < 1?
// TODO: Is this == -1 or < 1?
if indexData[i] < 1 {
continue
}
colorData[i*bytesPerPixel] = palette.Colors[indexData[i]].R
colorData[i*bytesPerPixel+1] = palette.Colors[indexData[i]].G
colorData[i*bytesPerPixel+2] = palette.Colors[indexData[i]].B
colorData[i*bytesPerPixel+3] = 0xff
c := palette.GetColors()[indexData[i]]
colorData[i*bytesPerPixel] = c.R()
colorData[i*bytesPerPixel+1] = c.G()
colorData[i*bytesPerPixel+2] = c.B()
colorData[i*bytesPerPixel+3] = c.A()
}
if err := sfc.ReplacePixels(colorData); err != nil {
@ -209,17 +214,20 @@ func CreateAnimationFromDC6(renderer d2interface.Renderer, dc6 *d2dc6.DC6, palet
return animation, nil
}
func (a *Animation) Clone() *Animation {
// Clone creates a copy of the animation
func (a *Animation) Clone() d2iface.Animation {
animation := *a
return &animation
}
func (a *Animation) SetSubLoop(startFrame, EndFrame int) {
// SetSubLoop sets a sub loop for the animation
func (a *Animation) SetSubLoop(startFrame, endFrame int) {
a.subStartingFrame = startFrame
a.subEndingFrame = EndFrame
a.subEndingFrame = endFrame
a.hasSubLoop = true
}
// Advance advances the animation state
func (a *Animation) Advance(elapsed float64) error {
if a.playMode == playModePause {
return nil
@ -234,6 +242,7 @@ func (a *Animation) Advance(elapsed float64) error {
for i := 0; i < framesAdvanced; i++ {
startIndex := 0
endIndex := frameCount
if a.hasSubLoop && a.playedCount > 0 {
startIndex = a.subStartingFrame
endIndex = a.subEndingFrame
@ -268,7 +277,8 @@ func (a *Animation) Advance(elapsed float64) error {
return nil
}
func (a *Animation) Render(target d2interface.Surface) error {
// Render renders the animation to the given surface
func (a *Animation) Render(target d2iface.Surface) error {
direction := a.directions[a.directionIndex]
frame := direction.frames[a.frameIndex]
@ -284,11 +294,13 @@ func (a *Animation) Render(target d2interface.Surface) error {
return target.Render(frame.image)
}
func (a *Animation) RenderFromOrigin(target d2interface.Surface) error {
// RenderFromOrigin renders the animation from the animation origin
func (a *Animation) RenderFromOrigin(target d2iface.Surface) error {
if a.originAtBottom {
direction := a.directions[a.directionIndex]
frame := direction.frames[a.frameIndex]
target.PushTranslation(0, -frame.height)
defer target.Pop()
}
@ -296,37 +308,40 @@ func (a *Animation) RenderFromOrigin(target d2interface.Surface) error {
}
// RenderSection renders the section of the animation frame enclosed by bounds
func (a *Animation) RenderSection(sfc d2interface.Surface, bound image.Rectangle) error {
func (a *Animation) RenderSection(sfc d2iface.Surface, bound image.Rectangle) error {
direction := a.directions[a.directionIndex]
frame := direction.frames[a.frameIndex]
sfc.PushTranslation(frame.offsetX, frame.offsetY)
sfc.PushCompositeMode(a.compositeMode)
sfc.PushColor(a.colorMod)
defer sfc.PopN(3)
return sfc.RenderSection(frame.image, bound)
}
// GetFrameSize gets the Size(width, height) of a indexed frame.
func (a *Animation) GetFrameSize(frameIndex int) (int, int, error) {
func (a *Animation) GetFrameSize(frameIndex int) (width, height int, err error) {
direction := a.directions[a.directionIndex]
if frameIndex >= len(direction.frames) {
return 0, 0, errors.New("invalid frame index")
}
frame := direction.frames[frameIndex]
return frame.width, frame.height, nil
}
// GetCurrentFrameSize gets the Size(width, height) of the current frame.
func (a *Animation) GetCurrentFrameSize() (int, int) {
width, height, _ := a.GetFrameSize(a.frameIndex)
func (a *Animation) GetCurrentFrameSize() (width, height int) {
width, height, _ = a.GetFrameSize(a.frameIndex)
return width, height
}
// GetFrameBounds gets maximum Size(width, height) of all frame.
func (a *Animation) GetFrameBounds() (int, int) {
maxWidth, maxHeight := 0, 0
func (a *Animation) GetFrameBounds() (maxWidth, maxHeight int) {
maxWidth, maxHeight = 0, 0
direction := a.directions[a.directionIndex]
for _, frame := range direction.frames {
@ -427,13 +442,15 @@ func (a *Animation) SetPlaySpeed(playSpeed float64) {
}
// SetPlayLength sets the Animation's play length in seconds
func (a *Animation) SetPlayLength(playLength float64) { // TODO refactor to use time.Duration instead of float64
func (a *Animation) SetPlayLength(playLength float64) {
// TODO refactor to use time.Duration instead of float64
a.playLength = playLength
a.lastFrameTime = 0
}
// SetPlayLengthMs sets the Animation's play length in milliseconds
func (a *Animation) SetPlayLengthMs(playLengthMs int) { // TODO remove this method
func (a *Animation) SetPlayLengthMs(playLengthMs int) {
// TODO remove this method
const millisecondsPerSecond = 1000.0
a.SetPlayLength(float64(playLengthMs) / millisecondsPerSecond)
}

View File

@ -19,6 +19,14 @@ type animationManager struct {
renderer d2interface.Renderer
}
func (am *animationManager) ClearCache() {
panic("implement me")
}
func (am *animationManager) GetCache() d2interface.Cache {
panic("implement me")
}
func createAnimationManager(renderer d2interface.Renderer) *animationManager {
return &animationManager{
renderer: renderer,
@ -26,13 +34,15 @@ func createAnimationManager(renderer d2interface.Renderer) *animationManager {
}
}
func (am *animationManager) loadAnimation(animationPath, palettePath string, transparency int) (*Animation, error) {
func (am *animationManager) LoadAnimation(
animationPath, palettePath string,
transparency int ) (d2interface.Animation, error) {
cachePath := fmt.Sprintf("%s;%s;%d", animationPath, palettePath, transparency)
if animation, found := am.cache.Retrieve(cachePath); found {
return animation.(*Animation).Clone(), nil
}
var animation *Animation
var animation d2interface.Animation
ext := strings.ToLower(filepath.Ext(animationPath))
switch ext {

View File

@ -10,9 +10,9 @@ import (
type assetManager struct {
archiveManager d2interface.ArchiveManager
archivedFileManager d2interface.ArchivedFileManager
paletteManager *paletteManager
paletteManager d2interface.ArchivedPaletteManager
paletteTransformManager *paletteTransformManager
animationManager *animationManager
animationManager d2interface.ArchivedAnimationManager
fontManager *fontManager
}

View File

@ -164,7 +164,7 @@ type compositeMode struct {
weaponClass string
playedCount int
layers []*Animation
layers []d2interface.Animation
frameCount int
frameIndex int
@ -194,7 +194,7 @@ func (c *Composite) createMode(animationMode, weaponClass string) (*compositeMod
cof: cof,
animationMode: animationMode,
weaponClass: weaponClass,
layers: make([]*Animation, d2enum.CompositeTypeMax),
layers: make([]d2interface.Animation, d2enum.CompositeTypeMax),
frameCount: animationData[0].FramesPerDirection,
animationSpeed: 1.0 / ((float64(animationData[0].AnimationSpeed) * 25.0) / 256.0),
}
@ -240,7 +240,7 @@ func (c *Composite) createMode(animationMode, weaponClass string) (*compositeMod
}
func (c *Composite) loadCompositeLayer(layerKey, layerValue, animationMode, weaponClass,
palettePath string, transparency int) (*Animation, error) {
palettePath string, transparency int) (d2interface.Animation, error) {
animationPaths := []string{
fmt.Sprintf("%s/%s/%s/%s%s%s%s%s.dcc", c.basePath, c.token, layerKey, c.token, layerKey, layerValue, animationMode, weaponClass),
fmt.Sprintf("%s/%s/%s/%s%s%s%s%s.dc6", c.basePath, c.token, layerKey, c.token, layerKey, layerValue, animationMode, weaponClass),

View File

@ -5,7 +5,6 @@ import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
)
@ -106,13 +105,14 @@ func FileExists(filePath string) (bool, error) {
}
// LoadAnimation loads an animation by its resource path and its palette path
func LoadAnimation(animationPath, palettePath string) (*Animation, error) {
func LoadAnimation(animationPath, palettePath string) (d2interface.Animation, error) {
return LoadAnimationWithTransparency(animationPath, palettePath, 255)
}
// LoadAnimationWithTransparency loads an animation by its resource path and its palette path with a given transparency value
func LoadAnimationWithTransparency(animationPath, palettePath string, transparency int) (*Animation, error) {
return singleton.animationManager.loadAnimation(animationPath, palettePath, transparency)
func LoadAnimationWithTransparency(animationPath, palettePath string,
transparency int) (d2interface.Animation, error) {
return singleton.animationManager.LoadAnimation(animationPath, palettePath, transparency)
}
// LoadComposite creates a composite object from a ObjectLookupRecord and palettePath describing it
@ -126,6 +126,6 @@ func LoadFont(tablePath, spritePath, palettePath string) (*Font, error) {
}
// LoadPalette loads a palette from a given palette path
func LoadPalette(palettePath string) (*d2dat.DATPalette, error) {
return singleton.paletteManager.loadPalette(palettePath)
func LoadPalette(palettePath string) (d2interface.Palette, error) {
return singleton.paletteManager.LoadPalette(palettePath)
}

View File

@ -19,7 +19,7 @@ type fontGlyph struct {
// Font represents a displayable font
type Font struct {
sheet *Animation
sheet d2interface.Animation
glyphs map[rune]fontGlyph
color color.Color
}

View File

@ -18,9 +18,9 @@ func createPaletteManager() *paletteManager {
return &paletteManager{d2common.CreateCache(paletteBudget)}
}
func (pm *paletteManager) loadPalette(palettePath string) (*d2dat.DATPalette, error) {
func (pm *paletteManager) LoadPalette(palettePath string) (d2interface.Palette, error) {
if palette, found := pm.cache.Retrieve(palettePath); found {
return palette.(*d2dat.DATPalette), nil
return palette.(d2interface.Palette), nil
}
paletteData, err := LoadFile(palettePath)

View File

@ -18,7 +18,8 @@ func loadFont(fontStyle FontStyle) (*d2asset.Font, error) {
return d2asset.LoadFont(config.fontBasePath+".tbl", config.fontBasePath+".dc6", config.palettePath)
}
func renderSegmented(animation *d2asset.Animation, segmentsX, segmentsY, frameOffset int, target d2interface.Surface) error {
func renderSegmented(animation d2interface.Animation, segmentsX, segmentsY, frameOffset int,
target d2interface.Surface) error {
var currentY int
for y := 0; y < segmentsY; y++ {
var currentX int

View File

@ -13,10 +13,10 @@ import (
type manager struct {
layout *Layout
cursorAnim *d2asset.Animation
cursorAnim d2interface.Animation
cursorX int
cursorY int
loadingAnim *d2asset.Animation
loadingAnim d2interface.Animation
cursorVisible bool
loading bool
}

View File

@ -19,7 +19,7 @@ type Sprite struct {
segmentsY int
frameOffset int
animation *d2asset.Animation
animation d2interface.Animation
}
type AnimatedSprite struct {

View File

@ -2,7 +2,6 @@ package d2mapentity
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
)
// AnimatedEntity represents an animation that can be projected onto the map.
@ -12,11 +11,11 @@ type AnimatedEntity struct {
action int
repetitions int
animation *d2asset.Animation
animation d2interface.Animation
}
// CreateAnimatedEntity creates an instance of AnimatedEntity
func CreateAnimatedEntity(x, y int, animation *d2asset.Animation) *AnimatedEntity {
func CreateAnimatedEntity(x, y int, animation d2interface.Animation) *AnimatedEntity {
entity := &AnimatedEntity{
mapEntity: createMapEntity(x, y),
animation: animation,

View File

@ -21,11 +21,11 @@ func (mr *MapRenderer) decodeTileGfxData(blocks []d2dt1.Block, pixels *[]byte, t
for n > 0 {
colorIndex := block.EncodedData[idx]
if colorIndex != 0 {
pixelColor := mr.palette.Colors[colorIndex]
pixelColor := mr.palette.GetColors()[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] = pixelColor.R()
(*pixels)[offset+1] = pixelColor.G()
(*pixels)[offset+2] = pixelColor.B()
(*pixels)[offset+3] = 255
}
x++
@ -58,12 +58,12 @@ func (mr *MapRenderer) decodeTileGfxData(blocks []d2dt1.Block, pixels *[]byte, t
for b2 > 0 {
colorIndex := block.EncodedData[idx]
if colorIndex != 0 {
pixelColor := mr.palette.Colors[colorIndex]
pixelColor := mr.palette.GetColors()[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] = pixelColor.R()
(*pixels)[offset+1] = pixelColor.G()
(*pixels)[offset+2] = pixelColor.B()
(*pixels)[offset+3] = 255
}

View File

@ -7,7 +7,6 @@ import (
"math"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
@ -19,7 +18,7 @@ import (
type MapRenderer struct {
renderer d2interface.Renderer // The renderer to use for drawing operations
mapEngine *d2mapengine.MapEngine // The map engine that is being rendered
palette *d2dat.DATPalette // The palette used for this map
palette d2interface.Palette // The palette used for this map
viewport *Viewport // The viewport for the map renderer (used for rendering offsets)
camera Camera // The camera for this map renderer (used to determine where on the map we are rendering)
debugVisLevel int // Debug visibility index (0=none, 1=tiles, 2=sub-tiles)
@ -354,7 +353,7 @@ func (mr *MapRenderer) Advance(elapsed float64) {
}
}
func loadPaletteForAct(levelType d2enum.RegionIdType) (*d2dat.DATPalette, error) {
func loadPaletteForAct(levelType d2enum.RegionIdType) (d2interface.Palette, error) {
var palettePath string
switch levelType {
case d2enum.RegionAct1Town, d2enum.RegionAct1Wilderness, d2enum.RegionAct1Cave, d2enum.RegionAct1Crypt,

View File

@ -8,21 +8,20 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
)
// Sprite is a positioned visual object.
type Sprite struct {
x int
y int
animation *d2asset.Animation
animation d2interface.Animation
}
var (
ErrNoAnimation = errors.New("no animation was specified")
)
func LoadSprite(animation *d2asset.Animation) (*Sprite, error) {
func LoadSprite(animation d2interface.Animation) (*Sprite, error) {
if animation == nil {
return nil, ErrNoAnimation
}