Compare commits
10 Commits
ea282171fc
...
fcf3cced80
Author | SHA1 | Date | |
---|---|---|---|
fcf3cced80 | |||
dce6603c58 | |||
0b26e93322 | |||
1b121f1b90 | |||
5893615589 | |||
61d3ceff70 | |||
ec711d9c16 | |||
12d1f47abd | |||
7a092d28fe | |||
40c09c36a6 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
*.mpq
|
||||||
|
.ccls-cache
|
||||||
asset
|
asset
|
||||||
imgui.ini
|
imgui.ini
|
||||||
*.mpq
|
|
||||||
|
27
LICENSE
27
LICENSE
@ -1,21 +1,18 @@
|
|||||||
MIT License
|
Copyright 2018-2019 Alex Yatskov
|
||||||
|
|
||||||
Copyright (c) 2018 Alex Yatskov
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
the Software without restriction, including without limitation the rights to
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
in the Software without restriction, including without limitation the rights
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
subject to the following conditions:
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
SOFTWARE.
|
|
||||||
|
81
README.md
81
README.md
@ -1,55 +1,55 @@
|
|||||||
# Lazarus #
|
# Lazarus
|
||||||
|
|
||||||
The Lazarus project aims to preserve [Diablo II](https://en.wikipedia.org/wiki/Diablo_II) by reimplementing the game
|
The Lazarus project aims to preserve [Diablo II](https://en.wikipedia.org/wiki/Diablo_II) by reimplementing the game
|
||||||
engine in the Go programming language. Lazarus is a drop-in replacement for the original game executable; the user is
|
engine in the Go programming language. Lazarus is a drop-in replacement for the original game executable; the user is
|
||||||
responsible for supplying the game assets (namely the MPQ files) from the official game media.
|
responsible for supplying the game assets (namely the MPQ files) from the official game media.
|
||||||
|
|
||||||
![](https://foosoft.net/projects/lazarus/img/viewer.png)
|
![](img/viewer.png)
|
||||||
|
|
||||||
## Building ##
|
## Building
|
||||||
|
|
||||||
It is not currently possible to use `go get` to install all of the packages in the project in one step; some assembly is
|
It is not currently possible to use `go get` to install all of the packages in the project in one step; some assembly is
|
||||||
required. Follow the instructions below to set up a build environment from a fresh install of your 64-bit operating
|
required. Follow the instructions below to set up a build environment from a fresh install of your 64-bit operating
|
||||||
system of choice.
|
system of choice.
|
||||||
|
|
||||||
### Linux ###
|
### Linux
|
||||||
|
|
||||||
Lazarus is primarily being developed on Fedora, but the required package names are also provided for Ubuntu.
|
Lazarus is primarily being developed on Fedora, but the required package names are also provided for Ubuntu.
|
||||||
|
|
||||||
1. Install the required packages (for [Fedora](https://getfedora.org/) users):
|
1. Install the required packages (for [Fedora](https://getfedora.org/) users):
|
||||||
```
|
```
|
||||||
# sudo dnf install golang gcc-c++ cmake make git SDL2-devel mesa-libGL-devel zlib-devel bzip2-devel
|
sudo dnf install golang gcc-c++ cmake make git SDL2-devel mesa-libGL-devel zlib-devel bzip2-devel
|
||||||
```
|
```
|
||||||
Install the required packages (for [Ubuntu](https://www.ubuntu.com/) users):
|
Install the required packages (for [Ubuntu](https://www.ubuntu.com/) users):
|
||||||
```
|
```
|
||||||
# sudo apt-get install golang g++ cmake make git libsdl2-dev libgl1-mesa-dev zlib1g-dev libbz2-dev
|
sudo apt-get install golang g++ cmake make git libsdl2-dev libgl1-mesa-dev zlib1g-dev libbz2-dev
|
||||||
```
|
```
|
||||||
2. Build the [Dear ImGui](https://github.com/ocornut/imgui) wrapper package:
|
2. Build the [Dear ImGui](https://github.com/ocornut/imgui) wrapper package:
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/platform/imgui
|
go get github.com/FooSoft/lazarus/platform/imgui
|
||||||
```
|
```
|
||||||
Go will fetch the code, but Cgo will fail to link the [cimgui](https://github.com/cimgui/cimgui) wrapper;
|
Go will fetch the code, but Cgo will fail to link the [cimgui](https://github.com/cimgui/cimgui) wrapper;
|
||||||
we need to configure and build it:
|
we need to configure and build it:
|
||||||
```
|
```
|
||||||
$ cd $GOPATH/src/github.com/FooSoft/lazarus/platform/imgui/cimgui
|
cd $GOPATH/src/github.com/FooSoft/lazarus/platform/imgui/cimgui
|
||||||
$ cmake -DIMGUI_STATIC="yes" .
|
cmake -DIMGUI_STATIC="yes" .
|
||||||
$ make
|
make
|
||||||
```
|
```
|
||||||
You should now have a `cimgui.a` statically linked library in the `cimgui` directory.
|
You should now have a `cimgui.a` statically linked library in the `cimgui` directory.
|
||||||
3. Build the [StormLib](http://zezula.net/en/mpq/stormlib.html) wrapper package:
|
3. Build the [StormLib](http://zezula.net/en/mpq/stormlib.html) wrapper package:
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/formats/mpq
|
go get github.com/FooSoft/lazarus/formats/mpq
|
||||||
```
|
```
|
||||||
Go will fetch the code, but Cgo will fail to link the StormLib wrapper;
|
Go will fetch the code, but Cgo will fail to link the StormLib wrapper;
|
||||||
we need to configure and build it:
|
we need to configure and build it:
|
||||||
```
|
```
|
||||||
$ cd $GOPATH/src/github.com/FooSoft/lazarus/formats/mpq/stormlib
|
cd $GOPATH/src/github.com/FooSoft/lazarus/formats/mpq/stormlib
|
||||||
$ cmake .
|
cmake .
|
||||||
$ make
|
make
|
||||||
```
|
```
|
||||||
You should now have a `libstorm.a` statically linked library in the `stormlib` directory.
|
You should now have a `libstorm.a` statically linked library in the `stormlib` directory.
|
||||||
|
|
||||||
### Windows ###
|
### Windows
|
||||||
|
|
||||||
Lazarus is only tested on Windows 10, but should in theory run on anything newer than Windows XP.
|
Lazarus is only tested on Windows 10, but should in theory run on anything newer than Windows XP.
|
||||||
|
|
||||||
@ -57,47 +57,47 @@ Lazarus is only tested on Windows 10, but should in theory run on anything newer
|
|||||||
2. Download and the latest 64-bit EXE installer for MSYS2 from the [official homepage](https://www.msys2.org/); install to the default directory.
|
2. Download and the latest 64-bit EXE installer for MSYS2 from the [official homepage](https://www.msys2.org/); install to the default directory.
|
||||||
3. Install the required packages (using the MSYS MinGW terminal):
|
3. Install the required packages (using the MSYS MinGW terminal):
|
||||||
```
|
```
|
||||||
$ pacman -S mingw-w64-x86_64-gcc cmake make git mingw-w64-x86_64-SDL2 zlib-devel libbz2-devel
|
pacman -S mingw-w64-x86_64-gcc cmake make git mingw-w64-x86_64-SDL2 zlib-devel libbz2-devel
|
||||||
```
|
```
|
||||||
4. Add `C:\msys64\usr\bin` and `C:\msys64\mingw64\bin` to your system's `PATH` environment variable.
|
4. Add `C:\msys64\usr\bin` and `C:\msys64\mingw64\bin` to your system's `PATH` environment variable.
|
||||||
5. Build the [Dear ImGui](https://github.com/ocornut/imgui) wrapper package (using the system command prompt):
|
5. Build the [Dear ImGui](https://github.com/ocornut/imgui) wrapper package (using the system command prompt):
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/platform/imgui
|
go get github.com/FooSoft/lazarus/platform/imgui
|
||||||
```
|
```
|
||||||
Go will fetch the code, but Cgo will fail to link the [cimgui](https://github.com/cimgui/cimgui) wrapper;
|
Go will fetch the code, but Cgo will fail to link the [cimgui](https://github.com/cimgui/cimgui) wrapper;
|
||||||
we need to configure and build it:
|
we need to configure and build it:
|
||||||
```
|
```
|
||||||
$ cd %GOPATH%/src/github.com/FooSoft/lazarus/platform/imgui/cimgui
|
cd %GOPATH%/src/github.com/FooSoft/lazarus/platform/imgui/cimgui
|
||||||
$ cmake -DIMGUI_STATIC="yes" .
|
cmake -DIMGUI_STATIC="yes" .
|
||||||
$ make
|
make
|
||||||
```
|
```
|
||||||
You should now have a `cimgui.a` statically linked library in the `cimgui` directory.
|
You should now have a `cimgui.a` statically linked library in the `cimgui` directory.
|
||||||
6. Build the [StormLib](http://zezula.net/en/mpq/stormlib.html) wrapper package (using the system command prompt):
|
6. Build the [StormLib](http://zezula.net/en/mpq/stormlib.html) wrapper package (using the system command prompt):
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/formats/mpq
|
go get github.com/FooSoft/lazarus/formats/mpq
|
||||||
```
|
```
|
||||||
Go will fetch the code, but Cgo will fail to link the StormLib wrapper;
|
Go will fetch the code, but Cgo will fail to link the StormLib wrapper;
|
||||||
we need to configure and build it:
|
we need to configure and build it:
|
||||||
```
|
```
|
||||||
$ cd %GOPATH%/src/github.com/FooSoft/lazarus/formats/mpq/stormlib
|
cd %GOPATH%/src/github.com/FooSoft/lazarus/formats/mpq/stormlib
|
||||||
$ cmake .
|
cmake .
|
||||||
$ make
|
make
|
||||||
```
|
```
|
||||||
You should now have a `libstorm.a` statically linked library in the `stormlib` directory.
|
You should now have a `libstorm.a` statically linked library in the `stormlib` directory.
|
||||||
|
|
||||||
## Tools ##
|
## Tools
|
||||||
|
|
||||||
This project includes several tools which are used to demonstrate the capabilities of the engine as well as manipulate
|
This project includes several tools which are used to demonstrate the capabilities of the engine as well as manipulate
|
||||||
game data for debugging purposes. Make sure to perform the setup steps outlined in the "Building" section before
|
game data for debugging purposes. Make sure to perform the setup steps outlined in the "Building" section before
|
||||||
installing these packages.
|
installing these packages.
|
||||||
|
|
||||||
### `dc6` ###
|
### `dc6`
|
||||||
|
|
||||||
Converts the frames of one or more DC6 animations to PNG files, using the provided palette file.
|
Converts the frames of one or more DC6 animations to PNG files, using the provided palette file.
|
||||||
|
|
||||||
* Installation:
|
* Installation:
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/tools/dc6
|
go get github.com/FooSoft/lazarus/tools/dc6
|
||||||
```
|
```
|
||||||
* Usage:
|
* Usage:
|
||||||
```
|
```
|
||||||
@ -108,13 +108,13 @@ Converts the frames of one or more DC6 animations to PNG files, using the provid
|
|||||||
target directory (default ".")
|
target directory (default ".")
|
||||||
```
|
```
|
||||||
|
|
||||||
### `mpq` ###
|
### `mpq`
|
||||||
|
|
||||||
Extracts the contents of one or more MPQ archives to a target directory, using an optional filter.
|
Extracts the contents of one or more MPQ archives to a target directory, using an optional filter.
|
||||||
|
|
||||||
* Installation:
|
* Installation:
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/tools/mpq
|
go get github.com/FooSoft/lazarus/tools/mpq
|
||||||
```
|
```
|
||||||
* Usage:
|
* Usage:
|
||||||
```
|
```
|
||||||
@ -127,14 +127,14 @@ Extracts the contents of one or more MPQ archives to a target directory, using a
|
|||||||
target directory (default ".")
|
target directory (default ".")
|
||||||
```
|
```
|
||||||
|
|
||||||
### `viewer` ###
|
### `viewer`
|
||||||
|
|
||||||
Displays the frames of DC6 animation files, using the provided palette file. A grayscale fallback palette is used if no
|
Displays the frames of DC6 animation files, using the provided palette file. A grayscale fallback palette is used if no
|
||||||
palette is provided on the command line.
|
palette is provided on the command line.
|
||||||
|
|
||||||
* Installation:
|
* Installation:
|
||||||
```
|
```
|
||||||
$ go get github.com/FooSoft/lazarus/tools/viewer
|
go get github.com/FooSoft/lazarus/tools/viewer
|
||||||
```
|
```
|
||||||
* Usage:
|
* Usage:
|
||||||
```
|
```
|
||||||
@ -144,22 +144,3 @@ palette is provided on the command line.
|
|||||||
-palette string
|
-palette string
|
||||||
path to palette file
|
path to palette file
|
||||||
```
|
```
|
||||||
|
|
||||||
## License ##
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
type Sprite struct {
|
type Sprite struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type bounds struct {
|
type box struct {
|
||||||
x1 int
|
x1 int
|
||||||
y1 int
|
y1 int
|
||||||
x2 int
|
x2 int
|
||||||
|
@ -2,6 +2,7 @@ package dcc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/FooSoft/lazarus/streaming"
|
"github.com/FooSoft/lazarus/streaming"
|
||||||
)
|
)
|
||||||
@ -19,13 +20,7 @@ type directionHeader struct {
|
|||||||
CodedBytesBits uint8
|
CodedBytesBits uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
type direction struct {
|
func readDirectionHeader(bitReader *streaming.BitReader) (*directionHeader, error) {
|
||||||
header directionHeader
|
|
||||||
frames []frame
|
|
||||||
bounds bounds
|
|
||||||
}
|
|
||||||
|
|
||||||
func readDirectionHeader(bitReader *streaming.BitReader) directionHeader {
|
|
||||||
var dirHead directionHeader
|
var dirHead directionHeader
|
||||||
|
|
||||||
dirHead.CodedSize = uint32(bitReader.ReadUint(32))
|
dirHead.CodedSize = uint32(bitReader.ReadUint(32))
|
||||||
@ -39,73 +34,57 @@ func readDirectionHeader(bitReader *streaming.BitReader) directionHeader {
|
|||||||
dirHead.OptionalBytesBits = uint8(bitReader.ReadUint(4))
|
dirHead.OptionalBytesBits = uint8(bitReader.ReadUint(4))
|
||||||
dirHead.CodedBytesBits = uint8(bitReader.ReadUint(4))
|
dirHead.CodedBytesBits = uint8(bitReader.ReadUint(4))
|
||||||
|
|
||||||
return dirHead
|
if err := bitReader.Error(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &dirHead, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readDirection(reader io.ReadSeeker, fileHead fileHeader) (*direction, error) {
|
func readDirection(reader io.ReadSeeker, fileHead fileHeader) (*direction, error) {
|
||||||
bitReader := streaming.NewBitReader(reader)
|
bitReader := streaming.NewBitReader(reader)
|
||||||
|
|
||||||
dirHead := readDirectionHeader(bitReader)
|
dirHead, err := readDirectionHeader(bitReader)
|
||||||
if err := bitReader.Error(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
frameHeads, err := readFrameHeaders(bitReader, fileHead, dirHead)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dirData direction
|
frameHeads, dirBounds, err := readFrameHeaders(bitReader, fileHead, *dirHead)
|
||||||
for i, frameHead := range frameHeads {
|
if err != nil {
|
||||||
frameData := frame{
|
return nil, err
|
||||||
header: frameHead,
|
|
||||||
bounds: bounds{
|
|
||||||
x1: int(frameHead.OffsetX),
|
|
||||||
y1: int(frameHead.OffsetY) - int(frameHead.Height) + 1,
|
|
||||||
x2: int(frameHead.OffsetX) + int(frameHead.Width),
|
|
||||||
y2: int(frameHead.OffsetY) + 1,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dirData.frames = append(dirData.frames, frameData)
|
dirData := direction{bounds: dirBounds}
|
||||||
|
for _, frameHead := range frameHeads {
|
||||||
if i == 0 {
|
dirData.frames = append(dirData.frames, newFrame(frameHead, dirBounds))
|
||||||
dirData.bounds = frameData.bounds
|
|
||||||
} else {
|
|
||||||
if dirData.bounds.x1 > frameData.bounds.x1 {
|
|
||||||
dirData.bounds.x1 = frameData.bounds.x1
|
|
||||||
}
|
|
||||||
if dirData.bounds.y1 > frameData.bounds.y1 {
|
|
||||||
dirData.bounds.y1 = frameData.bounds.y1
|
|
||||||
}
|
|
||||||
if dirData.bounds.x2 < frameData.bounds.x2 {
|
|
||||||
dirData.bounds.x2 = frameData.bounds.x2
|
|
||||||
}
|
|
||||||
if dirData.bounds.y2 < frameData.bounds.y2 {
|
|
||||||
dirData.bounds.y2 = frameData.bounds.y2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var entries []pixelBufferEntry
|
var entries []pixelBufferEntry
|
||||||
|
|
||||||
entries, err = decodeDirectionStage1(bitReader, &dirData, entries)
|
entries, err = dirData.decodeStage1(bitReader, entries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
entries, err = decodeDirectionStage2(bitReader, &dirData, entries)
|
entries, err = dirData.decodeStage2(bitReader, entries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println(dirData.bounds)
|
||||||
return &dirData, nil
|
return &dirData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeDirectionStage1(bitReader *streaming.BitReader, dirData *direction, entries []pixelBufferEntry) ([]pixelBufferEntry, error) {
|
type direction struct {
|
||||||
|
header directionHeader
|
||||||
|
frames []frame
|
||||||
|
bounds box
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *direction) decodeStage1(bitReader *streaming.BitReader, entries []pixelBufferEntry) ([]pixelBufferEntry, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeDirectionStage2(bitReader *streaming.BitReader, dirData *direction, entries []pixelBufferEntry) ([]pixelBufferEntry, error) {
|
func (d *direction) decodeStage2(bitReader *streaming.BitReader, entries []pixelBufferEntry) ([]pixelBufferEntry, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,7 @@ type frameHeader struct {
|
|||||||
FrameBottomUp bool
|
FrameBottomUp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type frame struct {
|
func readFrameHeader(bitReader *streaming.BitReader, dirHead directionHeader) (*frameHeader, error) {
|
||||||
header frameHeader
|
|
||||||
bounds bounds
|
|
||||||
}
|
|
||||||
|
|
||||||
func readFrameHeader(bitReader *streaming.BitReader, dirHead directionHeader) frameHeader {
|
|
||||||
var frameHead frameHeader
|
var frameHead frameHeader
|
||||||
|
|
||||||
frameHead.Variable0 = uint32(bitReader.ReadUintPacked(int(dirHead.Variable0Bits)))
|
frameHead.Variable0 = uint32(bitReader.ReadUintPacked(int(dirHead.Variable0Bits)))
|
||||||
@ -34,13 +29,6 @@ func readFrameHeader(bitReader *streaming.BitReader, dirHead directionHeader) fr
|
|||||||
frameHead.CodedBytes = uint32(bitReader.ReadUintPacked(int(dirHead.CodedBytesBits)))
|
frameHead.CodedBytes = uint32(bitReader.ReadUintPacked(int(dirHead.CodedBytesBits)))
|
||||||
frameHead.FrameBottomUp = bitReader.ReadBool()
|
frameHead.FrameBottomUp = bitReader.ReadBool()
|
||||||
|
|
||||||
return frameHead
|
|
||||||
}
|
|
||||||
|
|
||||||
func readFrameHeaders(bitReader *streaming.BitReader, fileHead fileHeader, dirHead directionHeader) ([]frameHeader, error) {
|
|
||||||
var frameHeads []frameHeader
|
|
||||||
for i := 0; i < int(fileHead.FramesPerDir); i++ {
|
|
||||||
frameHead := readFrameHeader(bitReader, dirHead)
|
|
||||||
if err := bitReader.Error(); err != nil {
|
if err := bitReader.Error(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -57,8 +45,133 @@ func readFrameHeaders(bitReader *streaming.BitReader, fileHead fileHeader, dirHe
|
|||||||
return nil, errors.New("invalid frame dimensions")
|
return nil, errors.New("invalid frame dimensions")
|
||||||
}
|
}
|
||||||
|
|
||||||
frameHeads = append(frameHeads, frameHead)
|
return &frameHead, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *frameHeader) bounds() box {
|
||||||
|
return box{
|
||||||
|
x1: int(h.OffsetX),
|
||||||
|
y1: int(h.OffsetY) - int(h.Height) + 1,
|
||||||
|
x2: int(h.OffsetX) + int(h.Width),
|
||||||
|
y2: int(h.OffsetY) + 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFrameHeaders(bitReader *streaming.BitReader, fileHead fileHeader, dirHead directionHeader) ([]frameHeader, box, error) {
|
||||||
|
var (
|
||||||
|
frameHeads []frameHeader
|
||||||
|
boundsAll box
|
||||||
|
)
|
||||||
|
|
||||||
|
for i := 0; i < int(fileHead.FramesPerDir); i++ {
|
||||||
|
frameHead, err := readFrameHeader(bitReader, dirHead)
|
||||||
|
if err != nil {
|
||||||
|
return nil, box{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return frameHeads, nil
|
bounds := frameHead.bounds()
|
||||||
|
if i == 0 {
|
||||||
|
boundsAll = bounds
|
||||||
|
} else {
|
||||||
|
if boundsAll.x1 > bounds.x1 {
|
||||||
|
boundsAll.x1 = bounds.x1
|
||||||
|
}
|
||||||
|
if boundsAll.y1 > bounds.y1 {
|
||||||
|
boundsAll.y1 = bounds.y1
|
||||||
|
}
|
||||||
|
if boundsAll.x2 < bounds.x2 {
|
||||||
|
boundsAll.x2 = bounds.x2
|
||||||
|
}
|
||||||
|
if boundsAll.y2 < bounds.y2 {
|
||||||
|
boundsAll.y2 = bounds.y2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frameHeads = append(frameHeads, *frameHead)
|
||||||
|
}
|
||||||
|
|
||||||
|
return frameHeads, boundsAll, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type frame struct {
|
||||||
|
header frameHeader
|
||||||
|
|
||||||
|
nbCellsX int
|
||||||
|
nbCellsY int
|
||||||
|
dirOffsetX int
|
||||||
|
dirOffsetY int
|
||||||
|
|
||||||
|
cellSameAsPrevious []bool
|
||||||
|
cellWidths []int
|
||||||
|
cellHeights []int
|
||||||
|
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFrame(frameHead frameHeader, dirBounds box) frame {
|
||||||
|
frameBounds := frameHead.bounds()
|
||||||
|
|
||||||
|
frameData := frame{
|
||||||
|
header: frameHead,
|
||||||
|
dirOffsetX: frameBounds.x1 - dirBounds.x1,
|
||||||
|
dirOffsetY: frameBounds.y1 - dirBounds.y1,
|
||||||
|
}
|
||||||
|
|
||||||
|
widthFirstColumn := 4 - frameData.dirOffsetX%4
|
||||||
|
frameWidth := frameBounds.x2 - frameBounds.x1
|
||||||
|
if frameWidth-widthFirstColumn <= 1 {
|
||||||
|
frameData.nbCellsX = 1
|
||||||
|
} else {
|
||||||
|
temp := frameWidth - widthFirstColumn - 1
|
||||||
|
frameData.nbCellsX = 2 + temp/4
|
||||||
|
if temp%4 == 0 {
|
||||||
|
frameData.nbCellsX--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heightFirstRow := 4 - frameData.dirOffsetY%4
|
||||||
|
frameHeight := frameBounds.y2 - frameBounds.y1
|
||||||
|
if frameHeight-heightFirstRow <= 1 {
|
||||||
|
frameData.nbCellsY = 1
|
||||||
|
} else {
|
||||||
|
temp := frameHeight - heightFirstRow - 1
|
||||||
|
frameData.nbCellsY = 2 + temp/4
|
||||||
|
if temp%4 == 0 {
|
||||||
|
frameData.nbCellsY--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frameData.cellWidths = make([]int, frameData.nbCellsX)
|
||||||
|
for i := range frameData.cellWidths {
|
||||||
|
frameData.cellWidths[i] = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if frameData.nbCellsX == 1 {
|
||||||
|
frameData.cellWidths[0] = frameWidth
|
||||||
|
} else {
|
||||||
|
frameData.cellWidths[0] = widthFirstColumn
|
||||||
|
nbColumnsExcludingFirstAndLast := frameData.nbCellsX - 2
|
||||||
|
widthExcludingFirstAndLastColumns := 4 * nbColumnsExcludingFirstAndLast
|
||||||
|
frameData.cellWidths[frameData.nbCellsX-1] = frameWidth - (widthFirstColumn + widthExcludingFirstAndLastColumns)
|
||||||
|
}
|
||||||
|
|
||||||
|
frameData.cellHeights = make([]int, frameData.nbCellsY)
|
||||||
|
for i := range frameData.cellHeights {
|
||||||
|
frameData.cellHeights[i] = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if frameData.nbCellsY == 1 {
|
||||||
|
frameData.cellHeights[0] = frameHeight
|
||||||
|
} else {
|
||||||
|
frameData.cellHeights[0] = heightFirstRow
|
||||||
|
nbRowsExcludingFirstAndLast := frameData.nbCellsY - 2
|
||||||
|
heightExcludingFirstAndLastRows := 4 * nbRowsExcludingFirstAndLast
|
||||||
|
frameData.cellHeights[frameData.nbCellsY-1] = frameHeight - (heightFirstRow + heightExcludingFirstAndLastRows)
|
||||||
|
}
|
||||||
|
|
||||||
|
frameData.cellSameAsPrevious = make([]bool, frameData.nbCellsX*frameData.nbCellsY)
|
||||||
|
frameData.data = make([]byte, frameWidth*frameHeight)
|
||||||
|
|
||||||
|
return frameData
|
||||||
|
|
||||||
}
|
}
|
||||||
|
BIN
img/viewer.png
Normal file
BIN
img/viewer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -44,7 +44,7 @@ func FileMountArchive(mountPath, archivePath string) error {
|
|||||||
func FileUnmountArchive(mountPath string) error {
|
func FileUnmountArchive(mountPath string) error {
|
||||||
archive, ok := fileState.mountPoints[mountPath]
|
archive, ok := fileState.mountPoints[mountPath]
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("file archive is nout mounted")
|
return errors.New("file archive is not mounted")
|
||||||
}
|
}
|
||||||
|
|
||||||
var paths []string
|
var paths []string
|
||||||
|
Loading…
Reference in New Issue
Block a user