Page 2 of 2

Re: Bagel NES CHR compression.

Posted: Tue Jan 17, 2017 10:46 am
by tepples
So now I'm finally getting around to seeing where I could use Bagel.

My next project is tools to manipulate an NES Stripe Image stored starting at $0108. (I chose $0108 because of how the 6502's only autoincrementing read instruction interacts with interrupts.) This would allow me to combine CHR and nametable updates in one vblank without needing a plethora of specific update formats such as the seven different bgup routines in RHDE. An update containing eight tiles would need two packet headers:

Code: Select all

$0100-$0107: scratch space in case the uploader is interrupted, enough for PC, P, A, X, Y
$0108-$010A: address and length for first four tiles
$010B-$014A: first four tiles
$014B-$014D: address and length for second four tiles
$014E-$018D: second four tiles
$018E: $FF terminator
I looked at bagel.s and found this doc comment for bagel_decompress_block:

Code: Select all

;;
; bagel_stream_ptr = the input stream pointer,
;     points to after stream on exit.
; X = output buffer offset, restored on exit.
; Returns: flags of decrementing bagel_block_count
Does that mean I could call it with X=$0B to decompress four tiles and X=$4E to decompress four more?

Re: Bagel NES CHR compression.

Posted: Tue Jan 17, 2017 10:53 am
by JRoatch
Yes. That will work given that the output buffer in bagel's context starts at $0100.

Also disregard "[X] restored on exit" part. When bagel_decompress_block returns, X has been incremented by 64. I use this fact to have my own string writing system compute strings lengths by differences in the X register.

Re: Bagel NES CHR compression.

Posted: Tue Jan 17, 2017 12:21 pm
by FrankenGraphics
re: the demo

Incidentally (?), blanking and overwriting characters when the letters there are in alphabetical order at that speed has a really nice animation effect on text written in the nametable.

Re: Bagel NES CHR compression.

Posted: Tue Jan 17, 2017 12:38 pm
by JRoatch
WheelInventor wrote:re: the demo

Incidentally (?), blanking and overwriting characters when the letters there are in alphabetical order at that speed has a really nice animation effect on text written in the nametable.
It's kind of a throwback to the demo I posted in first post I made in this fourm.

Bonus undocumented feature of the demo: While holding B press Left or Right to see it decompress from the wrong parts of the ROM.

Re: Bagel NES CHR compression.

Posted: Tue Jan 17, 2017 1:14 pm
by FrankenGraphics
Oh, i see. Well, it has a nice substance to it, when it's either because of (like in this case), or based on a real process, like decompressing and uploading tiles. :beer: :) For comparison, many "text scrambler" effects for appearing/disappearing text i've seen used in animation/sfx seem to just take a seed and dish out some RND product based on that and the current frame. I think random functions often feel a little cheap/superficially imposed; because they often are. Such can be done with AfterEffects scripts, but there's also commercial plugins for the same for those who don't have the time. Sorry for the side note.

Re: Bagel NES CHR compression.

Posted: Tue Jan 17, 2017 5:35 pm
by tepples
I have some ideas for improving the encoder's command-line options.

In main_encode_blocks it encodes the file as a set of independent banks, each in turn made up of pages that are swizzled together. Currently, you have hardcoded 64 blocks (4096 bytes) per page and 2 pages per bank, but I have ideas for options to change this. For example, a bank of four 2048-byte pages might be helpful for Super Mario Bros. 3-style CHR rotation in an MMC3 cart with 32K CHR RAM. Or 1024-byte pages might be helpful when loading things that remain constant across all pages of a character's sprite animation, such as a projectile that remains on screen as the player switches to other CHR banks.

I'd also like an option to write out a header listing the offset to the start of each bank's compressed data. This is important for things like RHDE, which need random access to 64-byte units (which would be 1 block in Bagel) to decode furniture graphics in the Furnish menu.

Code: Select all

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -d, --decompress      decode the input file
  -b, --bytes=SIZE      put SIZE bytes (multiple of 64) per page
  -I, --interleave=NUM  interleave NUM pages together (requires -b)
  --header              write the block count, interleave size, and byte
                        offset to subsequent pages (or interleaved sets)
  -o FILE, --output FILE
                        output to FILE instead of last positional arg
I'm willing to add these features myself. Do you have a public version control repository for Bagel? Or should I just attach diffs in replies to this topic?

Re: Bagel NES CHR compression.

Posted: Wed Jan 18, 2017 9:28 am
by JRoatch
It might be faster for you to improve on the encoder's features.

I can try today and we'll see how far I can get Maybe this next weekend I can try something. I also needed an option to disable inner block referencing, as some streaming setups can't guarantee an intact buffer.
tepples wrote:I'd also like an option to write out a header listing the offset to the start of each bank's compressed data.
I'm assuming this would be the same format as the address list in pb53.
tepples wrote:I'm willing to add these features myself. Do you have a public version control repository for Bagel? Or should I just attach diffs in replies to this topic?
I do not have a public repository. Feel free to place it in any of yours. I believe I got the software licencing attached correctly, GPLv3 for the python encoder, and all permissive for the decoder.

Re: Bagel NES CHR compression.

Posted: Fri Feb 24, 2017 4:46 am
by JRoatch
I should post this now even though It's missing decoding, but this is my idea for accommodating your encoding options.

The header if used is encoded in 2 bytes: YYYYYIII nnnnnnnn
n = number of blocks per interleave (0 means 256)
I = number of interleaves per segment minus 1
Y = number of segments (unimplemented)

For the case of non interleaved pages, the first byte is then 0.