package d2ui import ( "log" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" ) type UIFrame struct { asset *d2asset.AssetManager uiManager *UIManager frame *Sprite originX int originY int frameOrientation FrameOrientation } type FrameOrientation = int const ( FrameLeft FrameOrientation = iota FrameRight ) // frame indices into dc6 images for panels const ( leftFrameTopLeft = iota leftFrameTopRight leftFrameMiddleRight leftFrameBottomLeft leftFrameBottomRight rightFrameTopLeft rightFrameTopRight rightFrameMiddleRight rightFrameBottomRight rightFrameBottomLeft ) type offsetCalcFn = func(u *UIFrame) (x, y int) func NewUIFrame( asset *d2asset.AssetManager, uiManager *UIManager, frameOrientation FrameOrientation, ) *UIFrame { var originX, originY = 0, 0 switch frameOrientation { case FrameLeft: originX = 0 originY = 0 case FrameRight: originX = 400 originY = 0 } frame := &UIFrame{ asset: asset, uiManager: uiManager, frameOrientation: frameOrientation, originX: originX, originY: originY, } frame.Load() return frame } func (u *UIFrame) Load() { sprite, err := u.uiManager.NewSprite(d2resource.Frame, d2resource.PaletteSky) if err != nil { log.Print(err) } u.frame = sprite } func (u *UIFrame) Render(target d2interface.Surface) error { switch u.frameOrientation { case FrameLeft: return u.renderLeft(target) case FrameRight: return u.renderRight(target) } return nil } func (u *UIFrame) renderLeft(target d2interface.Surface) error { // the frame pieces we are interested in. framePieces := []int{ leftFrameTopLeft, leftFrameTopRight, leftFrameMiddleRight, leftFrameBottomLeft, leftFrameBottomRight, } // the frame coordinates coord := make(map[int]*struct{ x, y int }) startX, startY := u.originX, u.originY currentX, currentY := startX, startY // first determine the coordinates for each frame // the order that we check is important for _, piece := range framePieces { width, height, err := u.frame.GetFrameSize(piece) if err != nil { return err } c := &struct{ x, y int }{} switch piece { case leftFrameTopLeft: c.x, c.y = currentX, currentY+height currentX, currentY = currentX+width, currentY+height case leftFrameTopRight: c.x, c.y = currentX, startY+height currentX = startX case leftFrameMiddleRight: c.x, c.y = currentX, currentY+height currentY += height case leftFrameBottomLeft: c.x, c.y = currentX, currentY+height currentX += width case leftFrameBottomRight: c.x, c.y = currentX, currentY+height } coord[piece] = c } // now render the pieces with the coordinates for idx, c := range coord { err := u.renderFramePiece(target, c.x, c.y, idx) if err != nil { return err } } return nil } func (u *UIFrame) renderRight(target d2interface.Surface) error { // the frame pieces we are interested in. framePieces := []int{ rightFrameTopLeft, rightFrameTopRight, rightFrameMiddleRight, rightFrameBottomRight, rightFrameBottomLeft, } // the frame coordinates coord := make(map[int]*struct{ x, y int }) startX, startY := u.originX, u.originY currentX, currentY := startX, startY // first determine the coordinates for each frame // the order that we check is important for _, piece := range framePieces { width, height, err := u.frame.GetFrameSize(piece) if err != nil { return err } c := &struct{ x, y int }{} switch piece { case rightFrameTopLeft: c.x, c.y = currentX, currentY+height currentX += width case rightFrameTopRight: c.x, c.y = currentX, currentY+height currentX += width currentY += height case rightFrameMiddleRight: c.x, c.y = currentX-width, currentY+height currentY += height case rightFrameBottomRight: c.x, c.y = currentX-width, currentY+height currentX -= width case rightFrameBottomLeft: c.x, c.y = currentX-width, currentY+height currentX += width } coord[piece] = c } // now render the pieces with the coordinates for idx, c := range coord { err := u.renderFramePiece(target, c.x, c.y, idx) if err != nil { return err } } return nil } func (u *UIFrame) GetFrameBounds() (width, height int) { return u.frame.GetFrameBounds() } func (u *UIFrame) GetFrameCount() int { return u.frame.GetFrameCount() } func (u *UIFrame) renderFramePiece(sfc d2interface.Surface, x, y, idx int) error { if err := u.frame.SetCurrentFrame(idx); err != nil { return err } u.frame.SetPosition(x, y) if err := u.frame.Render(sfc); err != nil { return err } return nil }