summaryrefslogtreecommitdiff
path: root/home/pic.asm
diff options
context:
space:
mode:
Diffstat (limited to 'home/pic.asm')
-rw-r--r--home/pic.asm591
1 files changed, 0 insertions, 591 deletions
diff --git a/home/pic.asm b/home/pic.asm
deleted file mode 100644
index cfc39f0f..00000000
--- a/home/pic.asm
+++ /dev/null
@@ -1,591 +0,0 @@
-; bankswitches and runs _UncompressSpriteData
-; bank is given in a, sprite input stream is pointed to in wSpriteInputPtr
-UncompressSpriteData::
- ld b, a
- ld a, [hLoadedROMBank]
- push af
- ld a, b
- ld [hLoadedROMBank], a
- ld [MBC1RomBank], a
- ld a, SRAM_ENABLE
- ld [MBC1SRamEnable], a
- xor a
- ld [MBC1SRamBank], a
- call _UncompressSpriteData
- pop af
- ld [hLoadedROMBank], a
- ld [MBC1RomBank], a
- ret
-
-; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop
-_UncompressSpriteData::
- ld hl, sSpriteBuffer1
- ld c, (2*SPRITEBUFFERSIZE) % $100
- ld b, (2*SPRITEBUFFERSIZE) / $100
- xor a
- call FillMemory ; clear sprite buffer 1 and 2
- ld a, $1
- ld [wSpriteInputBitCounter], a
- ld a, $3
- ld [wSpriteOutputBitOffset], a
- xor a
- ld [wSpriteCurPosX], a
- ld [wSpriteCurPosY], a
- ld [wSpriteLoadFlags], a
- call ReadNextInputByte ; first byte of input determines sprite width (high nybble) and height (low nybble) in tiles (8x8 pixels)
- ld b, a
- and $f
- add a
- add a
- add a
- ld [wSpriteHeight], a
- ld a, b
- swap a
- and $f
- add a
- add a
- add a
- ld [wSpriteWidth], a
- call ReadNextInputBit
- ld [wSpriteLoadFlags], a ; initialite bit1 to 0 and bit0 to the first input bit
- ; this will load two chunks of data to sSpriteBuffer1 and sSpriteBuffer2
- ; bit 0 decides in which one the first chunk is placed
- ; fall through
-
-; uncompresses a chunk from the sprite input data stream (pointed to at wd0da) into sSpriteBuffer1 or sSpriteBuffer2
-; each chunk is a 1bpp sprite. A 2bpp sprite consist of two chunks which are merged afterwards
-; note that this is an endless loop which is terminated during a call to MoveToNextBufferPosition by manipulating the stack
-UncompressSpriteDataLoop::
- ld hl, sSpriteBuffer1
- ld a, [wSpriteLoadFlags]
- bit 0, a
- jr z, .useSpriteBuffer1 ; check which buffer to use
- ld hl, sSpriteBuffer2
-.useSpriteBuffer1
- call StoreSpriteOutputPointer
- ld a, [wSpriteLoadFlags]
- bit 1, a
- jr z, .startDecompression ; check if last iteration
- call ReadNextInputBit ; if last chunk, read 1-2 bit unpacking mode
- and a
- jr z, .unpackingMode0 ; 0 -> mode 0
- call ReadNextInputBit ; 1 0 -> mode 1
- inc a ; 1 1 -> mode 2
-.unpackingMode0
- ld [wSpriteUnpackMode], a
-.startDecompression
- call ReadNextInputBit
- and a
- jr z, .readRLEncodedZeros ; if first bit is 0, the input starts with zeroes, otherwise with (non-zero) input
-.readNextInput
- call ReadNextInputBit
- ld c, a
- call ReadNextInputBit
- sla c
- or c ; read next two bits into c
- and a
- jr z, .readRLEncodedZeros ; 00 -> RLEncoded zeroes following
- call WriteSpriteBitsToBuffer ; otherwise write input to output and repeat
- call MoveToNextBufferPosition
- jr .readNextInput
-.readRLEncodedZeros
- ld c, $0 ; number of zeroes it length encoded, the number
-.countConsecutiveOnesLoop ; of consecutive ones determines the number of bits the number has
- call ReadNextInputBit
- and a
- jr z, .countConsecutiveOnesFinished
- inc c
- jr .countConsecutiveOnesLoop
-.countConsecutiveOnesFinished
- ld a, c
- add a
- ld hl, LengthEncodingOffsetList
- add l
- ld l, a
- jr nc, .noCarry
- inc h
-.noCarry
- ld a, [hli] ; read offset that is added to the number later on
- ld e, a ; adding an offset of 2^length - 1 makes every integer uniquely
- ld d, [hl] ; representable in the length encoding and saves bits
- push de
- inc c
- ld e, $0
- ld d, e
-.readNumberOfZerosLoop ; reads the next c+1 bits of input
- call ReadNextInputBit
- or e
- ld e, a
- dec c
- jr z, .readNumberOfZerosDone
- sla e
- rl d
- jr .readNumberOfZerosLoop
-.readNumberOfZerosDone
- pop hl ; add the offset
- add hl, de
- ld e, l
- ld d, h
-.writeZerosLoop
- ld b, e
- xor a ; write 00 to buffer
- call WriteSpriteBitsToBuffer
- ld e, b
- call MoveToNextBufferPosition
- dec de
- ld a, d
- and a
- jr nz, .continueLoop
- ld a, e
- and a
-.continueLoop
- jr nz, .writeZerosLoop
- jr .readNextInput
-
-; moves output pointer to next position
-; also cancels the calling function if the all output is done (by removing the return pointer from stack)
-; and calls postprocessing functions according to the unpack mode
-MoveToNextBufferPosition::
- ld a, [wSpriteHeight]
- ld b, a
- ld a, [wSpriteCurPosY]
- inc a
- cp b
- jr z, .curColumnDone
- ld [wSpriteCurPosY], a
- ld a, [wSpriteOutputPtr]
- inc a
- ld [wSpriteOutputPtr], a
- ret nz
- ld a, [wSpriteOutputPtr+1]
- inc a
- ld [wSpriteOutputPtr+1], a
- ret
-.curColumnDone
- xor a
- ld [wSpriteCurPosY], a
- ld a, [wSpriteOutputBitOffset]
- and a
- jr z, .bitOffsetsDone
- dec a
- ld [wSpriteOutputBitOffset], a
- ld hl, wSpriteOutputPtrCached
- ld a, [hli]
- ld [wSpriteOutputPtr], a
- ld a, [hl]
- ld [wSpriteOutputPtr+1], a
- ret
-.bitOffsetsDone
- ld a, $3
- ld [wSpriteOutputBitOffset], a
- ld a, [wSpriteCurPosX]
- add $8
- ld [wSpriteCurPosX], a
- ld b, a
- ld a, [wSpriteWidth]
- cp b
- jr z, .allColumnsDone
- ld a, [wSpriteOutputPtr]
- ld l, a
- ld a, [wSpriteOutputPtr+1]
- ld h, a
- inc hl
- jp StoreSpriteOutputPointer
-.allColumnsDone
- pop hl
- xor a
- ld [wSpriteCurPosX], a
- ld a, [wSpriteLoadFlags]
- bit 1, a
- jr nz, .done ; test if there is one more sprite to go
- xor $1
- set 1, a
- ld [wSpriteLoadFlags], a
- jp UncompressSpriteDataLoop
-.done
- jp UnpackSprite
-
-; writes 2 bits (from a) to the output buffer (pointed to from wSpriteOutputPtr)
-WriteSpriteBitsToBuffer::
- ld e, a
- ld a, [wSpriteOutputBitOffset]
- and a
- jr z, .offset0
- cp $2
- jr c, .offset1
- jr z, .offset2
- rrc e ; offset 3
- rrc e
- jr .offset0
-.offset1
- sla e
- sla e
- jr .offset0
-.offset2
- swap e
-.offset0
- ld a, [wSpriteOutputPtr]
- ld l, a
- ld a, [wSpriteOutputPtr+1]
- ld h, a
- ld a, [hl]
- or e
- ld [hl], a
- ret
-
-; reads next bit from input stream and returns it in a
-ReadNextInputBit::
- ld a, [wSpriteInputBitCounter]
- dec a
- jr nz, .curByteHasMoreBitsToRead
- call ReadNextInputByte
- ld [wSpriteInputCurByte], a
- ld a, $8
-.curByteHasMoreBitsToRead
- ld [wSpriteInputBitCounter], a
- ld a, [wSpriteInputCurByte]
- rlca
- ld [wSpriteInputCurByte], a
- and $1
- ret
-
-; reads next byte from input stream and returns it in a
-ReadNextInputByte::
- ld a, [wSpriteInputPtr]
- ld l, a
- ld a, [wSpriteInputPtr+1]
- ld h, a
- ld a, [hli]
- ld b, a
- ld a, l
- ld [wSpriteInputPtr], a
- ld a, h
- ld [wSpriteInputPtr+1], a
- ld a, b
- ret
-
-; the nth item is 2^n - 1
-LengthEncodingOffsetList::
- dw %0000000000000001
- dw %0000000000000011
- dw %0000000000000111
- dw %0000000000001111
- dw %0000000000011111
- dw %0000000000111111
- dw %0000000001111111
- dw %0000000011111111
- dw %0000000111111111
- dw %0000001111111111
- dw %0000011111111111
- dw %0000111111111111
- dw %0001111111111111
- dw %0011111111111111
- dw %0111111111111111
- dw %1111111111111111
-
-; unpacks the sprite data depending on the unpack mode
-UnpackSprite::
- ld a, [wSpriteUnpackMode]
- cp $2
- jp z, UnpackSpriteMode2
- and a
- jp nz, XorSpriteChunks
- ld hl, sSpriteBuffer1
- call SpriteDifferentialDecode
- ld hl, sSpriteBuffer2
- ; fall through
-
-; decodes differential encoded sprite data
-; input bit value 0 preserves the current bit value and input bit value 1 toggles it (starting from initial value 0).
-SpriteDifferentialDecode::
- xor a
- ld [wSpriteCurPosX], a
- ld [wSpriteCurPosY], a
- call StoreSpriteOutputPointer
- ld a, [wSpriteFlipped]
- and a
- jr z, .notFlipped
- ld hl, DecodeNybble0TableFlipped
- ld de, DecodeNybble1TableFlipped
- jr .storeDecodeTablesPointers
-.notFlipped
- ld hl, DecodeNybble0Table
- ld de, DecodeNybble1Table
-.storeDecodeTablesPointers
- ld a, l
- ld [wSpriteDecodeTable0Ptr], a
- ld a, h
- ld [wSpriteDecodeTable0Ptr+1], a
- ld a, e
- ld [wSpriteDecodeTable1Ptr], a
- ld a, d
- ld [wSpriteDecodeTable1Ptr+1], a
- ld e, $0 ; last decoded nybble, initialized to 0
-.decodeNextByteLoop
- ld a, [wSpriteOutputPtr]
- ld l, a
- ld a, [wSpriteOutputPtr+1]
- ld h, a
- ld a, [hl]
- ld b, a
- swap a
- and $f
- call DifferentialDecodeNybble ; decode high nybble
- swap a
- ld d, a
- ld a, b
- and $f
- call DifferentialDecodeNybble ; decode low nybble
- or d
- ld b, a
- ld a, [wSpriteOutputPtr]
- ld l, a
- ld a, [wSpriteOutputPtr+1]
- ld h, a
- ld a, b
- ld [hl], a ; write back decoded data
- ld a, [wSpriteHeight]
- add l ; move on to next column
- jr nc, .noCarry
- inc h
-.noCarry
- ld [wSpriteOutputPtr], a
- ld a, h
- ld [wSpriteOutputPtr+1], a
- ld a, [wSpriteCurPosX]
- add $8
- ld [wSpriteCurPosX], a
- ld b, a
- ld a, [wSpriteWidth]
- cp b
- jr nz, .decodeNextByteLoop ; test if current row is done
- xor a
- ld e, a
- ld [wSpriteCurPosX], a
- ld a, [wSpriteCurPosY] ; move on to next row
- inc a
- ld [wSpriteCurPosY], a
- ld b, a
- ld a, [wSpriteHeight]
- cp b
- jr z, .done ; test if all rows finished
- ld a, [wSpriteOutputPtrCached]
- ld l, a
- ld a, [wSpriteOutputPtrCached+1]
- ld h, a
- inc hl
- call StoreSpriteOutputPointer
- jr .decodeNextByteLoop
-.done
- xor a
- ld [wSpriteCurPosY], a
- ret
-
-; decodes the nybble stored in a. Last decoded data is assumed to be in e (needed to determine if initial value is 0 or 1)
-DifferentialDecodeNybble::
- srl a ; c=a%2, a/=2
- ld c, $0
- jr nc, .evenNumber
- ld c, $1
-.evenNumber
- ld l, a
- ld a, [wSpriteFlipped]
- and a
- jr z, .notFlipped ; determine if initial value is 0 or one
- bit 3, e ; if flipped, consider MSB of last data
- jr .selectLookupTable
-.notFlipped
- bit 0, e ; else consider LSB
-.selectLookupTable
- ld e, l
- jr nz, .initialValue1 ; load the appropriate table
- ld a, [wSpriteDecodeTable0Ptr]
- ld l, a
- ld a, [wSpriteDecodeTable0Ptr+1]
- jr .tableLookup
-.initialValue1
- ld a, [wSpriteDecodeTable1Ptr]
- ld l, a
- ld a, [wSpriteDecodeTable1Ptr+1]
-.tableLookup
- ld h, a
- ld a, e
- add l
- ld l, a
- jr nc, .noCarry
- inc h
-.noCarry
- ld a, [hl]
- bit 0, c
- jr nz, .selectLowNybble
- swap a ; select high nybble
-.selectLowNybble
- and $f
- ld e, a ; update last decoded data
- ret
-
-DecodeNybble0Table::
- dn $0, $1
- dn $3, $2
- dn $7, $6
- dn $4, $5
- dn $f, $e
- dn $c, $d
- dn $8, $9
- dn $b, $a
-DecodeNybble1Table::
- dn $f, $e
- dn $c, $d
- dn $8, $9
- dn $b, $a
- dn $0, $1
- dn $3, $2
- dn $7, $6
- dn $4, $5
-DecodeNybble0TableFlipped::
- dn $0, $8
- dn $c, $4
- dn $e, $6
- dn $2, $a
- dn $f, $7
- dn $3, $b
- dn $1, $9
- dn $d, $5
-DecodeNybble1TableFlipped::
- dn $f, $7
- dn $3, $b
- dn $1, $9
- dn $d, $5
- dn $0, $8
- dn $c, $4
- dn $e, $6
- dn $2, $a
-
-; combines the two loaded chunks with xor (the chunk loaded second is the destination). The source chunk is differeintial decoded beforehand.
-XorSpriteChunks::
- xor a
- ld [wSpriteCurPosX], a
- ld [wSpriteCurPosY], a
- call ResetSpriteBufferPointers
- ld a, [wSpriteOutputPtr] ; points to buffer 1 or 2, depending on flags
- ld l, a
- ld a, [wSpriteOutputPtr+1]
- ld h, a
- call SpriteDifferentialDecode ; decode buffer 1 or 2, depending on flags
- call ResetSpriteBufferPointers
- ld a, [wSpriteOutputPtr] ; source buffer, points to buffer 1 or 2, depending on flags
- ld l, a
- ld a, [wSpriteOutputPtr+1]
- ld h, a
- ld a, [wSpriteOutputPtrCached] ; destination buffer, points to buffer 2 or 1, depending on flags
- ld e, a
- ld a, [wSpriteOutputPtrCached+1]
- ld d, a
-.xorChunksLoop
- ld a, [wSpriteFlipped]
- and a
- jr z, .notFlipped
- push de
- ld a, [de]
- ld b, a
- swap a
- and $f
- call ReverseNybble ; if flipped reverse the nybbles in the destination buffer
- swap a
- ld c, a
- ld a, b
- and $f
- call ReverseNybble
- or c
- pop de
- ld [de], a
-.notFlipped
- ld a, [hli]
- ld b, a
- ld a, [de]
- xor b
- ld [de], a
- inc de
- ld a, [wSpriteCurPosY]
- inc a
- ld [wSpriteCurPosY], a ; go to next row
- ld b, a
- ld a, [wSpriteHeight]
- cp b
- jr nz, .xorChunksLoop ; test if column finished
- xor a
- ld [wSpriteCurPosY], a
- ld a, [wSpriteCurPosX]
- add $8
- ld [wSpriteCurPosX], a ; go to next column
- ld b, a
- ld a, [wSpriteWidth]
- cp b
- jr nz, .xorChunksLoop ; test if all columns finished
- xor a
- ld [wSpriteCurPosX], a
- ret
-
-; reverses the bits in the nybble given in register a
-ReverseNybble::
- ld de, NybbleReverseTable
- add e
- ld e, a
- jr nc, .noCarry
- inc d
-.noCarry
- ld a, [de]
- ret
-
-; resets sprite buffer pointers to buffer 1 and 2, depending on wSpriteLoadFlags
-ResetSpriteBufferPointers::
- ld a, [wSpriteLoadFlags]
- bit 0, a
- jr nz, .buffer2Selected
- ld de, sSpriteBuffer1
- ld hl, sSpriteBuffer2
- jr .storeBufferPointers
-.buffer2Selected
- ld de, sSpriteBuffer2
- ld hl, sSpriteBuffer1
-.storeBufferPointers
- ld a, l
- ld [wSpriteOutputPtr], a
- ld a, h
- ld [wSpriteOutputPtr+1], a
- ld a, e
- ld [wSpriteOutputPtrCached], a
- ld a, d
- ld [wSpriteOutputPtrCached+1], a
- ret
-
-; maps each nybble to its reverse
-NybbleReverseTable::
- db $0, $8, $4, $c, $2, $a, $6 ,$e, $1, $9, $5, $d, $3, $b, $7 ,$f
-
-; combines the two loaded chunks with xor (the chunk loaded second is the destination). Both chunks are differeintial decoded beforehand.
-UnpackSpriteMode2::
- call ResetSpriteBufferPointers
- ld a, [wSpriteFlipped]
- push af
- xor a
- ld [wSpriteFlipped], a ; temporarily clear flipped flag for decoding the destination chunk
- ld a, [wSpriteOutputPtrCached]
- ld l, a
- ld a, [wSpriteOutputPtrCached+1]
- ld h, a
- call SpriteDifferentialDecode
- call ResetSpriteBufferPointers
- pop af
- ld [wSpriteFlipped], a
- jp XorSpriteChunks
-
-; stores hl into the output pointers
-StoreSpriteOutputPointer::
- ld a, l
- ld [wSpriteOutputPtr], a
- ld [wSpriteOutputPtrCached], a
- ld a, h
- ld [wSpriteOutputPtr+1], a
- ld [wSpriteOutputPtrCached+1], a
- ret