diff --git a/d2common/d2fileformats/d2dat/dat.go b/d2common/d2fileformats/d2dat/dat.go index 0c9677bd..217866f4 100644 --- a/d2common/d2fileformats/d2dat/dat.go +++ b/d2common/d2fileformats/d2dat/dat.go @@ -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 diff --git a/d2common/d2fileformats/d2dat/dat_color.go b/d2common/d2fileformats/d2dat/dat_color.go index 2af2b76a..c1c75904 100644 --- a/d2common/d2fileformats/d2dat/dat_color.go +++ b/d2common/d2fileformats/d2dat/dat_color.go @@ -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 & mask) + x = uint8(wxyz>>bitShift16 & mask) + y = uint8(wxyz>>bitShift8 & mask) + z = uint8(wxyz>>bitShift0 & mask) + return w, x, y, z +} + diff --git a/d2common/d2fileformats/d2dat/dat_palette.go b/d2common/d2fileformats/d2dat/dat_palette.go index 89535b5a..95e75f4e 100644 --- a/d2common/d2fileformats/d2dat/dat_palette.go +++ b/d2common/d2fileformats/d2dat/dat_palette.go @@ -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) } diff --git a/d2common/d2interface/animation.go b/d2common/d2interface/animation.go new file mode 100644 index 00000000..b5b2cd6e --- /dev/null +++ b/d2common/d2interface/animation.go @@ -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) +} diff --git a/d2common/d2interface/archived_animation_manager.go b/d2common/d2interface/archived_animation_manager.go new file mode 100644 index 00000000..3315f128 --- /dev/null +++ b/d2common/d2interface/archived_animation_manager.go @@ -0,0 +1,6 @@ +package d2interface + +type ArchivedAnimationManager interface { + Cacher + LoadAnimation(animationPath, palettePath string, transparency int) (Animation, error) +} diff --git a/d2common/d2interface/archived_palette_manager.go b/d2common/d2interface/archived_palette_manager.go new file mode 100644 index 00000000..c7a3097a --- /dev/null +++ b/d2common/d2interface/archived_palette_manager.go @@ -0,0 +1,5 @@ +package d2interface + +type ArchivedPaletteManager interface { + LoadPalette(palettePath string) (Palette, error) +} diff --git a/d2common/d2interface/palette.go b/d2common/d2interface/palette.go new file mode 100644 index 00000000..927be9af --- /dev/null +++ b/d2common/d2interface/palette.go @@ -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) +} diff --git a/d2core/d2asset/animation.go b/d2core/d2asset/animation.go index d7dfd40c..b2d94ff8 100644 --- a/d2core/d2asset/animation.go +++ b/d2core/d2asset/animation.go @@ -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) } diff --git a/d2core/d2asset/animation_manager.go b/d2core/d2asset/animation_manager.go index 94ed24b8..9226205c 100644 --- a/d2core/d2asset/animation_manager.go +++ b/d2core/d2asset/animation_manager.go @@ -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 { diff --git a/d2core/d2asset/asset_manager.go b/d2core/d2asset/asset_manager.go index b846248a..f372c933 100644 --- a/d2core/d2asset/asset_manager.go +++ b/d2core/d2asset/asset_manager.go @@ -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 } diff --git a/d2core/d2asset/composite.go b/d2core/d2asset/composite.go index c3d349ab..6cb941d2 100644 --- a/d2core/d2asset/composite.go +++ b/d2core/d2asset/composite.go @@ -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), diff --git a/d2core/d2asset/d2asset.go b/d2core/d2asset/d2asset.go index f0fb12c8..dfbde880 100644 --- a/d2core/d2asset/d2asset.go +++ b/d2core/d2asset/d2asset.go @@ -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) } diff --git a/d2core/d2asset/font.go b/d2core/d2asset/font.go index 783a1fbd..8a539b81 100644 --- a/d2core/d2asset/font.go +++ b/d2core/d2asset/font.go @@ -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 } diff --git a/d2core/d2asset/palette_manager.go b/d2core/d2asset/palette_manager.go index cc9d2972..0b72a92d 100644 --- a/d2core/d2asset/palette_manager.go +++ b/d2core/d2asset/palette_manager.go @@ -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) diff --git a/d2core/d2gui/common.go b/d2core/d2gui/common.go index 656ca35b..30569721 100644 --- a/d2core/d2gui/common.go +++ b/d2core/d2gui/common.go @@ -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 diff --git a/d2core/d2gui/manager.go b/d2core/d2gui/manager.go index 5eef7ab1..f53f2cff 100644 --- a/d2core/d2gui/manager.go +++ b/d2core/d2gui/manager.go @@ -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 } diff --git a/d2core/d2gui/sprite.go b/d2core/d2gui/sprite.go index 44dbb549..89acc7d0 100644 --- a/d2core/d2gui/sprite.go +++ b/d2core/d2gui/sprite.go @@ -19,7 +19,7 @@ type Sprite struct { segmentsY int frameOffset int - animation *d2asset.Animation + animation d2interface.Animation } type AnimatedSprite struct { diff --git a/d2core/d2map/d2mapentity/animated_entity.go b/d2core/d2map/d2mapentity/animated_entity.go index 121c4ebd..05cf7a16 100644 --- a/d2core/d2map/d2mapentity/animated_entity.go +++ b/d2core/d2map/d2mapentity/animated_entity.go @@ -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, diff --git a/d2core/d2map/d2maprenderer/gfx_decode.go b/d2core/d2map/d2maprenderer/gfx_decode.go index 7b5bf62f..f8efe397 100644 --- a/d2core/d2map/d2maprenderer/gfx_decode.go +++ b/d2core/d2map/d2maprenderer/gfx_decode.go @@ -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 } diff --git a/d2core/d2map/d2maprenderer/renderer.go b/d2core/d2map/d2maprenderer/renderer.go index 632961f7..0d2a67a7 100644 --- a/d2core/d2map/d2maprenderer/renderer.go +++ b/d2core/d2map/d2maprenderer/renderer.go @@ -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, diff --git a/d2core/d2ui/sprite.go b/d2core/d2ui/sprite.go index ad71d3c0..675147ed 100644 --- a/d2core/d2ui/sprite.go +++ b/d2core/d2ui/sprite.go @@ -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 }