shithub: pokecrystal

Download patch

ref: 35de889dd714744c8657190bbee6cae743e34f2d
parent: 99d2ee2bdc0c3ed7206a91bbeee61b32c83584ca
author: yenatch <[email protected]>
date: Mon Aug 19 23:34:54 EDT 2013

split out decompression

--- /dev/null
+++ b/engine/decompress.asm
@@ -1,0 +1,367 @@
+FarDecompress: ; b40
+; Decompress graphics data at a:hl to de
+
+; put a away for a sec
+	ld [$c2c4], a
+; save bank
+	ld a, [hROMBank]
+	push af
+; bankswitch
+	ld a, [$c2c4]
+	rst Bankswitch
+	
+; what we came here for
+	call Decompress
+	
+; restore bank
+	pop af
+	rst Bankswitch
+	ret
+; b50
+
+
+Decompress: ; b50
+; Pokemon Crystal uses an lz variant for compression.
+
+; This is mainly used for graphics, but the intro's
+; tilemaps also use this compression.
+
+; This function decompresses lz-compressed data at hl to de.
+
+
+; Basic rundown:
+
+;	A typical control command consists of:
+;		-the command (bits 5-7)
+;		-the count (bits 0-4)
+;		-and any additional params
+
+;	$ff is used as a terminator.
+
+
+;	Commands:
+
+;		0: literal
+;			literal data for some number of bytes
+;		1: iterate
+;			one byte repeated for some number of bytes
+;		2: alternate
+;			two bytes alternated for some number of bytes
+;		3: zero (whitespace)
+;			0x00 repeated for some number of bytes
+
+;	Repeater control commands have a signed parameter used to determine the start point.
+;	Wraparound is simulated:
+;		Positive values are added to the start address of the decompressed data
+;		and negative values are subtracted from the current position.
+
+;		4: repeat
+;			repeat some number of bytes from decompressed data
+;		5: flipped
+;			repeat some number of flipped bytes from decompressed data
+;			ex: $ad = %10101101 -> %10110101 = $b5
+;		6: reverse
+;			repeat some number of bytes in reverse from decompressed data
+
+;	If the value in the count needs to be larger than 5 bits,
+;	control code 7 can be used to expand the count to 10 bits.
+
+;		A new control command is read in bits 2-4.
+;		The new 10-bit count is split:
+;			bits 0-1 contain the top 2 bits
+;			another byte is added containing the latter 8
+
+;		So, the structure of the control command becomes:
+;			111xxxyy yyyyyyyy
+;			 |  |  |    |
+;            |  | our new count
+;            | the control command for this count
+;            7 (this command)
+
+; For more information, refer to the code below and in extras/gfx.py .
+
+; save starting output address
+	ld a, e
+	ld [$c2c2], a
+	ld a, d
+	ld [$c2c3], a
+	
+.loop
+; get next byte
+	ld a, [hl]
+; done?
+	cp $ff ; end
+	ret z
+
+; get control code
+	and %11100000
+	
+; 10-bit param?
+	cp $e0 ; LZ_HI
+	jr nz, .normal
+	
+	
+; 10-bit param:
+
+; get next 3 bits (%00011100)
+	ld a, [hl]
+	add a
+	add a ; << 3
+	add a
+	
+; this is our new control code
+	and %11100000
+	push af
+	
+; get param hi
+	ld a, [hli]
+	and %00000011
+	ld b, a
+	
+; get param lo
+	ld a, [hli]
+	ld c, a
+	
+; read at least 1 byte
+	inc bc
+	jr .readers
+	
+	
+.normal
+; push control code
+	push af
+; get param
+	ld a, [hli]
+	and %00011111
+	ld c, a
+	ld b, $0
+; read at least 1 byte
+	inc c
+	
+.readers
+; let's get started
+
+; inc loop counts since we bail as soon as they hit 0
+	inc b
+	inc c
+	
+; get control code
+	pop af
+; command type
+	bit 7, a ; 80, a0, c0
+	jr nz, .repeatertype
+	
+; literals
+	cp $20 ; LZ_ITER
+	jr z, .iter
+	cp $40 ; LZ_ALT
+	jr z, .alt
+	cp $60 ; LZ_ZERO
+	jr z, .zero
+	; else $00
+	
+; 00 ; LZ_LIT
+; literal data for bc bytes
+.loop1
+; done?
+	dec c
+	jr nz, .next1
+	dec b
+	jp z, .loop
+	
+.next1
+	ld a, [hli]
+	ld [de], a
+	inc de
+	jr .loop1
+	
+	
+; 20 ; LZ_ITER
+; write byte for bc bytes
+.iter
+	ld a, [hli]
+	
+.iterloop
+	dec c
+	jr nz, .iternext
+	dec b
+	jp z, .loop
+	
+.iternext
+	ld [de], a
+	inc de
+	jr .iterloop
+	
+	
+; 40 ; LZ_ALT
+; alternate two bytes for bc bytes
+
+; next pair
+.alt
+; done?
+	dec c
+	jr nz, .alt0
+	dec b
+	jp z, .altclose0
+	
+; alternate for bc
+.alt0
+	ld a, [hli]
+	ld [de], a
+	inc de
+	dec c
+	jr nz, .alt1
+; done?
+	dec b
+	jp z, .altclose1
+.alt1
+	ld a, [hld]
+	ld [de], a
+	inc de
+	jr .alt
+	
+; skip past the bytes we were alternating
+.altclose0
+	inc hl
+.altclose1
+	inc hl
+	jr .loop
+	
+	
+; 60 ; LZ_ZERO
+; write 00 for bc bytes
+.zero
+	xor a
+	
+.zeroloop
+	dec c
+	jr nz, .zeronext
+	dec b
+	jp z, .loop
+	
+.zeronext
+	ld [de], a
+	inc de
+	jr .zeroloop
+	
+	
+; repeats
+; 80, a0, c0
+; repeat decompressed data from output
+.repeatertype
+	push hl
+	push af
+; get next byte
+	ld a, [hli]
+; absolute?
+	bit 7, a
+	jr z, .absolute
+	
+; relative
+; a = -a
+	and %01111111 ; forget the bit we just looked at
+	cpl
+; add de (current output address)
+	add e
+	ld l, a
+	ld a, $ff ; -1
+	adc d
+	ld h, a
+	jr .repeaters
+	
+.absolute
+; get next byte (lo)
+	ld l, [hl]
+; last byte (hi)
+	ld h, a
+; add starting output address
+	ld a, [$c2c2]
+	add l
+	ld l, a
+	ld a, [$c2c3]
+	adc h
+	ld h, a
+	
+.repeaters
+	pop af
+	cp $80 ; LZ_REPEAT
+	jr z, .repeat
+	cp $a0 ; LZ_FLIP
+	jr z, .flip
+	cp $c0 ; LZ_REVERSE
+	jr z, .reverse
+	
+; e0 -> 80
+	
+; 80 ; LZ_REPEAT
+; repeat some decompressed data
+.repeat
+; done?
+	dec c
+	jr nz, .repeatnext
+	dec b
+	jr z, .cleanup
+	
+.repeatnext
+	ld a, [hli]
+	ld [de], a
+	inc de
+	jr .repeat
+	
+	
+; a0 ; LZ_FLIP
+; repeat some decompressed data w/ flipped bit order
+.flip
+	dec c
+	jr nz, .flipnext
+	dec b
+	jp z, .cleanup
+	
+.flipnext
+	ld a, [hli]
+	push bc
+	ld bc, $0008
+	
+.fliploop
+	rra
+	rl b
+	dec c
+	jr nz, .fliploop
+	ld a, b
+	pop bc
+	ld [de], a
+	inc de
+	jr .flip
+	
+	
+; c0 ; LZ_REVERSE
+; repeat some decompressed data in reverse
+.reverse
+	dec c
+	jr nz, .reversenext
+	
+	dec b
+	jp z, .cleanup
+	
+.reversenext
+	ld a, [hld]
+	ld [de], a
+	inc de
+	jr .reverse
+	
+	
+.cleanup
+; get type of repeat we just used
+	pop hl
+; was it relative or absolute?
+	bit 7, [hl]
+	jr nz, .next
+
+; skip two bytes for absolute
+	inc hl
+; skip one byte for relative
+.next
+	inc hl
+	jp .loop
+; c2f
+
--- a/main.asm
+++ b/main.asm
@@ -1314,374 +1314,7 @@
 ; b40
 
 
