diff --git a/formats/dat/dat.go b/formats/dat/dat.go index 5b62180..5b4c224 100644 --- a/formats/dat/dat.go +++ b/formats/dat/dat.go @@ -7,7 +7,7 @@ import ( "github.com/FooSoft/lazarus/math" ) -type DatPalette struct { +type Palette struct { Colors [256]math.Color3b } @@ -17,13 +17,13 @@ type color struct { R byte } -func NewFromReader(reader io.Reader) (*DatPalette, error) { +func NewFromReader(reader io.Reader) (*Palette, error) { var colors [256]color if err := binary.Read(reader, binary.LittleEndian, &colors); err != nil { return nil, err } - palette := new(DatPalette) + palette := new(Palette) for i, color := range colors { palette.Colors[i] = math.Color3b{R: color.R, G: color.G, B: color.B} } @@ -31,8 +31,8 @@ func NewFromReader(reader io.Reader) (*DatPalette, error) { return palette, nil } -func NewFromGrayscale() *DatPalette { - palette := new(DatPalette) +func NewFromGrayscale() *Palette { + palette := new(Palette) for i := 0; i < 256; i++ { value := uint8(i) palette.Colors[i] = math.Color3b{R: value, G: value, B: value} diff --git a/formats/dc6/dc6.go b/formats/dc6/dc6.go index 59a5d1b..a983c43 100644 --- a/formats/dc6/dc6.go +++ b/formats/dc6/dc6.go @@ -38,12 +38,12 @@ type Frame struct { Data []byte } -type Dc6Animation struct { +type Animation struct { Directions []Direction } -func NewFromReader(reader io.ReadSeeker) (*Dc6Animation, error) { - sprite := new(Dc6Animation) +func NewFromReader(reader io.ReadSeeker) (*Animation, error) { + sprite := new(Animation) var fileHead fileHeader if err := binary.Read(reader, binary.LittleEndian, &fileHead); err != nil { diff --git a/formats/mpq/mpq.go b/formats/mpq/mpq.go index 56edac4..bac295d 100644 --- a/formats/mpq/mpq.go +++ b/formats/mpq/mpq.go @@ -20,23 +20,16 @@ import ( "unsafe" ) -type File interface { - Read(data []byte) (int, error) - Seek(offset int64, whence int) (int64, error) - Close() error +type Archive struct { + handle unsafe.Pointer + paths map[string]string } -type MpqArchive interface { - OpenFile(path string) (File, error) - GetPaths() []string - Close() error -} - -func NewFromFile(path string) (MpqArchive, error) { +func NewFromFile(path string) (*Archive, error) { cs := C.CString(path) defer C.free(unsafe.Pointer(cs)) - a := new(archive) + a := new(Archive) if result := C.SFileOpenArchive(cs, 0, 0, (*C.HANDLE)(&a.handle)); result == 0 { return nil, fmt.Errorf("failed to open archive (%d)", getLastError()) } @@ -49,58 +42,7 @@ func NewFromFile(path string) (MpqArchive, error) { return a, nil } -type file struct { - handle unsafe.Pointer -} - -func (f *file) Read(data []byte) (int, error) { - var bytesRead int - if result := C.SFileReadFile(C.HANDLE(f.handle), unsafe.Pointer(&data[0]), C.ulong(len(data)), (*C.ulong)(unsafe.Pointer(&bytesRead)), nil); result == 0 { - lastError := getLastError() - if lastError == C.ERROR_HANDLE_EOF { - return bytesRead, io.EOF - } - - return 0, fmt.Errorf("failed to read file (%d)", lastError) - } - - return bytesRead, nil -} - -func (f *file) Seek(offset int64, whence int) (int64, error) { - var method uint - switch whence { - case io.SeekStart: - method = C.FILE_BEGIN - case io.SeekCurrent: - method = C.FILE_CURRENT - case io.SeekEnd: - method = C.FILE_END - } - - result := C.SFileSetFilePointer(C.HANDLE(f.handle), C.long(offset), nil, C.ulong(method)) - if result == C.SFILE_INVALID_SIZE { - return 0, fmt.Errorf("failed to set file pointer (%d)", getLastError()) - } - - return int64(result), nil -} - -func (f *file) Close() error { - if result := C.SFileCloseFile(C.HANDLE(f.handle)); result == 0 { - return fmt.Errorf("failed to close file (%d)", getLastError()) - } - - f.handle = nil - return nil -} - -type archive struct { - handle unsafe.Pointer - paths map[string]string -} - -func (a *archive) Close() error { +func (a *Archive) Close() error { if result := C.SFileCloseArchive(C.HANDLE(a.handle)); result == 0 { return fmt.Errorf("failed to close archive (%d)", getLastError()) } @@ -110,7 +52,7 @@ func (a *archive) Close() error { return nil } -func (a *archive) OpenFile(path string) (File, error) { +func (a *Archive) OpenFile(path string) (*File, error) { if pathInt, ok := a.paths[path]; ok { path = pathInt } @@ -118,7 +60,7 @@ func (a *archive) OpenFile(path string) (File, error) { cs := C.CString(path) defer C.free(unsafe.Pointer(cs)) - file := new(file) + file := new(File) if result := C.SFileOpenFileEx(C.HANDLE(a.handle), cs, 0, (*C.HANDLE)(&file.handle)); result == 0 { return nil, fmt.Errorf("failed to open file (%d)", getLastError()) } @@ -126,7 +68,7 @@ func (a *archive) OpenFile(path string) (File, error) { return file, nil } -func (a *archive) GetPaths() []string { +func (a *Archive) GetPaths() []string { var extPaths []string for extPath := range a.paths { extPaths = append(extPaths, extPath) @@ -135,7 +77,7 @@ func (a *archive) GetPaths() []string { return extPaths } -func (a *archive) buildPathMap() error { +func (a *Archive) buildPathMap() error { f, err := a.OpenFile("(listfile)") if err != nil { return err @@ -161,6 +103,52 @@ func (a *archive) buildPathMap() error { return nil } +type File struct { + handle unsafe.Pointer +} + +func (f *File) Read(data []byte) (int, error) { + var bytesRead int + if result := C.SFileReadFile(C.HANDLE(f.handle), unsafe.Pointer(&data[0]), C.ulong(len(data)), (*C.ulong)(unsafe.Pointer(&bytesRead)), nil); result == 0 { + lastError := getLastError() + if lastError == C.ERROR_HANDLE_EOF { + return bytesRead, io.EOF + } + + return 0, fmt.Errorf("failed to read file (%d)", lastError) + } + + return bytesRead, nil +} + +func (f *File) Seek(offset int64, whence int) (int64, error) { + var method uint + switch whence { + case io.SeekStart: + method = C.FILE_BEGIN + case io.SeekCurrent: + method = C.FILE_CURRENT + case io.SeekEnd: + method = C.FILE_END + } + + result := C.SFileSetFilePointer(C.HANDLE(f.handle), C.long(offset), nil, C.ulong(method)) + if result == C.SFILE_INVALID_SIZE { + return 0, fmt.Errorf("failed to set file pointer (%d)", getLastError()) + } + + return int64(result), nil +} + +func (f *File) Close() error { + if result := C.SFileCloseFile(C.HANDLE(f.handle)); result == 0 { + return fmt.Errorf("failed to close file (%d)", getLastError()) + } + + f.handle = nil + return nil +} + func sanitizePath(path string) string { return strings.ToLower(strings.Replace(path, "\\", string(os.PathSeparator), -1)) } diff --git a/platform/file.go b/platform/file.go index 47090c9..da34b48 100644 --- a/platform/file.go +++ b/platform/file.go @@ -3,7 +3,7 @@ package platform import "github.com/FooSoft/lazarus/formats/mpq" var fileState struct { - mountPoints map[string]mpq.MpqArchive + mountPoints map[string]*mpq.Archive } type File struct { diff --git a/tools/dc6/dc6.go b/tools/dc6/dc6.go index 4bc70da..65ce9d7 100644 --- a/tools/dc6/dc6.go +++ b/tools/dc6/dc6.go @@ -14,7 +14,7 @@ import ( "github.com/FooSoft/lazarus/formats/dc6" ) -func loadPalette(path string) (*dat.DatPalette, error) { +func loadPalette(path string) (*dat.Palette, error) { fp, err := os.Open(path) if err != nil { return nil, err @@ -23,7 +23,7 @@ func loadPalette(path string) (*dat.DatPalette, error) { return dat.NewFromReader(fp) } -func loadSprite(path string) (*dc6.Dc6Animation, error) { +func loadSprite(path string) (*dc6.Animation, error) { fp, err := os.Open(path) if err != nil { return nil, err @@ -32,7 +32,7 @@ func loadSprite(path string) (*dc6.Dc6Animation, error) { return dc6.NewFromReader(fp) } -func extractSprite(spritePath string, palette *dat.DatPalette, targetDir string) error { +func extractSprite(spritePath string, palette *dat.Palette, targetDir string) error { sprite, err := loadSprite(spritePath) if err != nil { return err diff --git a/tools/viewer/viewer.go b/tools/viewer/viewer.go index 7400e06..6e75942 100644 --- a/tools/viewer/viewer.go +++ b/tools/viewer/viewer.go @@ -15,7 +15,7 @@ import ( "github.com/FooSoft/lazarus/platform/imgui" ) -func loadPalette(path string) (*dat.DatPalette, error) { +func loadPalette(path string) (*dat.Palette, error) { fp, err := os.Open(path) if err != nil { return nil, err @@ -24,7 +24,7 @@ func loadPalette(path string) (*dat.DatPalette, error) { return dat.NewFromReader(fp) } -func loadAnimation(path string) (*dc6.Dc6Animation, error) { +func loadAnimation(path string) (*dc6.Animation, error) { fp, err := os.Open(path) if err != nil { return nil, err @@ -34,8 +34,8 @@ func loadAnimation(path string) (*dc6.Dc6Animation, error) { } type scene struct { - animation *dc6.Dc6Animation - palette *dat.DatPalette + animation *dc6.Animation + palette *dat.Palette texture graphics.Texture directionIndex int @@ -145,7 +145,7 @@ func main() { os.Exit(1) } - var palette *dat.DatPalette + var palette *dat.Palette if len(*palettePath) > 0 { palette, err = loadPalette(*palettePath) if err != nil {