Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
package movie
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/inkyblackness/hacked/ss1/content/audio"
|
||||
"github.com/inkyblackness/hacked/ss1/content/text"
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
)
|
||||
|
||||
const sizeLimit = 0xFFFFFF
|
||||
|
||||
// Cache retrieves movie container from a localizer and keeps them decoded until they are invalidated.
|
||||
type Cache struct {
|
||||
cp text.Codepage
|
||||
|
||||
localizer resource.Localizer
|
||||
|
||||
movies map[resource.Key]*cachedMovie
|
||||
}
|
||||
|
||||
type cachedMovie struct {
|
||||
sizeWarning bool
|
||||
container Container
|
||||
scenes []Scene
|
||||
}
|
||||
|
||||
func (cached *cachedMovie) video() []Scene {
|
||||
if len(cached.scenes) > 0 {
|
||||
return cached.scenes
|
||||
}
|
||||
cached.scenes, _ = cached.container.Video.Decompress()
|
||||
return cached.scenes
|
||||
}
|
||||
|
||||
// NewCache returns a new instance.
|
||||
func NewCache(cp text.Codepage, localizer resource.Localizer) *Cache {
|
||||
cache := &Cache{
|
||||
cp: cp,
|
||||
localizer: localizer,
|
||||
|
||||
movies: make(map[resource.Key]*cachedMovie),
|
||||
}
|
||||
return cache
|
||||
}
|
||||
|
||||
// InvalidateResources lets the cache remove any movies from resources that are specified in the given slice.
|
||||
func (cache *Cache) InvalidateResources(ids []resource.ID) {
|
||||
for _, id := range ids {
|
||||
for key := range cache.movies {
|
||||
if key.ID == id {
|
||||
delete(cache.movies, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cache *Cache) cached(key resource.Key) (*cachedMovie, error) {
|
||||
value, existing := cache.movies[key]
|
||||
if existing {
|
||||
return value, nil
|
||||
}
|
||||
selector := cache.localizer.LocalizedResources(key.Lang)
|
||||
view, err := selector.Select(key.ID.Plus(key.Index))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if (view.ContentType() != resource.Movie) || view.Compound() || (view.BlockCount() != 1) {
|
||||
return nil, resource.ErrWrongType(key, resource.Movie)
|
||||
}
|
||||
reader, err := view.Block(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
container, err := Read(bytes.NewReader(data), cache.cp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cached := &cachedMovie{
|
||||
sizeWarning: len(data) > sizeLimit,
|
||||
container: container,
|
||||
}
|
||||
cache.movies[key] = cached
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
// SizeWarning returns true if the given movie is cached and is larger than the underlying archive would support.
|
||||
func (cache *Cache) SizeWarning(key resource.Key) bool {
|
||||
cached, existing := cache.movies[key]
|
||||
return existing && cached.sizeWarning
|
||||
}
|
||||
|
||||
// Container retrieves and caches the underlying movie, and returns the complete container.
|
||||
func (cache *Cache) Container(key resource.Key) (Container, error) {
|
||||
cached, err := cache.cached(key)
|
||||
if err != nil {
|
||||
return Container{}, err
|
||||
}
|
||||
return cached.container, nil
|
||||
}
|
||||
|
||||
// Audio retrieves and caches the underlying movie, and returns the audio only.
|
||||
func (cache *Cache) Audio(key resource.Key) (sound audio.L8, err error) {
|
||||
cached, err := cache.cached(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return cached.container.Audio.Sound, nil
|
||||
}
|
||||
|
||||
// Video retrieves and caches the underlying movie, and returns the complete list of decoded scenes.
|
||||
func (cache *Cache) Video(key resource.Key) ([]Scene, error) {
|
||||
cached, err := cache.cached(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cached.video(), nil
|
||||
}
|
||||
|
||||
// Subtitles retrieves and caches the underlying movie, and returns the subtitles for given language.
|
||||
func (cache *Cache) Subtitles(key resource.Key, language resource.Language) (SubtitleList, error) {
|
||||
cached, err := cache.cached(key)
|
||||
if err != nil {
|
||||
return SubtitleList{}, err
|
||||
}
|
||||
return cached.container.Subtitles.PerLanguage[language], nil
|
||||
}
|
||||
Reference in New Issue
Block a user