shithub: pokered

Download patch

ref: f6038a3d52a2d26271fdcba9639284301305d751
parent: 5a14234b49e8870a33b80fb768928c194756255c
author: yenatch <yenatch@gmail.com>
date: Sun May 25 15:23:12 EDT 2014

Try to clean up PrepareOAMData.

--- /dev/null
+++ b/engine/oam_dma.asm
@@ -1,0 +1,25 @@
+WriteDMACodeToHRAM:
+; Since no other memory is available during OAM DMA,
+; DMARoutine is copied to HRAM and executed there.
+	ld c, $ff80 % $100
+	ld b, DMARoutineEnd - DMARoutine
+	ld hl, DMARoutine
+.copy
+	ld a, [hli]
+	ld [$ff00+c], a
+	inc c
+	dec b
+	jr nz, .copy
+	ret
+
+DMARoutine:
+	; initiate DMA
+	ld a, $c3
+	ld [$ff46], a
+
+	; wait for DMA to finish
+	ld a, $28
+.wait	dec a
+	jr nz, .wait
+	ret
+DMARoutineEnd:
--- /dev/null
+++ b/engine/overworld/oam.asm
@@ -1,0 +1,178 @@
+PrepareOAMData:
+; Determine OAM data for currently visible
+; sprites and write it to wOAMBuffer.
+
+	ld a, [$cfcb]
+	dec a
+	jr z, .asm_4b1e
+
+	cp 0 - 1
+	ret nz
+	ld [$cfcb], a
+	jp HideSprites
+
+.asm_4b1e
+	xor a
+	ld [$ff90], a
+.asm_4b21
+	ld [$ff8f], a
+
+	ld d, wSpriteStateData1 / $100
+	ld a, [$ff8f]
+	ld e, a
+	ld a, [de] ; c1x0
+	and a
+	jp z, .asm_4bad
+
+	inc e
+	inc e
+	ld a, [de] ; c1x2 (facing/anim)
+	ld [$d5cd], a
+	cp $ff ; off-screen (don't draw)
+	jr nz, .visible
+
+	call Func_4bd1
+	jr .asm_4bad
+
+.visible
+	cp $a0
+	jr c, .usefacing
+	and $f
+	add $10
+	jr .asm_4b48
+
+.usefacing
+	and $f
+.asm_4b48
+	ld l, a
+
+	push de
+	inc d
+	ld a, e
+	add $5
+	ld e, a
+	ld a, [de] ; c2x7
+	and $80
+	ld [$ff94], a ; temp store sprite priority
+	pop de
+
+	ld h, 0
+	ld bc, SpriteFacingAndAnimationTable
+	add hl, hl
+	add hl, hl
+	add hl, bc
+
+	ld a, [hli]
+	ld c, a
+	ld a, [hli]
+	ld b, a
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+
+	call Func_4bd1
+
+	ld a, [$ff90]
+	ld e, a
+	ld d, wOAMBuffer / $100
+.tile
+	ld a, [$ff92]            ; temp for sprite Y position
+	add $10                  ; Y=16 is top of screen (Y=0 is invisible)
+	add [hl]                 ; add Y offset from table
+	ld [de], a               ; write new sprite OAM Y position
+	inc hl
+	ld a, [$ff91]            ; temp for sprite X position
+	add $8                   ; X=8 is left of screen (X=0 is invisible)
+	add [hl]                 ; add X offset from table
+	inc e
+	ld [de], a               ; write new sprite OAM X position
+	inc e
+	ld a, [bc]               ; read pattern number offset (accomodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
+	inc bc
+	push bc
+	ld b, a
+
+	ld a, [$d5cd]            ; temp copy of c1x2
+	swap a                   ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
+	and $f
+
+	; Sprites $a and $b have one face (and therefore 4 tiles instead of 12).
+	; As a result, sprite $b's tile offset is less than normal.
+	cp $b
+	jr nz, .offset
+	ld a, $a * 12 + 4
+	jr .gotoffset
+
+.offset
+	; a *= 12
+	sla a
+	sla a
+	ld c, a
+	sla a
+	add c
+.gotoffset
+	add b ; which frame
+	pop bc
+	ld [de], a ; tile id
+	inc hl
+	inc e
+	ld a, [hl]
+	bit 1, a ; sprite priority
+	jr z, .fg
+	ld a, [$ff94] ; facing priority
+	or [hl]
+.fg
+	inc hl
+	ld [de], a
+	inc e
+	bit 0, a ; OAMFLAG_ENDOFDATA
+	jr z, .tile
+
+	ld a, e
+	ld [$ff90], a
+
+.asm_4bad
+	ld a, [$ff8f]
+	add $10
+	cp $100 % $100
+	jp nz, .asm_4b21
+
+	; Clear unused OAM.
+	ld a, [$ff90]
+	ld l, a
+	ld h, wOAMBuffer / $100
+	ld de, $4
+	ld b, $a0
+	ld a, [$d736]
+	bit 6, a
+	ld a, $a0
+	jr z, .clear
+	ld a, $90
+.clear
+	cp l
+	ret z
+	ld [hl], b
+	add hl, de
+	jr .clear
+
+Func_4bd1: ; 4bd1 (1:4bd1)
+	inc e
+	inc e
+	ld a, [de] ; c1x4
+	ld [$ff92], a
+	inc e
+	inc e
+	ld a, [de] ; c1x6
+	ld [$ff91], a
+	ld a, $4
+	add e
+	ld e, a
+	ld a, [$ff92]
+	add $4
+	and $f0
+	ld [de], a ; c1xa (y)
+	inc e
+	ld a, [$ff91]
+	and $f0
+	ld [de], a  ; c1xb (x)
+	ret
--- a/main.asm
+++ b/main.asm
@@ -139,184 +139,8 @@
 	db "マスター@"
 	db "エクセレント"
 
-; calculates the OAM data for all currently visible sprites and writes it to wOAMBuffer
-PrepareOAMData: ; 4b0f (1:4b0f)
-	ld a, [$cfcb]
-	dec a
-	jr z, .asm_4b1e
-	cp $ff
-	ret nz
-	ld [$cfcb], a
-	jp HideSprites
-.asm_4b1e
-	xor a
-	ld [$ff90], a
-.asm_4b21
-	ld [$ff8f], a
-	ld d, $c1
-	ld a, [$ff8f]
-	ld e, a
-	ld a, [de]         ; c1x0
-	and a
-	jp z, .asm_4bad
-	inc e
-	inc e
-	ld a, [de]         ; c1x2 read combined orientation and animation info
-	ld [$d5cd], a
-	cp $ff
-	jr nz, .spriteVisible   ; $ff -> offscreen, don't draw
-	call Func_4bd1
-	jr .asm_4bad
-.spriteVisible
-	cp $a0
-	jr c, .considerOrientation ; if >= $a0, ignore the sprite orientation and animation (by using a different conversion table)
-	and $f
-	add $10
-	jr .asm_4b48
-.considerOrientation
-	and $f                     ; the lower nybble contains orientation and animation info
-.asm_4b48
-	ld l, a
-	push de
-	inc d
-	ld a, e
-	add $5
-	ld e, a
-	ld a, [de]         ; c2x7
-	and $80
-	ld [$ff94], a          ; temp store bit 7 for later use in OAM flags (draws sprite behind background (used for grass))
-	pop de
-	ld h, $0
-	ld bc, SpriteFacingAndAnimationTable
-	add hl, hl
-	add hl, hl
-	add hl, bc                 ; skip to the table location determined by orientation and animation
-	ld a, [hli]
-	ld c, a
-	ld a, [hli]
-	ld b, a
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	call Func_4bd1
-	ld a, [$ff90]
-	ld e, a
-	ld d, $c3                ; wOAMBuffer+x is buffer for OAM data
-.spriteTilesLoop             ; loops 4 times for the 4 tiles a sprite consists of
-	ld a, [$ff92]        ; temp for sprite Y position
-	add $10                  ; Y=16 is top of screen (Y=0 is invisible)
-	add [hl]                 ; add Y offset from table
-	ld [de], a               ; write new sprite OAM Y position
-	inc hl
-	ld a, [$ff91]        ; temp for sprite X position
-	add $8                   ; X=8 is left of screen (X=0 is invisible)
-	add [hl]                 ; add X offset from table
-	inc e
-	ld [de], a               ; write new sprite OAM X position
-	inc e
-	ld a, [bc]               ; read pattern number offset (accomodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
-	inc bc
-	push bc
-	ld b, a
-	ld a, [$d5cd]            ; temp copy of c1x2
-	swap a                   ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
-	and $f
-	cp $b                    ; sprites $a and $b have no orientation or animation and therefore only 4 tiles
-	jr nz, .calcTileOffset   ; (instead of 12), so tile b's offset is a special case
-	ld a, $7c                ; = $a * 12 + 4
-	jr .doneCalcTileOffset
-.calcTileOffset
-	sla a
-	sla a
-	ld c, a
-	sla a
-	add c                    ; a *= 12 (each sprite consists of 12 tiles)
-.doneCalcTileOffset
-	add b                    ; add orientation and animation offset
-	pop bc
-	ld [de], a               ; write OAM sprite pattern number
-	inc hl
-	inc e
-	ld a, [hl]
-	bit 1, a                 ; bit 1 is ignored for OAM, it's used here as an "always in foregroud" flag.
-	jr z, .alwaysInForeground
-	ld a, [$ff94]        ; load bit 7 (set to $80 if sprite is in grass and should be drawn behind it)
-	or [hl]
-.alwaysInForeground
-	inc hl
-	ld [de], a               ; write OAM sprite flags
-	inc e
-	bit 0, a                 ; test for OAMFLAG_ENDOFDATA
-	jr z, .spriteTilesLoop
-	ld a, e
-	ld [$ff90], a
-.asm_4bad
-	ld a, [$ff8f]
-	add $10
-	cp $0
-	jp nz, .asm_4b21
-	ld a, [$ff90]
-	ld l, a
-	ld h, $c3
-	ld de, $4
-	ld b, $a0
-	ld a, [$d736]
-	bit 6, a
-	ld a, $a0
-	jr z, .clearUnusedOAMEntriesLoop
-	ld a, $90
-.clearUnusedOAMEntriesLoop
-	cp l
-	ret z
-	ld [hl], b
-	add hl, de
-	jr .clearUnusedOAMEntriesLoop
-
-Func_4bd1: ; 4bd1 (1:4bd1)
-	inc e
-	inc e
-	ld a, [de]            ; c1x4
-	ld [$ff92], a
-	inc e
-	inc e
-	ld a, [de]            ; c1x6
-	ld [$ff91], a
-	ld a, $4
-	add e
-	ld e, a
-	ld a, [$ff92]
-	add $4
-	and $f0
-	ld [de], a            ; c1xa (sprite Y pos (snapped to whole steps (?))
-	inc e
-	ld a, [$ff91]
-	and $f0
-	ld [de], a            ; c1xb (sprite X pos (snapped to whole steps (?))
-	ret
-
-; copies DMA routine to HRAM. By GB specifications, all DMA needs to be done in HRAM (no other memory section is available during DMA)
-WriteDMACodeToHRAM: ; 4bed (1:4bed)
-	ld c, $80
-	ld b, $a
-	ld hl, DMARoutine
-.copyLoop
-	ld a, [hli]
-	ld [$ff00+c], a
-	inc c
-	dec b
-	jr nz, .copyLoop
-	ret
-
-; this routine is copied to HRAM and executed there on every VBlank
-DMARoutine: ; 4bfb (1:4bfb)
-	ld a, $c3
-	ld [$ff46], a   ; start DMA
-	ld a, $28
-.waitLoop               ; wait for DMA to finish
-	dec a
-	jr nz, .waitLoop
-	ret
-
+INCLUDE "engine/overworld/oam.asm"
+INCLUDE "engine/oam_dma.asm"
 
 PrintWaitingText:
 	FuncCoord 3, 10