2021-02-08 07:21:50 -05:00
|
|
|
package d2font
|
2020-02-17 22:11:52 -05:00
|
|
|
|
|
|
|
import (
|
2021-02-08 07:21:50 -05:00
|
|
|
"fmt"
|
2020-02-17 22:11:52 -05:00
|
|
|
"image/color"
|
|
|
|
"strings"
|
|
|
|
|
2021-02-08 08:11:51 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
2020-07-13 09:05:04 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
2020-08-11 18:01:33 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
2020-02-17 22:11:52 -05:00
|
|
|
)
|
|
|
|
|
2021-02-08 09:03:59 -05:00
|
|
|
const (
|
|
|
|
knownSignature = "Woo!\x01"
|
|
|
|
)
|
|
|
|
|
2021-02-08 11:25:02 -05:00
|
|
|
const (
|
|
|
|
signatureBytesCount = 5
|
|
|
|
unknownHeaderBytesCount = 7
|
|
|
|
unknown1BytesCount = 1
|
2021-02-09 02:43:46 -05:00
|
|
|
unknown2BytesCount = 3
|
2021-02-08 11:25:02 -05:00
|
|
|
unknown3BytesCount = 4
|
|
|
|
)
|
|
|
|
|
2021-02-17 03:05:29 -05:00
|
|
|
// FontGlyph represents a single font glyph
|
|
|
|
type FontGlyph struct {
|
2021-02-08 09:03:59 -05:00
|
|
|
unknown1 []byte
|
|
|
|
unknown2 []byte
|
|
|
|
unknown3 []byte
|
|
|
|
frame int
|
|
|
|
width int
|
|
|
|
height int
|
2020-02-17 22:11:52 -05:00
|
|
|
}
|
|
|
|
|
2021-02-17 04:37:04 -05:00
|
|
|
// SetSize sets glyph's size to w, h
|
2021-02-17 04:28:36 -05:00
|
|
|
func (fg *FontGlyph) SetSize(w, h int) {
|
|
|
|
fg.width, fg.height = w, h
|
2021-02-09 02:43:46 -05:00
|
|
|
}
|
|
|
|
|
2021-02-17 02:38:41 -05:00
|
|
|
// Size returns glyph's size
|
2021-02-17 03:05:29 -05:00
|
|
|
func (fg *FontGlyph) Size() (w, h int) {
|
2021-02-17 02:28:23 -05:00
|
|
|
return fg.width, fg.height
|
|
|
|
}
|
|
|
|
|
2021-02-17 04:37:04 -05:00
|
|
|
// SetFrameIndex sets frame index to idx
|
2021-02-17 04:28:36 -05:00
|
|
|
func (fg *FontGlyph) SetFrameIndex(idx int) {
|
|
|
|
fg.frame = idx
|
|
|
|
}
|
|
|
|
|
2021-02-17 02:38:41 -05:00
|
|
|
// FrameIndex returns glyph's frame
|
2021-02-17 03:05:29 -05:00
|
|
|
func (fg *FontGlyph) FrameIndex() int {
|
2021-02-17 02:28:23 -05:00
|
|
|
return fg.frame
|
|
|
|
}
|
|
|
|
|
2020-07-01 14:09:18 -04:00
|
|
|
// Font represents a displayable font
|
2020-02-17 22:11:52 -05:00
|
|
|
type Font struct {
|
2021-02-08 09:03:59 -05:00
|
|
|
unknownHeaderBytes []byte
|
|
|
|
sheet d2interface.Animation
|
|
|
|
table []byte
|
2021-02-17 03:05:29 -05:00
|
|
|
Glyphs map[rune]*FontGlyph
|
2021-02-08 09:03:59 -05:00
|
|
|
color color.Color
|
2020-02-17 22:11:52 -05:00
|
|
|
}
|
|
|
|
|
2021-02-08 07:21:50 -05:00
|
|
|
// Load loads a new font from byte slice
|
2021-02-09 02:43:46 -05:00
|
|
|
func Load(data []byte) (*Font, error) {
|
2021-02-08 09:03:59 -05:00
|
|
|
sr := d2datautils.CreateStreamReader(data)
|
|
|
|
|
2021-02-08 11:25:02 -05:00
|
|
|
signature, err := sr.ReadBytes(signatureBytesCount)
|
2021-02-08 09:03:59 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if string(signature) != knownSignature {
|
2021-02-08 07:21:50 -05:00
|
|
|
return nil, fmt.Errorf("invalid font table format")
|
|
|
|
}
|
|
|
|
|
|
|
|
font := &Font{
|
|
|
|
table: data,
|
|
|
|
color: color.White,
|
|
|
|
}
|
|
|
|
|
2021-02-08 11:25:02 -05:00
|
|
|
font.unknownHeaderBytes, err = sr.ReadBytes(unknownHeaderBytesCount)
|
2021-02-08 09:03:59 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2021-02-08 08:11:51 -05:00
|
|
|
}
|
|
|
|
|
2021-02-08 11:25:02 -05:00
|
|
|
err = font.initGlyphs(sr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-02-08 08:11:51 -05:00
|
|
|
|
2021-02-08 07:21:50 -05:00
|
|
|
return font, nil
|
|
|
|
}
|
|
|
|
|
2021-02-09 02:43:46 -05:00
|
|
|
// SetBackground sets font's background
|
|
|
|
func (f *Font) SetBackground(sheet d2interface.Animation) {
|
|
|
|
f.sheet = sheet
|
|
|
|
|
|
|
|
// recalculate max height
|
|
|
|
_, h := f.sheet.GetFrameBounds()
|
|
|
|
|
2021-02-17 02:29:10 -05:00
|
|
|
for i := range f.Glyphs {
|
2021-02-17 04:28:36 -05:00
|
|
|
f.Glyphs[i].SetSize(f.Glyphs[i].width, h)
|
2021-02-09 02:43:46 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 15:56:48 -04:00
|
|
|
// SetColor sets the fonts color
|
2020-07-01 14:09:18 -04:00
|
|
|
func (f *Font) SetColor(c color.Color) {
|
|
|
|
f.color = c
|
2020-02-24 22:35:21 -05:00
|
|
|
}
|
|
|
|
|
2020-07-01 14:09:18 -04:00
|
|
|
// GetTextMetrics returns the dimensions of the Font element in pixels
|
|
|
|
func (f *Font) GetTextMetrics(text string) (width, height int) {
|
2020-02-17 22:11:52 -05:00
|
|
|
var (
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
lineWidth int
|
|
|
|
lineHeight int
|
2020-02-17 22:11:52 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
for _, c := range text {
|
|
|
|
if c == '\n' {
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
width = d2math.MaxInt(width, lineWidth)
|
|
|
|
height += lineHeight
|
2020-02-17 22:11:52 -05:00
|
|
|
lineWidth = 0
|
|
|
|
lineHeight = 0
|
2021-02-17 02:29:10 -05:00
|
|
|
} else if glyph, ok := f.Glyphs[c]; ok {
|
2020-02-17 22:11:52 -05:00
|
|
|
lineWidth += glyph.width
|
2020-08-05 00:03:33 -04:00
|
|
|
lineHeight = d2math.MaxInt(lineHeight, glyph.height)
|
2020-02-17 22:11:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
width = d2math.MaxInt(width, lineWidth)
|
|
|
|
height += lineHeight
|
2020-02-17 22:11:52 -05:00
|
|
|
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
return width, height
|
2020-02-17 22:11:52 -05:00
|
|
|
}
|
|
|
|
|
2020-07-07 20:16:22 -04:00
|
|
|
// RenderText prints a text using its configured style on a Surface (multi-lines are left-aligned, use label otherwise)
|
2020-06-29 00:41:58 -04:00
|
|
|
func (f *Font) RenderText(text string, target d2interface.Surface) error {
|
2020-02-17 22:11:52 -05:00
|
|
|
f.sheet.SetColorMod(f.color)
|
|
|
|
|
|
|
|
lines := strings.Split(text, "\n")
|
|
|
|
|
|
|
|
for _, line := range lines {
|
|
|
|
var (
|
|
|
|
lineHeight int
|
|
|
|
lineLength int
|
|
|
|
)
|
|
|
|
|
|
|
|
for _, c := range line {
|
2021-02-17 02:29:10 -05:00
|
|
|
glyph, ok := f.Glyphs[c]
|
2020-07-01 14:09:18 -04:00
|
|
|
if !ok {
|
|
|
|
continue
|
2020-02-17 22:11:52 -05:00
|
|
|
}
|
2020-07-01 14:09:18 -04:00
|
|
|
|
|
|
|
if err := f.sheet.SetCurrentFrame(glyph.frame); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-10-28 14:17:42 -04:00
|
|
|
f.sheet.Render(target)
|
2020-07-01 14:09:18 -04:00
|
|
|
|
2020-08-05 00:03:33 -04:00
|
|
|
lineHeight = d2math.MaxInt(lineHeight, glyph.height)
|
2020-07-01 14:09:18 -04:00
|
|
|
lineLength++
|
|
|
|
|
|
|
|
target.PushTranslation(glyph.width, 0)
|
2020-02-17 22:11:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
target.PopN(lineLength)
|
|
|
|
target.PushTranslation(0, lineHeight)
|
|
|
|
}
|
|
|
|
|
|
|
|
target.PopN(len(lines))
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
|
2021-02-08 09:03:59 -05:00
|
|
|
func (f *Font) initGlyphs(sr *d2datautils.StreamReader) error {
|
2021-02-17 03:05:29 -05:00
|
|
|
glyphs := make(map[rune]*FontGlyph)
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
|
|
|
|
for i := 12; i < len(f.table); i += 14 {
|
2021-02-08 08:11:51 -05:00
|
|
|
code, err := sr.ReadUInt16()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
|
2021-02-17 03:05:29 -05:00
|
|
|
var glyph FontGlyph
|
2021-02-08 08:11:51 -05:00
|
|
|
|
2021-02-09 02:43:46 -05:00
|
|
|
// two bytes of 0
|
2021-02-08 11:25:02 -05:00
|
|
|
glyph.unknown1, err = sr.ReadBytes(unknown1BytesCount)
|
2021-02-08 09:03:59 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-02-08 08:11:51 -05:00
|
|
|
|
|
|
|
width, err := sr.ReadByte()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
glyph.width = int(width)
|
|
|
|
|
2021-02-09 02:43:46 -05:00
|
|
|
height, err := sr.ReadByte()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
glyph.height = int(height)
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
|
2021-02-09 02:43:46 -05:00
|
|
|
// 1, 0, 0
|
2021-02-08 11:25:02 -05:00
|
|
|
glyph.unknown2, err = sr.ReadBytes(unknown2BytesCount)
|
2021-02-08 09:03:59 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-02-08 08:11:51 -05:00
|
|
|
|
|
|
|
frame, err := sr.ReadUInt16()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
glyph.frame = int(frame)
|
|
|
|
|
2021-02-09 02:43:46 -05:00
|
|
|
// 1, 0, 0, character code repeated, and further 0.
|
2021-02-08 11:25:02 -05:00
|
|
|
glyph.unknown3, err = sr.ReadBytes(unknown3BytesCount)
|
2021-02-08 09:03:59 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-02-09 02:43:46 -05:00
|
|
|
glyphs[rune(code)] = &glyph
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
}
|
|
|
|
|
2021-02-17 02:29:10 -05:00
|
|
|
f.Glyphs = glyphs
|
2021-02-08 08:11:51 -05:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-02-08 11:25:02 -05:00
|
|
|
// Marshal encodes font back into byte slice
|
2021-02-08 08:11:51 -05:00
|
|
|
func (f *Font) Marshal() []byte {
|
|
|
|
sw := d2datautils.CreateStreamWriter()
|
|
|
|
|
|
|
|
sw.PushBytes([]byte("Woo!\x01")...)
|
2021-02-08 09:03:59 -05:00
|
|
|
sw.PushBytes(f.unknownHeaderBytes...)
|
|
|
|
|
2021-02-17 02:29:10 -05:00
|
|
|
for c, i := range f.Glyphs {
|
2021-02-08 09:03:59 -05:00
|
|
|
sw.PushUint16(uint16(c))
|
|
|
|
sw.PushBytes(i.unknown1...)
|
|
|
|
sw.PushBytes(byte(i.width))
|
2021-02-09 02:43:46 -05:00
|
|
|
sw.PushBytes(byte(i.height))
|
2021-02-08 09:03:59 -05:00
|
|
|
sw.PushBytes(i.unknown2...)
|
|
|
|
sw.PushUint16(uint16(i.frame))
|
|
|
|
sw.PushBytes(i.unknown3...)
|
|
|
|
}
|
2021-02-08 08:11:51 -05:00
|
|
|
|
|
|
|
return sw.GetBytes()
|
Decouple asset manager from renderer (#730)
* improve AssetManager implementation
Notable changes are:
* removed the individual managers inside of d2asset, only one asset manager
* AssetManager now has caches for the types of files it loads
* created a type for TextDictionary (the txt file structs)
* fixed a file path bug in d2loader Source
* fixed a asset stream bug in d2loader Asset
* d2loader.Loader now needs a d2config.Config on creation (for resolving locale files)
* updated the mpq file in d2asset test data, added test case for "sub-directory"
* added a Data method to d2asset.Asset. The data is cached on first full read.
* renamed ArchiveDataStream to DataStream in d2interface
* moved palette utility func out of d2asset and into d2util
* bugfix for MacOS mpq loader issue
* lint fixes, added data caching to filesystem asset
* adding comment for mpq asset close
* Decouple d2asset from d2render
Notable changes in d2common:
* d2dcc.Load now fully decodes the dcc and stores the directions/frames in the dcc struct
* un-exported dcc.decodeDirection, it is only used in d2dcc
* removed font interface from d2interface, we only have one font implementation
* added `Renderer` method to d2interface.Surface, animations use this to bind to a renderer and create surfaces as they need
* added `BindRenderer` method to animation interface
Notable changes in d2common/d2asset:
* **d2asset.NewAssetManager only needs to be passed a d2config.Config**, it is decoupled from d2render
* exported Animation
* Animation implementation binds to the renderer to create surfaces only on the first time it is rendered
* font, dcc, dc6 initialization logic moved out of asset_manager.go
* for dc6 and dcc animations, the process of decoding and creating render surfaces has been broken into different methods
* the d2asset.Font struct now stores font table data for initialization purposes
Notable changes in d2core/d2render:
* Surfaces store a renderer reference, this allows animations to bind to the renderer and create a surface just-in-time
**These last changes should have been a separate PR, sorry.**
Notable changes in d2core/d2ui:
* ui.NewSprite now handles creating an animation internally, only needs image and palette path as arguments
Notable Changes in d2game:
Because of the change in d2ui, all instances of this code pattern...
```golang
animation, err := screen.asset.LoadAnimation(imgPath, palettePath)
sprite, err := screen.ui.NewSprite(animation)
```
... becomes this ...
```golang
sprite, err := screen.ui.NewSprite(imgPath, palettePath)
```
2020-09-14 17:31:45 -04:00
|
|
|
}
|