From 04063424b7dd414e9737a51fa916714662a415ab Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Sat, 21 Jan 2023 15:01:17 -0600 Subject: [PATCH 1/5] changing to markdown for repo and using word/long --- README.md | 192 +++++++++++++++++++++--------------------------------- 1 file changed, 74 insertions(+), 118 deletions(-) diff --git a/README.md b/README.md index 384ec0d..f9db4af 100644 --- a/README.md +++ b/README.md @@ -1,138 +1,94 @@ -# gslaplay -Apple IIgs GSLA Player +# gslaplay - Apple IIgs GSLA Player -Example of a GS LZB Animation Player +Program that plays GS LZB Animation files. -Inspired by Deluxe Animation Run/Skip/Dump, and FLI/FLC with similar properties +----- +New Apple IIgs Animation file format ... GS LZ Byte Compressed Animation +> Why? When there are so many image formats would we need another one? +> It's because $C2/Paintworks animation format is just terribly inefficient. -I replace the "Run" with a dictionary/frame buffer copy from the existing -buffer to the existing buffer. This is able to runlength not just a single -byte, but a repeating pattern of arbitrary length. +- Inspired by Deluxe Animation Run/Skip/Dump, and FLI/FLC with similar properties. +- I replace the "Run" with a dictionary/frame buffer copy from the existing buffer to the existing buffer. This is able to runlength not just a single byte, but a repeating pattern of arbitrary length. +- Care is taken in the encoder to make sure the 65816 does not have to cross bank boundaries during any copy. This is so we can use the MVN instruction and also reduce the number of bank checks in the code. +-- (We have an opcode to indicate "source data bank has changed".) +- Goals include a good balance between file size, and playback performance (since one often makes a trade off with the other). --------------------------------------------------------------------------------- -New Apple IIgs Animation file format -GS LZ Byte Compressed Animation -Why? When there are so many image formats would we need another one? It’s -because $C2/Paintworks animation format is just terribly inefficient. - -Care is taken in the encoder, to make sure the 65816 does not have to cross bank -boundaries during any copy. This is so we can use the MVN instruction, and so -we can reduce the number of bank checks in the code. - -We have an opcode, that says “source data bank has changed” - -Goals include a good balance between file size, and playback performance -(since one often makes a trade off with the other). - -The file is defined as a byte stream. - -I will attempt to define the format as - -file-offset: the thing that is at the offset - -Header of the File is 20 bytes as follows - -File Offset Data Commentary ------------------------------------------------------------------- -0 0x47 ; ‘G’ Graphics -1 0x53 ; ‘S’ -2 0x4C ; ‘L’ LZB -3 0x41 ; ‘A’ Animation - -; File Length, is the total length of the file -4 FileLengthLow ; Low byte, 32-bit file length -5 LengthLowHigh ; High byte of low word -6 LengthHighLow ; Low byte, of high word -7 LengthHighHigh ; High Byte, of high word - -; 16 bit word with version # -8 VL ; Version # of the file format, currently only version 0 -9 VH ; Version High Byte - ; %RVVV_VVVV_VVVV_VVVV - ; V is a version #, 0 for now - ; R is the MSB, R = 0 no ring frame - ; R = 1, there is a ring frame - ; A Ring Frame is a frame that will delta from the last - ; frame of the animation, back to the first, for smoother - ; looping , If a ring frame exists, it’s also in the - ; frame count - -// next is a word, width in bytes (only 160 for now) -0xA WL ; Display Width in bytes low byte -0xB WH ; Display Width in bytes high byte -// next is a word, height (likely 200 for now, in tiled mode a multiple of 16) -0xC HL ; Display Height in bytes, low byte -0xD HH ; Display Height in bytes, high byte -// 2 bytes, Frame Size in Bytes, since a “Frame” may contain more than just the -// width * height, worth of pixels, for now this is $8000, or 32768 -0xE FBL ; Frame Buffer Length Low -0xF FBH ; Frame Buffer Length High - -// 4 byte, 32-bit, Frame Count (includes total frame count, so if there is a -// ring frame, this is included in the total) -0x10 FrameCountLow -0x11 FrameCountLowHigh -0x12 FrameCountHighLow -0x13 FrameCountHigh +----- -After this comes AIFF style chunks of data, basically a 4 byte chunk name, -followed by a 4 byte length (inclusive of the chunk size). The idea is that -you can skip chunks you don’t understand. +## Format +The file has an initial header followed by multiple data chunks. + +### Header + +Header of the File is 20 bytes as follows: + +File Offset | Data | Comment +------------|:----------------------:|------------------------------------ +| | _File ID_ | +0 | `0x47` | 'G' Graphics +1 | `0x53` | 'S' +2 | `0x4C` | 'L' LZB +3 | `0x41` | 'A' Animation +4 | {FileLength} | (32-bit long) File length in bytes +8 | {VL} | Version Low - File format Minor version, `0` for now +9 | {VH} | Version High - Bits: ```%RVVV_VVVV_VVVV_VVVV``` +| | | `V` is Major version #, `0` for now +| | | `R` is the MSB, `R = 0` no ring frame +| | | `R = 1`, there is a ring frame +| | | _Ring Frame_ is a frame that will delta from the last frame of the animation back to the first for smoother looping. If a ring frame exists, it's also in the frame count. +0xA | {Width} `0x00A0` | (16-bit word) Width in bytes, typically 320/2 == 160 == 0x00A0 +0xC | {Height} `0x00C8` | (16-bit word) Height in bytes, typically 200 == 0x00C8 +0xE | {FrameLength} `0x8000` | (16-bit word) Frame size in bytes, since a "Frame" may contain more than just the width * height, worth of pixels. For now this is `$8000`, or 32768 +0x10 | {FrameCount} | (32-bit long) Frame Count (total, including ring frame) +0x14 | _First data chunk...._ | .... +... | _Next data chunk...._ | .... until end of file + + +After the header comes AIFF style chunks of data starting at file offset `0x14`, basically a 4-byte chunk name, followed by a 4-byte length (inclusive of the chunk header). The idea is that you can skip chunks you don't understand. File Offset: 0x14 First Chunk (followed by more Chunks, until end of file) -Chunk Definitions -Name: ‘INIT’ - Initial Frame Chunk, this is the data used to first - initialize the playback buffer -0: 0x49 ; ‘I’ -1: 0x4E ; ‘N’ -2: 0x49 ; ‘I’ -3: 0x54 ; ‘T’ -// 32 bit long, length, little endian, including the 8 byte header -4: length low low -5: length low high -6: length high low -7: length high high +### Data Chunk Definitions +##### INIT +Initial Frame Chunk, this is the data used to first initialize the playback buffer -8: This is a single frame of data, that decodes/decompresses into frame sized -bytes (right now 0x8000) -This data stream includes, an end of animation opcode, so that the normal -animation decompressor, can be called on this data, and it will emit the initial -frame onto the screen +File Offset | Data | Comment +------------|:----------------------:|------------------------------------ +0 | `0x49` | 'I' +1 | `0x4E` | 'N' +2 | `0x49` | 'I' +3 | `0x54` | 'T' +4 | {ChunkLength} | (32-bit long) Chunk length in bytes, including this 8-byte header +8 | {FrameData} | A single frame of data which will be decoded/decompressed into a frame-sized buffer (right now `0x8000`). This data stream includes, an end of animation opcode, so that the normal animation decompressor can be called on this data and it will emit the initial frame onto the screen. -Name: ‘ANIM’ - Frames -0: 0x41 ‘A’ -1: 0x4E ‘N’ -2: 0x49 ‘I’ -3: 0x4D ‘M’ -// 32 bit long, length, little endian, including chunk header -4: length low low -5: length low high -6: length high low -7: length high high +##### ANIM +Animation Frame Chunk, contains the encoded delta frame data for all of the frames -// This is followed by the frames, with the intention of decompressing them at -// 60FPS, which is why no play speed is included, if you need a play-rate slower -// than this, blank frame’s should be inserted into the animation data +Chunk Offset| Data | Comment +------------|:----------------------:|------------------------------------ +0 | `0x41` | 'A' +1 | `0x4E` | 'N' +2 | `0x49` | 'I' +3 | `0x4D` | 'M' +4 | {ChunkLength} | (32-bit long) Chunk length in bytes, including this 8-byte header +8 | {FrameData} | Frames data stream, intended to be decompressed at 60FPS, which is why no play speed is included. If you need a play-rate slower than this, blank frames should be inserted into the animation data -// Every attempt is made to delta encode the image, meaning we just encode -// information about what changed each frame. We attempt to make the size -// efficient by supporting dictionary copies (where the dictionary is made up of -// existing pixels in the frame buffer). +> Every attempt is made to delta encode the image, meaning we just encode information about what changed each frame. We attempt to make the size efficient by supporting dictionary copies (where the dictionary is made up of existing pixels in the frame buffer). + +### Decoding Chunk Data Command Word, encoded low-high, what the bits mean: -// xxx_xxxx_xxxx_xxx is the number of bytes 1-16384 to follow (0 == 1 byte) +`xxx_xxxx_xxxx_xxx` is the number of bytes 1-16384 to follow (0 == 1 byte) -* %0xxx_xxxx_xxxx_xxx1 - Copy Bytes - straight copy bytes -* %1xxx_xxxx_xxxx_xxx1 - Skip Bytes - skip bytes / move the cursor -* %1xxx_xxxx_xxxx_xxx0 - Dictionary Copy Bytes from frame buffer to frame buffer -* -* %0000_0000_0000_0000- Source Skip -> Source pointer skips to next bank of data -* %0000_0000_0000_0010- End of Frame - end of frame -* %0000_0000_0000_0110- End of Animation / End of File / no more frames +`%0xxx_xxxx_xxxx_xxx1` - Copy Bytes - straight copy bytes +`%1xxx_xxxx_xxxx_xxx1` - Skip Bytes - skip bytes / move the cursor +`%1xxx_xxxx_xxxx_xxx0` - Dictionary Copy bytes from frame buffer to frame buffer -// other remaining codes, are reserved for future expansion +`%0000_0000_0000_0000` - Source Skip -> Source pointer skips to next bank of data +`%0000_0000_0000_0010` - End of Frame - end of frame +`%0000_0000_0000_0110` - End of Animation / End of File / No more frames +- other remaining codes, are reserved for future expansion From 34553ac36e72b31c5df16c7d528d9bb1d3aaa0f3 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Sat, 21 Jan 2023 16:41:40 -0600 Subject: [PATCH 2/5] adding quick-n-dirty CI --- .github/workflows/main.yml | 46 ++++++++++++++++++++++++++++++++++++++ README.md | 5 ++--- 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..1659883 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,46 @@ +on: [push] + +jobs: + cicd_pipeline: + runs-on: ubuntu-latest + name: Run assembly and disk image CICD pipeline + steps: + # CHECKOUT AND ASSEMBLE ON EVERY PUSH, ANY BRANCH + - uses: actions/checkout@v1 + - name: Install Merlin + uses: digarok/install-merlin32-action@v0.1.3 + - name: Assemble Source + run: | + merlin32 -V macros\ asm\link.s + + - name: Install Cadius + uses: digarok/install-cadius-action@v0.1.3 + + - name: Make Bootable ProDOS Image + if: startsWith(github.ref, 'refs/tags/v') + run: | + cadius createvolume gslaplay.po gslaplay 800KB >/dev/null + cadius addfile gslaplay.po /gslaplay/ asm/play.sys16 >/dev/null + + # EVERYTHING BELOW IS ONLY WHEN VERSION TAGS PUSHED (i.e. tag like "v0.1") + - name: Create Release + id: create_release + if: startsWith(github.ref, 'refs/tags/v') + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + + - name: Upload Release Asset - 800KB ProDOS Image + if: startsWith(github.ref, 'refs/tags/v') + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./gslaplay.po + asset_name: gslaplay.po + asset_content_type: application/octet-stream + \ No newline at end of file diff --git a/README.md b/README.md index f9db4af..89ee996 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ New Apple IIgs Animation file format ... GS LZ Byte Compressed Animation - Inspired by Deluxe Animation Run/Skip/Dump, and FLI/FLC with similar properties. - I replace the "Run" with a dictionary/frame buffer copy from the existing buffer to the existing buffer. This is able to runlength not just a single byte, but a repeating pattern of arbitrary length. - Care is taken in the encoder to make sure the 65816 does not have to cross bank boundaries during any copy. This is so we can use the MVN instruction and also reduce the number of bank checks in the code. --- (We have an opcode to indicate "source data bank has changed".) + - (We have an opcode to indicate "source data bank has changed".) - Goals include a good balance between file size, and playback performance (since one often makes a trade off with the other). ----- @@ -41,14 +41,13 @@ File Offset | Data | Comment 0xC | {Height} `0x00C8` | (16-bit word) Height in bytes, typically 200 == 0x00C8 0xE | {FrameLength} `0x8000` | (16-bit word) Frame size in bytes, since a "Frame" may contain more than just the width * height, worth of pixels. For now this is `$8000`, or 32768 0x10 | {FrameCount} | (32-bit long) Frame Count (total, including ring frame) +| | _HEADER END HERE_ | 0x14 | _First data chunk...._ | .... ... | _Next data chunk...._ | .... until end of file After the header comes AIFF style chunks of data starting at file offset `0x14`, basically a 4-byte chunk name, followed by a 4-byte length (inclusive of the chunk header). The idea is that you can skip chunks you don't understand. -File Offset: -0x14 First Chunk (followed by more Chunks, until end of file) ### Data Chunk Definitions ##### INIT From 7754ed61ac7110376731862b8ba4c30182c10d17 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Sat, 21 Jan 2023 16:44:20 -0600 Subject: [PATCH 3/5] ci --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1659883..14dc204 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,8 @@ jobs: uses: digarok/install-merlin32-action@v0.1.3 - name: Assemble Source run: | - merlin32 -V macros\ asm\link.s + merlin32 + merlin32 -V .\macros\ asm\link.s - name: Install Cadius uses: digarok/install-cadius-action@v0.1.3 From 3b52d78eb2b30bcfbd70ed9b2c6d316f273eb8c2 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Sat, 21 Jan 2023 16:45:07 -0600 Subject: [PATCH 4/5] ci --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14dc204..7ee8584 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,6 @@ jobs: uses: digarok/install-merlin32-action@v0.1.3 - name: Assemble Source run: | - merlin32 merlin32 -V .\macros\ asm\link.s - name: Install Cadius From ebd589409c6272c96083d16f231f755e8cece2b2 Mon Sep 17 00:00:00 2001 From: Dagen Brock Date: Sat, 21 Jan 2023 16:45:50 -0600 Subject: [PATCH 5/5] ci --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7ee8584..398ba40 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ jobs: uses: digarok/install-merlin32-action@v0.1.3 - name: Assemble Source run: | - merlin32 -V .\macros\ asm\link.s + merlin32 -V ./macros/ asm/link.s - name: Install Cadius uses: digarok/install-cadius-action@v0.1.3