-FarDecompress: ; b40
-; Decompress graphics data at a:hl to de
-
-; put a away for a sec
-	ld [$c2c4], a
-; save bank
-	ld a, [hROMBank]
-	push af
-; bankswitch
-	ld a, [$c2c4]
-	rst Bankswitch
-	
-; what we came here for
-	call Decompress
-	
-; restore bank
-	pop af
-	rst Bankswitch
-	ret
-; b50
-
-
-Decompress: ; b50
-; Pokemon Crystal uses an lz variant for compression.
-
-; This is mainly used for graphics, but the intro's
-; tilemaps also use this compression.
-
-; This function decompresses lz-compressed data at hl to de.
-
-
-; Basic rundown:
-
-;	A typical control command consists of:
-;		-the command (bits 5-7)
-;		-the count (bits 0-4)
-;		-and any additional params
-
-;	$ff is used as a terminator.
-
-
-;	Commands:
-
-;		0: literal
-;			literal data for some number of bytes
-;		1: iterate
-;			one byte repeated for some number of bytes
-;		2: alternate
-;			two bytes alternated for some number of bytes
-;		3: zero (whitespace)
-;			0x00 repeated for some number of bytes
-
-;	Repeater control commands have a signed parameter used to determine the start point.
-;	Wraparound is simulated:
-;		Positive values are added to the start address of the decompressed data
-;		and negative values are subtracted from the current position.
-
-;		4: repeat
-;			repeat some number of bytes from decompressed data
-;		5: flipped
-;			repeat some number of flipped bytes from decompressed data
-;			ex: $ad = %10101101 -> %10110101 = $b5
-;		6: reverse
-;			repeat some number of bytes in reverse from decompressed data
-
-;	If the value in the count needs to be larger than 5 bits,
-;	control code 7 can be used to expand the count to 10 bits.
-
-;		A new control command is read in bits 2-4.
-;		The new 10-bit count is split:
-;			bits 0-1 contain the top 2 bits
-;			another byte is added containing the latter 8
-
-;		So, the structure of the control command becomes:
-;			111xxxyy yyyyyyyy
-;			 |  |  |    |
-;            |  | our new count
-;            | the control command for this count
-;            7 (this command)
-
-; For more information, refer to the code below and in extras/gfx.py .
-
-; save starting output address
-	ld a, e
-	ld [$c2c2], a
-	ld a, d
-	ld [$c2c3], a
-	
-.loop
-; get next byte
-	ld a, [hl]
-; done?
-	cp $ff ; end
-	ret z
-
-; get control code
-	and %11100000
-	
-; 10-bit param?
-	cp $e0 ; LZ_HI
-	jr nz, .normal
-	
-	
-; 10-bit param:
-
-; get next 3 bits (%00011100)
-	ld a, [hl]
-	add a
-	add a ; << 3
-	add a
-	
-; this is our new control code
-	and %11100000
-	push af
-	
-; get param hi
-	ld a, [hli]
-	and %00000011
-	ld b, a
-	
-; get param lo
-	ld a, [hli]
-	ld c, a
-	
-; read at least 1 byte
-	inc bc
-	jr .readers
-	
-	
-.normal
-; push control code
-	push af
-; get param
-	ld a, [hli]
-	and %00011111
-	ld c, a
-	ld b, $0
-; read at least 1 byte
-	inc c
-	
-.readers
-; let's get started
-
-; inc loop counts since we bail as soon as they hit 0
-	inc b
-	inc c
-	
-; get control code
-	pop af
-; command type
-	bit 7, a ; 80, a0, c0
-	jr nz, .repeatertype
-	
-; literals
-	cp $20 ; LZ_ITER
-	jr z, .iter
-	cp $40 ; LZ_ALT
-	jr z, .alt
-	cp $60 ; LZ_ZERO
-	jr z, .zero
-	; else $00
-	
-; 00 ; LZ_LIT
-; literal data for bc bytes
-.loop1
-; done?
-	dec c
-	jr nz, .next1
-	dec b
-	jp z, .loop
-	
-.next1
-	ld a, [hli]
-	ld [de], a
-	inc de
-	jr .loop1
-	
-	
-; 20 ; LZ_ITER
-; write byte for bc bytes
-.iter
-	ld a, [hli]
-	
-.iterloop
-	dec c
-	jr nz, .iternext
-	dec b
-	jp z, .loop
-	
-.iternext
-	ld [de], a
-	inc de
-	jr .iterloop
-	
-	
-; 40 ; LZ_ALT
-; alternate two bytes for bc bytes
-
-; next pair
-.alt
-; done?
-	dec c
-	jr nz, .alt0
-	dec b
-	jp z, .altclose0
-	
-; alternate for bc
-.alt0
-	ld a, [hli]
-	ld [de], a
-	inc de
-	dec c
-	jr nz, .alt1
-; done?
-	dec b
-	jp z, .altclose1
-.alt1
-	ld a, [hld]
-	ld [de], a
-	inc de
-	jr .alt
-	
-; skip past the bytes we were alternating
-.altclose0
-	inc hl
-.altclose1
-	inc hl
-	jr .loop
-	
-	
-; 60 ; LZ_ZERO
-; write 00 for bc bytes
-.zero
-	xor a
-	
-.zeroloop
-	dec c
-	jr nz, .zeronext
-	dec b
-	jp z, .loop
-	
-.zeronext
-	ld [de], a
-	inc de
-	jr .zeroloop
-	
-	
-; repeats
-; 80, a0, c0
-; repeat decompressed data from output
-.repeatertype
-	push hl
-	push af
-; get next byte
-	ld a, [hli]
-; absolute?
-	bit 7, a
-	jr z, .absolute
-	
-; relative
-; a = -a
-	and %01111111 ; forget the bit we just looked at
-	cpl
-; add de (current output address)
-	add e
-	ld l, a
-	ld a, $ff ; -1
-	adc d
-	ld h, a
-	jr .repeaters
-	
-.absolute
-; get next byte (lo)
-	ld l, [hl]
-; last byte (hi)
-	ld h, a
-; add starting output address
-	ld a, [$c2c2]
-	add l
-	ld l, a
-	ld a, [$c2c3]
-	adc h
-	ld h, a
-	
-.repeaters
-	pop af
-	cp $80 ; LZ_REPEAT
-	jr z, .repeat
-	cp $a0 ; LZ_FLIP
-	jr z, .flip
-	cp $c0 ; LZ_REVERSE
-	jr z, .reverse
-	
-; e0 -> 80
-	
-; 80 ; LZ_REPEAT
-; repeat some decompressed data
-.repeat
-; done?
-	dec c
-	jr nz, .repeatnext
-	dec b
-	jr z, .cleanup
-	
-.repeatnext
-	ld a, [hli]
-	ld [de], a
-	inc de
-	jr .repeat
-	
-	
-; a0 ; LZ_FLIP
-; repeat some decompressed data w/ flipped bit order
-.flip
-	dec c
-	jr nz, .flipnext
-	dec b
-	jp z, .cleanup
-	
-.flipnext
-	ld a, [hli]
-	push bc
-	ld bc, $0008
-	
-.fliploop
-	rra
-	rl b
-	dec c
-	jr nz, .fliploop
-	ld a, b
-	pop bc
-	ld [de], a
-	inc de
-	jr .flip
-	
-	
-; c0 ; LZ_REVERSE
-; repeat some decompressed data in reverse
-.reverse
-	dec c
-	jr nz, .reversenext
-	
-	dec b
-	jp z, .cleanup
-	
-.reversenext
-	ld a, [hld]
-	ld [de], a
-	inc de
-	jr .reverse
-	
-	
-.cleanup
-; get type of repeat we just used
-	pop hl
-; was it relative or absolute?
-	bit 7, [hl]
-	jr nz, .next
-
-; skip two bytes for absolute
-	inc hl
-; skip one byte for relative
-.next
-	inc hl
-	jp .loop
-; c2f
-
-
+INCLUDE "engine/decompress.asm"
 
 
 UpdatePalsIfCGB: ; c2f