Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Space Harrier II graphics compression #27

Open
DevsArchive opened this issue Jan 8, 2022 · 0 comments
Open

Space Harrier II graphics compression #27

DevsArchive opened this issue Jan 8, 2022 · 0 comments
Assignees

Comments

@DevsArchive
Copy link

DevsArchive commented Jan 8, 2022

Space Harrier 2 has an interesting, but simple graphics compression algorithm.

It has a 32 byte decompression buffer for holding decompressed tile data. For each tile, it'll use a list of bitfields that describe the places in the decompression buffer to copy a field's corresponding byte into. It is then finished off with a string of bytes that then fill up the rest of the unwritten to spots. The buffer is then copied to VRAM and it loops. It does this until it hits a termination flag.

; ---------------------------------------------------------------------------
; Space Harrier II graphics decompression
; VDP write command should be set before calling this
; ---------------------------------------------------------------------------
; PARAMETERS:
;	a0.l - Pointer to compressed art
; ---------------------------------------------------------------------------

SH2GfxDecomp:
		lea	$FFF2C0.w,a3		; Decompression buffer
		moveq	#0,d0			; Buffer write flags

		moveq	#0,d2			; Get number of bitfield copies for this tile
		move.b	(a0)+,d2
		beq.w	.CopyRest		; If there are none, branch
		bmi.w	.End			; If this is the end of the compressed data, branch
		subq.w	#1,d2			; Subtract 1 for dbf

; ---------------------------------------------------------------------------

.GetCopyPattern:
		lea	$FFF2C0.w,a2		; Decompression buffer
		movea.l a2,a3

		move.b	(a0)+,d3		; Get byte to copy
		move.b	(a0)+,d4		; Get copy pattern
		lsl.w	#8,d4
		move.b	(a0)+,d4
		lsl.l	#8,d4
		move.b	(a0)+,d4
		lsl.l	#8,d4
		move.b	(a0)+,d4
		or.l	 d4,d0			; Mark spots in pattern as written to

		moveq	#32-1,d7		; Start checking which places in buffer to copy byte into

.CopyByteLoop:
		lsl.l	#1,d4			; Shift copy pattern and get MSB
		bcc.w	.AdvanceCopy		; If the byte shouldn't be written to this spot, branch
		move.b	d3,(a2)			; If it should, write it

.AdvanceCopy:
		addq.l	#1,a2			; Go to next byte in buffer
		dbf	d7,.CopyByteLoop	; Loop until the whole copy pattern is scanned
		dbf	d2,.GetCopyPattern	; Loop until all copy patterns are scanned for this tile

; ---------------------------------------------------------------------------

		moveq	#$FFFFFFFF,d1		; Is the whole buffer filled up?
		eor.l	d0,d1
		beq.w	.CopyToVRAM		; If so, branch

.CopyRest:
		moveq	#32-1,d7		; Start copying the rest of the tile data

.CopyRestLoop:
		lsl.l	#1,d0			; Shift remaining pattern and get MSB
		bcs.w	.AdvanceRest		; If the next byte shouldn't be written to this spot, branch
		move.b	(a0)+,(a3)		; Copy byte and advance

.AdvanceRest:
		addq.l	#1,a3			; Go to next byte in buffer
		dbf	d7,.CopyRestLoop	; Loop until the rest of the buffer is filled up

; ---------------------------------------------------------------------------

.CopyToVRAM:
		lea	$FFF2C0.w,a6		; Copy buffer to VRAM
		lea	$C00000,a5
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)
		move.l	(a6)+,(a5)

		bra.s	SH2GfxDecomp		; Loop back to start for next tile

.End:
		rts
@flamewing flamewing self-assigned this Jan 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants