diff --git a/platform/file.go b/platform/file.go index da34b48..0dfc0c4 100644 --- a/platform/file.go +++ b/platform/file.go @@ -17,6 +17,16 @@ func FileUnmountArchive(mountPath string) error { return nil } +func FileUnmountAll() error { + for _, archive := range fileState.mountPoints { + if err := archive.Close(); err != nil { + return err + } + } + + return nil +} + func FileOpen(path string) (*File, error) { return nil, nil } diff --git a/platform/platform.go b/platform/platform.go index 36b2ec7..9e03f04 100644 --- a/platform/platform.go +++ b/platform/platform.go @@ -1,17 +1,57 @@ package platform import ( + "errors" "log" "runtime" "github.com/veandco/go-sdl2/sdl" ) -var platfromState struct { - sdlIsInit bool +var ( + ErrPlatformNotInit = errors.New("platform is not initialized") +) + +var platformState struct { + isInit bool +} + +func Initialize() error { + log.Println("platform init") + + if platformState.isInit { + return nil + } + + runtime.LockOSThread() + + if err := sdl.Init(sdl.INIT_VIDEO); err != nil { + return err + } + + platformState.isInit = true + return nil +} + +func Shutdown() error { + log.Println("platform shutdown") + + if !platformState.isInit { + return nil + } + + if err := FileUnmountAll(); err != nil { + return err + } + + return nil } func Advance() (bool, error) { + if !platformState.isInit { + return false, ErrPlatformNotInit + } + for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch event.(type) { case *sdl.QuitEvent: @@ -30,19 +70,3 @@ func Advance() (bool, error) { return run, err } - -func platformInit() error { - if platfromState.sdlIsInit { - return nil - } - - runtime.LockOSThread() - - log.Println("sdl init") - if err := sdl.Init(sdl.INIT_VIDEO); err != nil { - return err - } - - platfromState.sdlIsInit = true - return nil -} diff --git a/platform/window.go b/platform/window.go index 9d26b4a..4d3e1b7 100644 --- a/platform/window.go +++ b/platform/window.go @@ -43,8 +43,6 @@ func WindowCreate(title string, size math.Vec2i, scene Scene) error { return ErrWindowExists } - platformInit() - var err error log.Println("window create") if windowState.sdlWindow, err = sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, int32(size.X), int32(size.Y), sdl.WINDOW_OPENGL); err != nil { diff --git a/streaming/bytewriter.go b/streaming/bytewriter.go new file mode 100644 index 0000000..1ef4da2 --- /dev/null +++ b/streaming/bytewriter.go @@ -0,0 +1,57 @@ +package streaming + +import ( + "errors" + "io" +) + +type Writer interface { + io.WriteSeeker +} + +type writer struct { + data []byte + offset int +} + +func NewWriter(data []byte) Writer { + return &writer{data, 0} +} + +func (w *writer) Write(data []byte) (int, error) { + length := len(data) + if w.offset+length > len(w.data) { + length = len(w.data) - w.offset + } + + if length == 0 { + return 0, errors.New("cannot write past end of buffer") + } + + copy(w.data[w.offset:], data[:length]) + w.offset += length + + return length, nil +} + +func (w *writer) Seek(offset int64, whence int) (int64, error) { + result := w.offset + switch whence { + case io.SeekStart: + result = int(offset) + case io.SeekCurrent: + result = w.offset + int(offset) + case io.SeekEnd: + result = len(w.data) - int(offset) + } + + if result < 0 { + return int64(w.offset), errors.New("cannot seek before beginning of buffer") + } + if result >= len(w.data) { + return int64(w.offset), errors.New("cannot seek past end of buffer") + } + + w.offset = result + return int64(w.offset), nil +} diff --git a/tools/viewer/viewer.go b/tools/viewer/viewer.go index 6e75942..b0cbb48 100644 --- a/tools/viewer/viewer.go +++ b/tools/viewer/viewer.go @@ -122,6 +122,9 @@ func (s *scene) updateTexture() error { } func main() { + platform.Initialize() + defer platform.Shutdown() + var ( palettePath = flag.String("palette", "", "path to palette file") )