68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package bitmap
|
|
|
|
import (
|
|
"github.com/inkyblackness/hacked/ss1/resource"
|
|
"github.com/inkyblackness/hacked/ss1/serial"
|
|
)
|
|
|
|
// PaletteCache retrieves palettes from a localizer and keeps them decoded until they are invalidated.
|
|
type PaletteCache struct {
|
|
localizer resource.Localizer
|
|
|
|
defaultPalette Palette
|
|
palettes map[resource.Key]Palette
|
|
}
|
|
|
|
// NewPaletteCache returns a new instance.
|
|
func NewPaletteCache(localizer resource.Localizer) *PaletteCache {
|
|
cache := &PaletteCache{
|
|
localizer: localizer,
|
|
palettes: make(map[resource.Key]Palette),
|
|
}
|
|
for i := 0; i < len(cache.defaultPalette); i++ {
|
|
col := &cache.defaultPalette[i]
|
|
col.Red = uint8(i)
|
|
col.Green = uint8(i)
|
|
col.Blue = uint8(i)
|
|
}
|
|
return cache
|
|
}
|
|
|
|
// InvalidateResources lets the cache remove any palettes from resources that are specified in the given slice.
|
|
func (cache *PaletteCache) InvalidateResources(ids []resource.ID) {
|
|
for _, id := range ids {
|
|
for key := range cache.palettes {
|
|
if key.ID == id {
|
|
delete(cache.palettes, key)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Palette tries to look up given palette.
|
|
func (cache *PaletteCache) Palette(key resource.Key) (pal Palette, err error) {
|
|
pal, existing := cache.palettes[key]
|
|
if existing {
|
|
return pal, nil
|
|
}
|
|
selector := cache.localizer.LocalizedResources(key.Lang)
|
|
view, err := selector.Select(key.ID)
|
|
if err != nil {
|
|
return cache.defaultPalette, err
|
|
}
|
|
if (view.ContentType() != resource.Palette) || (view.BlockCount() != 1) {
|
|
return cache.defaultPalette, resource.ErrWrongType(key, resource.Palette)
|
|
}
|
|
reader, err := view.Block(0)
|
|
if err != nil {
|
|
return cache.defaultPalette, err
|
|
}
|
|
decoder := serial.NewDecoder(reader)
|
|
decoder.Code(&pal)
|
|
if decoder.FirstError() != nil {
|
|
return cache.defaultPalette, decoder.FirstError()
|
|
}
|
|
cache.palettes[key] = pal
|
|
return pal, nil
|
|
}
|