Skip to content

Commit

Permalink
Work in progress on GUI (OpenDiablo2#304)
Browse files Browse the repository at this point in the history
* Work in progress on GUI refactor

* Remove WIP file

* Remove WIP style
  • Loading branch information
FooSoft authored Feb 18, 2020
1 parent 1983ec3 commit 810b168
Show file tree
Hide file tree
Showing 13 changed files with 717 additions and 181 deletions.
1 change: 1 addition & 0 deletions d2core/d2asset/asset_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type assetManager struct {
fileManager *fileManager
paletteManager *paletteManager
animationManager *animationManager
fontManager *fontManager
}

func loadPalette(palettePath string) (*d2datadict.PaletteRec, error) {
Expand Down
19 changes: 15 additions & 4 deletions d2core/d2asset/d2asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ func Initialize() error {
fileManager = createFileManager(config, archiveManager)
paletteManager = createPaletteManager()
animationManager = createAnimationManager()
fontManager = createFontManager()
)

singleton = &assetManager{
archiveManager,
fileManager,
paletteManager,
animationManager,
fontManager,
}

d2term.BindAction("assetspam", "display verbose asset manager logs", func(verbose bool) {
Expand All @@ -44,17 +46,19 @@ func Initialize() error {
})

d2term.BindAction("assetstat", "display asset manager cache statistics", func() {
d2term.OutputInfo("archive cache: %f%%", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
d2term.OutputInfo("file cache: %f%%", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
d2term.OutputInfo("palette cache: %f%%", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
d2term.OutputInfo("animation cache: %f%%", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
d2term.OutputInfo("archive cache: %f", float64(archiveManager.cache.GetWeight())/float64(archiveManager.cache.GetBudget())*100.0)
d2term.OutputInfo("file cache: %f", float64(fileManager.cache.GetWeight())/float64(fileManager.cache.GetBudget())*100.0)
d2term.OutputInfo("palette cache: %f", float64(paletteManager.cache.GetWeight())/float64(paletteManager.cache.GetBudget())*100.0)
d2term.OutputInfo("animation cache: %f", float64(animationManager.cache.GetWeight())/float64(animationManager.cache.GetBudget())*100.0)
d2term.OutputInfo("font cache: %f", float64(fontManager.cache.GetWeight())/float64(fontManager.cache.GetBudget())*100.0)
})

d2term.BindAction("assetclear", "clear asset manager cache", func() {
archiveManager.cache.Clear()
fileManager.cache.Clear()
paletteManager.cache.Clear()
animationManager.cache.Clear()
fontManager.cache.Clear()
})

return nil
Expand Down Expand Up @@ -86,6 +90,7 @@ func FileExists(filePath string) (bool, error) {
}

func LoadAnimation(animationPath, palettePath string) (*Animation, error) {
verifyWasInit()
return LoadAnimationWithTransparency(animationPath, palettePath, 255)
}

Expand All @@ -95,9 +100,15 @@ func LoadAnimationWithTransparency(animationPath, palettePath string, transparen
}

func LoadComposite(object *d2datadict.ObjectLookupRecord, palettePath string) (*Composite, error) {
verifyWasInit()
return CreateComposite(object, palettePath), nil
}

func LoadFont(tablePath, spritePath, palettePath string) (*Font, error) {
verifyWasInit()
return singleton.fontManager.loadFont(tablePath, spritePath, palettePath)
}

func verifyWasInit() {
if singleton == nil {
panic(ErrNotInit)
Expand Down
126 changes: 126 additions & 0 deletions d2core/d2asset/font.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package d2asset

import (
"encoding/binary"
"errors"
"image/color"
"strings"

"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
)

type fontGlyph struct {
frame int
width int
height int
}

type Font struct {
sheet *Animation
glyphs map[rune]fontGlyph
color color.Color
}

func loadFont(tablePath, spritePath, palettePath string) (*Font, error) {
sheet, err := LoadAnimation(spritePath, palettePath)
if err != nil {
return nil, err
}

data, err := LoadFile(tablePath)
if err != nil {
return nil, err
}

if string(data[:5]) != "Woo!\x01" {
return nil, errors.New("invalid font table format")
}

_, maxCharHeight := sheet.GetFrameBounds()

glyphs := make(map[rune]fontGlyph)
for i := 12; i < len(data); i += 14 {
code := rune(binary.LittleEndian.Uint16(data[i : i+2]))

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])

glyphs[code] = glyph
}

font := &Font{
sheet: sheet,
glyphs: glyphs,
color: color.White,
}

return font, nil
}

func (f *Font) GetTextMetrics(text string) (int, int) {
var (
lineWidth int
lineHeight int
totalWidth int
totalHeight int
)

for _, c := range text {
if c == '\n' {
totalWidth = d2common.MaxInt(totalWidth, lineWidth)
totalHeight += lineHeight
lineWidth = 0
lineHeight = 0
} else if glyph, ok := f.glyphs[c]; ok {
lineWidth += glyph.width
lineHeight = d2common.MaxInt(lineHeight, glyph.height)
}
}

totalWidth = d2common.MaxInt(totalWidth, lineWidth)
totalHeight += lineHeight

return totalWidth, totalHeight
}

func (f *Font) Clone() *Font {
return &Font{
sheet: f.sheet,
glyphs: f.glyphs,
color: f.color,
}
}

func (f *Font) RenderText(text string, target d2render.Surface) error {
f.sheet.SetColorMod(f.color)
f.sheet.SetBlend(false)

lines := strings.Split(text, "\n")

for _, line := range lines {
var (
lineHeight int
lineLength int
)

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++
}
}

target.PopN(lineLength)
target.PushTranslation(0, lineHeight)
}

target.PopN(len(lines))

return nil
}
37 changes: 37 additions & 0 deletions d2core/d2asset/font_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package d2asset

import (
"fmt"

"github.com/OpenDiablo2/OpenDiablo2/d2common"
)

const (
fontBudget = 64
)

type fontManager struct {
cache *d2common.Cache
}

func createFontManager() *fontManager {
return &fontManager{d2common.CreateCache(fontBudget)}
}

func (fm *fontManager) loadFont(tablePath, spritePath, palettePath string) (*Font, error) {
cachePath := fmt.Sprintf("%s;%s;%s", tablePath, spritePath, palettePath)
if font, found := fm.cache.Retrieve(cachePath); found {
return font.(*Font).Clone(), nil
}

font, err := loadFont(tablePath, spritePath, palettePath)
if err != nil {
return nil, err
}

if err := fm.cache.Insert(cachePath, font.Clone(), 1); err != nil {
return nil, err
}

return font, nil
}
14 changes: 13 additions & 1 deletion d2core/d2gui/d2gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var (
ErrNotInit = errors.New("gui system is not initialized")
)

var singleton *guiManager
var singleton *manager

func Initialize() error {
verifyNotInit()
Expand All @@ -34,6 +34,18 @@ func Advance(elapsed float64) error {
return singleton.advance(elapsed)
}

func AddLayout() *Layout {
return singleton.addLayout()
}

func AddSprite(imagePath, palettePath string) *Sprite {
return singleton.addSprite(imagePath, palettePath)
}

func AddLabel(text string, fontStyle FontStyle) *Label {
return singleton.addLabel(text, fontStyle)
}

func Clear() {
verifyWasInit()
singleton.clear()
Expand Down
125 changes: 0 additions & 125 deletions d2core/d2gui/gui_manager.go

This file was deleted.

Loading

0 comments on commit 810b168

Please sign in to comment.