mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-18 02:16:23 -05:00
first pass at resolving linting issues in d2asset (#518)
This commit is contained in:
parent
973e969002
commit
c8ec4c018e
@ -26,6 +26,8 @@ const (
|
||||
playModeBackward
|
||||
)
|
||||
|
||||
const defaultPlayLength = 1.0
|
||||
|
||||
type animationFrame struct {
|
||||
width int
|
||||
height int
|
||||
@ -59,9 +61,10 @@ type Animation struct {
|
||||
subEndingFrame int
|
||||
}
|
||||
|
||||
// CreateAnimationFromDCC creates an animation from d2dcc.DCC and d2dat.DATPalette
|
||||
func CreateAnimationFromDCC(dcc *d2dcc.DCC, palette *d2dat.DATPalette, transparency int) (*Animation, error) {
|
||||
animation := &Animation{
|
||||
playLength: 1.0,
|
||||
playLength: defaultPlayLength,
|
||||
playLoop: true,
|
||||
}
|
||||
|
||||
@ -80,14 +83,14 @@ func CreateAnimationFromDCC(dcc *d2dcc.DCC, palette *d2dat.DATPalette, transpare
|
||||
frameWidth := maxX - minX
|
||||
frameHeight := maxY - minY
|
||||
|
||||
pixels := make([]byte, frameWidth*frameHeight*4)
|
||||
const bytesPerPixel = 4
|
||||
pixels := make([]byte, frameWidth*frameHeight*bytesPerPixel)
|
||||
|
||||
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) * 4
|
||||
offset := (x + y*frameWidth) * bytesPerPixel
|
||||
pixels[offset] = palColor.R
|
||||
pixels[offset+1] = palColor.G
|
||||
pixels[offset+2] = palColor.B
|
||||
@ -123,9 +126,10 @@ func CreateAnimationFromDCC(dcc *d2dcc.DCC, palette *d2dat.DATPalette, transpare
|
||||
return animation, nil
|
||||
}
|
||||
|
||||
// CreateAnimationFromDC6 creates an Animation from d2dc6.DC6 and d2dat.DATPalette
|
||||
func CreateAnimationFromDC6(dc6 *d2dc6.DC6, palette *d2dat.DATPalette) (*Animation, error) {
|
||||
animation := &Animation{
|
||||
playLength: 1.0,
|
||||
playLength: defaultPlayLength,
|
||||
playLoop: true,
|
||||
originAtBottom: true,
|
||||
}
|
||||
@ -170,17 +174,18 @@ func CreateAnimationFromDC6(dc6 *d2dc6.DC6, palette *d2dat.DATPalette) (*Animati
|
||||
}
|
||||
}
|
||||
|
||||
colorData := make([]byte, dc6Frame.Width*dc6Frame.Height*4)
|
||||
bytesPerPixel := 4
|
||||
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?
|
||||
continue
|
||||
}
|
||||
|
||||
colorData[i*4] = palette.Colors[indexData[i]].R
|
||||
colorData[i*4+1] = palette.Colors[indexData[i]].G
|
||||
colorData[i*4+2] = palette.Colors[indexData[i]].B
|
||||
colorData[i*4+3] = 0xff
|
||||
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
|
||||
}
|
||||
|
||||
if err := sfc.ReplacePixels(colorData); err != nil {
|
||||
@ -269,9 +274,14 @@ func (a *Animation) Render(target d2interface.Surface) error {
|
||||
frame := direction.frames[a.frameIndex]
|
||||
|
||||
target.PushTranslation(frame.offsetX, frame.offsetY)
|
||||
defer target.Pop()
|
||||
|
||||
target.PushCompositeMode(a.compositeMode)
|
||||
defer target.Pop()
|
||||
|
||||
target.PushColor(a.colorMod)
|
||||
defer target.PopN(3)
|
||||
defer target.Pop()
|
||||
|
||||
return target.Render(frame.image)
|
||||
}
|
||||
|
||||
@ -356,9 +366,11 @@ func (a *Animation) GetDirectionCount() int {
|
||||
|
||||
// SetDirection places the animation in the direction of an animation
|
||||
func (a *Animation) SetDirection(directionIndex int) error {
|
||||
if directionIndex >= 64 {
|
||||
const smallestInvalidDirectionIndex = 64
|
||||
if directionIndex >= smallestInvalidDirectionIndex {
|
||||
return errors.New("invalid direction index")
|
||||
}
|
||||
|
||||
a.directionIndex = d2dcc.Dir64ToDcc(directionIndex, len(a.directions))
|
||||
a.frameIndex = 0
|
||||
|
||||
@ -378,6 +390,7 @@ func (a *Animation) SetCurrentFrame(frameIndex int) error {
|
||||
|
||||
a.frameIndex = frameIndex
|
||||
a.lastFrameTime = 0
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -414,17 +427,21 @@ func (a *Animation) SetPlaySpeed(playSpeed float64) {
|
||||
a.SetPlayLength(playSpeed * float64(a.GetFrameCount()))
|
||||
}
|
||||
|
||||
func (a *Animation) SetPlayLength(playLength 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
|
||||
a.playLength = playLength
|
||||
a.lastFrameTime = 0
|
||||
}
|
||||
|
||||
func (a *Animation) SetPlayLengthMs(playLengthMs int) {
|
||||
a.SetPlayLength(float64(playLengthMs) / 1000.0)
|
||||
// SetPlayLengthMs sets the Animation's play length in milliseconds
|
||||
func (a *Animation) SetPlayLengthMs(playLengthMs int) { // TODO remove this method
|
||||
const millisecondsPerSecond = 1000.0
|
||||
a.SetPlayLength(float64(playLengthMs) / millisecondsPerSecond)
|
||||
}
|
||||
|
||||
func (a *Animation) SetColorMod(color color.Color) {
|
||||
a.colorMod = color
|
||||
// SetColorMod sets the Animation's color mod
|
||||
func (a *Animation) SetColorMod(colorMod color.Color) {
|
||||
a.colorMod = colorMod
|
||||
}
|
||||
|
||||
// GetPlayedCount gets the number of times the application played
|
||||
@ -437,7 +454,7 @@ func (a *Animation) ResetPlayedCount() {
|
||||
a.playedCount = 0
|
||||
}
|
||||
|
||||
// SetBlend sets the animation alpha blending status
|
||||
// SetBlend sets the Animation alpha blending status
|
||||
func (a *Animation) SetBlend(blend bool) {
|
||||
if blend {
|
||||
a.compositeMode = d2enum.CompositeModeLighter
|
||||
|
@ -27,6 +27,7 @@ func (am *animationManager) loadAnimation(animationPath, palettePath string, tra
|
||||
}
|
||||
|
||||
var animation *Animation
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(animationPath))
|
||||
switch ext {
|
||||
case ".dc6":
|
||||
|
@ -17,7 +17,7 @@ type archiveEntry struct {
|
||||
|
||||
type archiveManager struct {
|
||||
cache *d2common.Cache
|
||||
config d2config.Configuration
|
||||
config *d2config.Configuration
|
||||
entries []archiveEntry
|
||||
mutex sync.Mutex
|
||||
}
|
||||
@ -26,7 +26,7 @@ const (
|
||||
archiveBudget = 1024 * 1024 * 512
|
||||
)
|
||||
|
||||
func createArchiveManager(config d2config.Configuration) *archiveManager {
|
||||
func createArchiveManager(config *d2config.Configuration) *archiveManager {
|
||||
return &archiveManager{cache: d2common.CreateCache(archiveBudget), config: config}
|
||||
}
|
||||
|
||||
@ -93,6 +93,7 @@ func (am *archiveManager) cacheArchiveEntries() error {
|
||||
|
||||
for _, archiveName := range am.config.MpqLoadOrder {
|
||||
archivePath := path.Join(am.config.MpqPath, archiveName)
|
||||
|
||||
archive, err := am.loadArchive(archivePath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -1,18 +1,11 @@
|
||||
package d2asset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2cof"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dc6"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dcc"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrWasInit = errors.New("asset system is already initialized")
|
||||
ErrNotInit = errors.New("asset system is not initialized")
|
||||
)
|
||||
|
||||
type assetManager struct {
|
||||
archiveManager *archiveManager
|
||||
fileManager *fileManager
|
||||
|
@ -5,24 +5,26 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2cof"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2cof"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
// Composite is a composite entity animation
|
||||
type Composite struct {
|
||||
object *d2datadict.ObjectLookupRecord
|
||||
palettePath string
|
||||
mode *compositeMode
|
||||
}
|
||||
|
||||
// CreateComposite creates a Composite from a given ObjectLookupRecord and palettePath.
|
||||
func CreateComposite(object *d2datadict.ObjectLookupRecord, palettePath string) *Composite {
|
||||
return &Composite{object: object, palettePath: palettePath}
|
||||
}
|
||||
|
||||
// Advance moves the composite animation forward for a given elapsed time in nanoseconds.
|
||||
func (c *Composite) Advance(elapsed float64) error {
|
||||
if c.mode == nil {
|
||||
return nil
|
||||
@ -46,6 +48,7 @@ func (c *Composite) Advance(elapsed float64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Render performs drawing of the Composite on the rendered d2interface.Surface.
|
||||
func (c *Composite) Render(target d2interface.Surface) error {
|
||||
if c.mode == nil {
|
||||
return nil
|
||||
@ -63,10 +66,12 @@ func (c *Composite) Render(target d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAnimationMode returns the animation mode the Composite should render with.
|
||||
func (c Composite) GetAnimationMode() string {
|
||||
return c.mode.animationMode
|
||||
}
|
||||
|
||||
// SetMode sets the Composite's animation mode weapon class and direction
|
||||
func (c *Composite) SetMode(animationMode, weaponClass string, direction int) error {
|
||||
if c.mode != nil && c.mode.animationMode == animationMode && c.mode.weaponClass == weaponClass && c.mode.cofDirection == direction {
|
||||
return nil
|
||||
@ -77,11 +82,13 @@ func (c *Composite) SetMode(animationMode, weaponClass string, direction int) er
|
||||
return err
|
||||
}
|
||||
|
||||
c.ResetPlayedCount()
|
||||
c.resetPlayedCount()
|
||||
c.mode = mode
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSpeed sets the speed at which the Composite's animation should advance through its frames
|
||||
func (c *Composite) SetSpeed(speed int) {
|
||||
c.mode.animationSpeed = 1.0 / ((float64(speed) * 25.0) / 256.0)
|
||||
for layerIdx := range c.mode.layers {
|
||||
@ -92,6 +99,7 @@ func (c *Composite) SetSpeed(speed int) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetDirectionCount returns the Composites number of available animated directions
|
||||
func (c *Composite) GetDirectionCount() int {
|
||||
if c.mode == nil {
|
||||
return 0
|
||||
@ -100,6 +108,7 @@ func (c *Composite) GetDirectionCount() int {
|
||||
return c.mode.directionCount
|
||||
}
|
||||
|
||||
// GetPlayedCount returns the number of times the current animation mode has completed all its distinct frames
|
||||
func (c *Composite) GetPlayedCount() int {
|
||||
if c.mode == nil {
|
||||
return 0
|
||||
@ -108,7 +117,7 @@ func (c *Composite) GetPlayedCount() int {
|
||||
return c.mode.playedCount
|
||||
}
|
||||
|
||||
func (c *Composite) ResetPlayedCount() {
|
||||
func (c *Composite) resetPlayedCount() {
|
||||
if c.mode != nil {
|
||||
c.mode.playedCount = 0
|
||||
}
|
||||
@ -117,7 +126,7 @@ func (c *Composite) ResetPlayedCount() {
|
||||
type compositeMode struct {
|
||||
animationMode string
|
||||
weaponClass string
|
||||
cofDirection int
|
||||
cofDirection int
|
||||
directionCount int
|
||||
playedCount int
|
||||
|
||||
@ -142,6 +151,7 @@ func (c *Composite) createMode(animationMode, weaponClass string, direction int)
|
||||
}
|
||||
|
||||
animationKey := strings.ToLower(c.object.Token + animationMode + weaponClass)
|
||||
|
||||
animationData := d2data.AnimationData[animationKey]
|
||||
if len(animationData) == 0 {
|
||||
return nil, errors.New("could not find animation data")
|
||||
@ -222,7 +232,9 @@ func (c *Composite) createMode(animationMode, weaponClass string, direction int)
|
||||
layer.SetPlaySpeed(mode.animationSpeed)
|
||||
layer.PlayForward()
|
||||
layer.SetBlend(blend)
|
||||
layer.SetDirection(direction)
|
||||
if err := layer.SetDirection(direction); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mode.layers[cofLayer.Type] = layer
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
/*
|
||||
Package d2asset has behaviors to load and save assets from disk.
|
||||
*/
|
||||
package d2asset
|
||||
|
||||
import (
|
||||
@ -8,19 +11,17 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2pl2"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
)
|
||||
|
||||
var singleton *assetManager
|
||||
|
||||
// Initialize creates and assigns all necessary dependencies for the assetManager top-level functions to work correctly
|
||||
func Initialize(term d2interface.Terminal) error {
|
||||
verifyNotInit()
|
||||
|
||||
var (
|
||||
config = d2config.Get()
|
||||
archiveManager = createArchiveManager(config)
|
||||
fileManager = createFileManager(config, archiveManager)
|
||||
archiveManager = createArchiveManager(&config)
|
||||
fileManager = createFileManager(&config, archiveManager)
|
||||
paletteManager = createPaletteManager()
|
||||
paletteTransformManager = createPaletteTransformManager()
|
||||
animationManager = createAnimationManager()
|
||||
@ -36,7 +37,7 @@ func Initialize(term d2interface.Terminal) error {
|
||||
fontManager,
|
||||
}
|
||||
|
||||
term.BindAction("assetspam", "display verbose asset manager logs", func(verbose bool) {
|
||||
if err := term.BindAction("assetspam", "display verbose asset manager logs", func(verbose bool) {
|
||||
if verbose {
|
||||
term.OutputInfof("asset manager verbose logging enabled")
|
||||
} else {
|
||||
@ -48,41 +49,47 @@ func Initialize(term d2interface.Terminal) error {
|
||||
paletteManager.cache.SetVerbose(verbose)
|
||||
paletteTransformManager.cache.SetVerbose(verbose)
|
||||
animationManager.cache.SetVerbose(verbose)
|
||||
})
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
term.BindAction("assetstat", "display asset manager cache statistics", func() {
|
||||
term.OutputInfof("archive cache: %f", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfof("file cache: %f", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfof("palette cache: %f", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfof("palette transform cache: %f", float64(paletteTransformManager.cache.GetWeight())/float64(paletteTransformManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfof("animation cache: %f", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
|
||||
term.OutputInfof("font cache: %f", float64(fontManager.cache.GetWeight())/float64(fontManager.cache.GetBudget())*100.0)
|
||||
})
|
||||
if err := term.BindAction("assetstat", "display asset manager cache statistics", func() {
|
||||
type cache interface {
|
||||
GetWeight() int
|
||||
GetBudget() int
|
||||
}
|
||||
|
||||
term.BindAction("assetclear", "clear asset manager cache", func() {
|
||||
var cacheStatistics = func(c cache) float64 {
|
||||
const percent = 100.0
|
||||
return float64(c.GetWeight()) / float64(c.GetBudget()) * percent
|
||||
}
|
||||
|
||||
term.OutputInfof("archive cache: %f", cacheStatistics(archiveManager.cache))
|
||||
term.OutputInfof("file cache: %f", cacheStatistics(fileManager.cache))
|
||||
term.OutputInfof("palette cache: %f", cacheStatistics(paletteManager.cache))
|
||||
term.OutputInfof("palette transform cache: %f", cacheStatistics(paletteTransformManager.cache))
|
||||
term.OutputInfof("animation cache: %f", cacheStatistics(animationManager.cache))
|
||||
term.OutputInfof("font cache: %f", cacheStatistics(fontManager.cache))
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := term.BindAction("assetclear", "clear asset manager cache", func() {
|
||||
archiveManager.cache.Clear()
|
||||
fileManager.cache.Clear()
|
||||
paletteManager.cache.Clear()
|
||||
paletteTransformManager.cache.Clear()
|
||||
animationManager.cache.Clear()
|
||||
fontManager.cache.Clear()
|
||||
})
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Shutdown() {
|
||||
singleton = nil
|
||||
}
|
||||
|
||||
func LoadArchive(archivePath string) (*d2mpq.MPQ, error) {
|
||||
verifyWasInit()
|
||||
return singleton.archiveManager.loadArchive(archivePath)
|
||||
}
|
||||
|
||||
// LoadFileStream streams an MPQ file from a source file path
|
||||
func LoadFileStream(filePath string) (*d2mpq.MpqDataStream, error) {
|
||||
verifyWasInit()
|
||||
|
||||
data, err := singleton.fileManager.loadFileStream(filePath)
|
||||
if err != nil {
|
||||
log.Printf("error loading file stream %s (%v)", filePath, err.Error())
|
||||
@ -91,9 +98,8 @@ func LoadFileStream(filePath string) (*d2mpq.MpqDataStream, error) {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// LoadFile loads an entire file from a source file path as a []byte
|
||||
func LoadFile(filePath string) ([]byte, error) {
|
||||
verifyWasInit()
|
||||
|
||||
data, err := singleton.fileManager.loadFile(filePath)
|
||||
if err != nil {
|
||||
log.Printf("error loading file %s (%v)", filePath, err.Error())
|
||||
@ -102,49 +108,32 @@ func LoadFile(filePath string) ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// FileExists checks if a file exists on the underlying file system at the given file path.
|
||||
func FileExists(filePath string) (bool, error) {
|
||||
verifyWasInit()
|
||||
return singleton.fileManager.fileExists(filePath)
|
||||
}
|
||||
|
||||
// LoadAnimation loads an animation by its resource path and its palette path
|
||||
func LoadAnimation(animationPath, palettePath string) (*Animation, error) {
|
||||
verifyWasInit()
|
||||
return LoadAnimationWithTransparency(animationPath, palettePath, 255)
|
||||
}
|
||||
|
||||
func LoadPaletteTransform(pl2Path string) (*d2pl2.PL2, error) {
|
||||
verifyWasInit()
|
||||
return singleton.paletteTransformManager.loadPaletteTransform(pl2Path)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
verifyWasInit()
|
||||
return singleton.animationManager.loadAnimation(animationPath, palettePath, transparency)
|
||||
}
|
||||
|
||||
// LoadComposite creates a composite object from a ObjectLookupRecord and palettePath describing it
|
||||
func LoadComposite(object *d2datadict.ObjectLookupRecord, palettePath string) (*Composite, error) {
|
||||
verifyWasInit()
|
||||
return CreateComposite(object, palettePath), nil
|
||||
}
|
||||
|
||||
// LoadFont loads a font the resource files
|
||||
func LoadFont(tablePath, spritePath, palettePath string) (*Font, error) {
|
||||
verifyWasInit()
|
||||
return singleton.fontManager.loadFont(tablePath, spritePath, palettePath)
|
||||
}
|
||||
|
||||
// LoadPalette loads a palette from a given palette path
|
||||
func LoadPalette(palettePath string) (*d2dat.DATPalette, error) {
|
||||
verifyWasInit()
|
||||
return singleton.paletteManager.loadPalette(palettePath)
|
||||
}
|
||||
|
||||
func verifyWasInit() {
|
||||
if singleton == nil {
|
||||
panic(ErrNotInit)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyNotInit() {
|
||||
if singleton != nil {
|
||||
panic(ErrWasInit)
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,13 @@ const (
|
||||
type fileManager struct {
|
||||
cache *d2common.Cache
|
||||
archiveManager *archiveManager
|
||||
config d2config.Configuration
|
||||
config *d2config.Configuration
|
||||
}
|
||||
|
||||
func createFileManager(config d2config.Configuration, archiveManager *archiveManager) *fileManager {
|
||||
func createFileManager(config *d2config.Configuration, archiveManager *archiveManager) *fileManager {
|
||||
return &fileManager{d2common.CreateCache(fileBudget), archiveManager, config}
|
||||
}
|
||||
|
||||
|
||||
func (fm *fileManager) loadFileStream(filePath string) (*d2mpq.MpqDataStream, error) {
|
||||
filePath = fm.fixupFilePath(filePath)
|
||||
|
||||
|
@ -17,6 +17,7 @@ type fontGlyph struct {
|
||||
height int
|
||||
}
|
||||
|
||||
// Font represents a displayable font
|
||||
type Font struct {
|
||||
sheet *Animation
|
||||
glyphs map[rune]fontGlyph
|
||||
@ -47,7 +48,7 @@ func loadFont(tablePath, spritePath, palettePath string) (*Font, error) {
|
||||
var glyph fontGlyph
|
||||
glyph.frame = int(binary.LittleEndian.Uint16(data[i+8 : i+10]))
|
||||
glyph.width = int(data[i+3])
|
||||
glyph.height = maxCharHeight // int(data[i+4])
|
||||
glyph.height = maxCharHeight
|
||||
|
||||
glyphs[code] = glyph
|
||||
}
|
||||
@ -61,11 +62,12 @@ func loadFont(tablePath, spritePath, palettePath string) (*Font, error) {
|
||||
return font, nil
|
||||
}
|
||||
|
||||
func (f *Font) SetColor(color color.Color) {
|
||||
f.color = color
|
||||
func (f *Font) SetColor(c color.Color) {
|
||||
f.color = c
|
||||
}
|
||||
|
||||
func (f *Font) GetTextMetrics(text string) (int, int) {
|
||||
// GetTextMetrics returns the dimensions of the Font element in pixels
|
||||
func (f *Font) GetTextMetrics(text string) (width, height int) {
|
||||
var (
|
||||
lineWidth int
|
||||
lineHeight int
|
||||
@ -91,6 +93,7 @@ func (f *Font) GetTextMetrics(text string) (int, int) {
|
||||
return totalWidth, totalHeight
|
||||
}
|
||||
|
||||
// Clone creates a shallow copy of the Font
|
||||
func (f *Font) Clone() *Font {
|
||||
return &Font{
|
||||
sheet: f.sheet,
|
||||
@ -99,6 +102,7 @@ func (f *Font) Clone() *Font {
|
||||
}
|
||||
}
|
||||
|
||||
// RenderText draws a string of text in a style described by Font onto the d2interface.Surface
|
||||
func (f *Font) RenderText(text string, target d2interface.Surface) error {
|
||||
f.sheet.SetColorMod(f.color)
|
||||
f.sheet.SetBlend(false)
|
||||
@ -112,13 +116,23 @@ func (f *Font) RenderText(text string, target d2interface.Surface) error {
|
||||
)
|
||||
|
||||
for _, c := range line {
|
||||
if glyph, ok := f.glyphs[c]; ok {
|
||||
f.sheet.SetCurrentFrame(glyph.frame)
|
||||
f.sheet.Render(target)
|
||||
lineHeight = d2common.MaxInt(lineHeight, glyph.height)
|
||||
target.PushTranslation(glyph.width, 0)
|
||||
lineLength++
|
||||
glyph, ok := f.glyphs[c]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := f.sheet.SetCurrentFrame(glyph.frame); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.sheet.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lineHeight = d2common.MaxInt(lineHeight, glyph.height)
|
||||
lineLength++
|
||||
|
||||
target.PushTranslation(glyph.width, 0)
|
||||
}
|
||||
|
||||
target.PopN(lineLength)
|
||||
|
@ -32,6 +32,9 @@ func (pm *paletteManager) loadPalette(palettePath string) (*d2dat.DATPalette, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pm.cache.Insert(palettePath, palette, 1)
|
||||
if err := pm.cache.Insert(palettePath, palette, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return palette, nil
|
||||
}
|
||||
|
@ -32,6 +32,9 @@ func (pm *paletteTransformManager) loadPaletteTransform(path string) (*d2pl2.PL2
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pm.cache.Insert(path, pl2, 1)
|
||||
if err := pm.cache.Insert(path, pl2, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pl2, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user