;*************************************************************
; Procedure Name  : wall_meld
;
; Author          : Marc Gale (Xalthorn or Eldara)
;
; Description     : Written for the Expedition project, this
;                   procedure scans the background (or window,
;                   as the base address is passed to it) for
;                   any wall tiles, and corrects the actual
;                   image used based on the surrounding tiles.
;
; On Entry        : B  = Tile number used for the wall topping
;                   C  = First tile of the wall set
;                   HL = Base Map address
;
; During          : All registers are used
;
; On Exit         : Nothing intentional
;*************************************************************
wall_meld
 ld     a,0
 ldh    [$4F],a         ; make sure we're playing with bank 0

 ld     d,0             ; initialise the y counter
.yloop:
 ld     e,0             ; initialise the x counter
.xloop:
 ld     a,0             ; initialise the flag byte
 push   af              ; preserve it

 push   bc              ; preserve bc

 ld     a,[hl]          ; grab the current tile
 cp     a,b             ; are we the filler tile?
 jr     z,.continue     ; if so, continue
 cp     a,c             ; are we higher than the low number?
 jr     c,.nocheck      ; if not, don't bother doing the checks
 ld     a,c             ; get the wall set number
 add    a,12            ; add twelve to it
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the current tile again
 cp     a,c             ; are we still in the wall set?
 jr     nc,.nocheck     ; if not, don't bother doing the checks
 jr     .continue

.nocheck
 pop    bc              ; restore bc
 pop    af              ; restore af (don't fill the stack)
 jp     .donedrawing    ; next tile

.continue
 pop    bc              ; restore bc

.row1:
 ld     a,d             ; grab the y counter
 cp     0               ; is it 0, the top of the map?
 jr     z,.row2         ; if so we can't do a row up

 ld     a,l             ; subtract 32 from hl to move
 sub    a,32            ; up a row
 ld     l,a             ; .
 ld     a,h             ; .
 sbc    a,0             ; .
 ld     h,a             ; .

.row1left:
 ld     a,e             ; get the x counter
 cp     0               ; is it 0, the left of the map?
 jr     z,.row1middle   ; if so, we can't go left

 dec    hl              ; move left one tile

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row1lefta:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row1leftb   ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af (a is the flag byte)
 set    7,a             ; set bit 7 (128)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row1leftdone   ; done this position, move to next
.row1leftb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row1leftdone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data again
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row1leftdone; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    7,a             ; set bit 7 (128)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row1leftdone:
 pop    bc              ; restore bc
 inc    hl              ; move right one

.row1middle:
 ld     a,[hl]          ; grab the map data
 push   bc              ; preserve bc
.row1middlea:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row1middleb ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    0,a             ; set bit 0 (1)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row1middledone ; we're done here, move to next
.row1middleb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row1middledone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12
 ld     c,a             ; put it back
 ld     a,[hl]          ; get the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row1middledone ; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    0,a             ; set bit 0 (1)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row1middledone:
 pop    bc              ; restore bc

.row1right:
 ld     a,e             ; get the x counter
 cp     31              ; is it 31, right hand edge?
 jr     z,.donerow1     ; if so, we can't go right

 inc    hl              ; move right one tile

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row1righta:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row1rightb  ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    1,a             ; set bit 1 (2)
 push   af              ; preserve af
 push   bc              ; preserve bc

 jr     .row1rightdone  ; we're done here
.row1rightb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row1rightdone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row1rightdone ; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    1,a             ; set bit 1 (2)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row1rightdone:
 pop    bc              ; restore bc
 dec    hl              ; move left one

.donerow1:
 push   de              ; preserve de

 ld     de,32           ; move down a row
 add    hl,de           ;

 pop    de              ; restore de

.row2:
.row2left:
 ld     a,e             ; get the x counter
 cp     0               ; is it 0, left hand edge?
 jr     z,.row2middle   ; if so, we can't go left

 dec    hl              ; move left one tile

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row2lefta:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row2leftb   ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    6,a             ; set bit 6 (64)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row2leftdone   ; we're done here
.row2leftb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row2leftdone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row2leftdone ; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    6,a             ; set bit 6 (64)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row2leftdone:
 pop    bc              ; restore bc
 inc    hl              ; move right one

.row2middle:

; nothing to do here, this is the square we're setting

.row2right:
 ld     a,e             ; get the x counter
 cp     31              ; is it 31, right hand edge?
 jr     z,.row3         ; if so, we can't go right

 inc    hl              ; move right one tile

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row2righta:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row2rightb   ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    2,a             ; set bit 2 (4)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row2rightdone  ; we're done here
.row2rightb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row2rightdone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12 to it
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row2rightdone ; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    2,a             ; set bit 2 (4)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row2rightdone:
 pop    bc              ; restore bc
 dec    hl              ; move left one

.row3:
 ld     a,d             ; get the y counter
 cp     31              ; is it 31, bottom edge?
 jr     z,.donerows     ; if so, we can't go down

 push   de              ; move down one row,
 ld     de,32           ; preserving and restoring
 add    hl,de           ; de as they are used for
 pop    de              ; the addition

.row3left:
 ld     a,e             ; get the x counter
 cp     0               ; is it 0, the left hand edge?
 jr     z,.row3middle   ; if so, we can't go left

 dec    hl              ; move left one tile

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row3lefta:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row3leftb   ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    5,a             ; set bit 5 (32)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row3leftdone   ; we're done here
.row3leftb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row3leftdone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12 to it
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row3leftdone ; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    5,a             ; set bit 5 (32)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row3leftdone:
 pop    bc              ; restore bc

 inc    hl              ; move right one

.row3middle:

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row3middlea:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row3middleb   ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    4,a             ; set bit 4 (16)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row3middledone ; we're done here
.row3middleb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row3middledone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12 to it
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row3middledone ; if not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    4,a             ; set bit 4 (16)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row3middledone:
 pop    bc              ; restore bc

.row3right:
 ld     a,e             ; get the x counter
 cp     31              ; is it 31, the right hand edge?
 jr     z,.donerow3     ; if so, we can't go right

 inc    hl              ; move right one tile

 ld     a,[hl]          ; grab the tile data

 push   bc              ; preserve bc
.row3righta:
 cp     a,b             ; is it the filler tile?
 jr     nz,.row3rightb   ; if not, try the walls
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    3,a             ; set bit 3 (8)
 push   af              ; preserve af
 push   bc              ; preserve bc
 jr     .row3rightdone  ; we're done here
.row3rightb:
 cp     a,c             ; are we higher than the low number?
 jr     c,.row3rightdone ; if not, we're done here
 ld     a,c             ; get the wall base number
 add    a,12            ; add 12 to it
 ld     c,a             ; put it back
 ld     a,[hl]          ; grab the map data
 cp     a,c             ; are we still in the wall set?
 jr     nc,.row3rightdone ; it not, we're done here
; found wall, set the bit
 pop    bc              ; restore bc
 pop    af              ; restore af
 set    3,a             ; set bit 3 (8)
 push   af              ; preserve af
 push   bc              ; preserve bc
.row3rightdone:
 pop    bc              ; restore bc
 dec    hl              ; move left one

.donerow3:
 ld     a,l             ; subtract 32 from hl,
 sub    a,32            ; bringing it up one row
 ld     l,a             ;
 ld     a,h             ;
 sbc    a,0             ;
 ld     h,a             ;
.donerows:
; okay, now we should have a byte set with the correct bits, let's
; get it into a
 pop    af              ; restore af

 push   hl              ; preserve the map pointer
 ld     hl,walltable    ; get the address of the data table
 push   de              ; preserve the counters
 ld     d,0             ; add a to hl
 ld     e,a             ; .
 add    hl,de           ; .
 pop    de              ; restore the counters
 ld     a,[hl]          ; grab the data from the table
 pop    hl              ; restore the map pointer
 cp     0               ; is the entry 0, nothing to set?
 jr     z,.donedrawing  ; if so, we're done here
 cp     13              ; is the entry the filler value
 jr     nz,.drawwall    ; if not, test the wall values
.drawfiller:
 ld     a,b             ; put the filler number in a
 jr     .dodraw         ; go draw the tile
.drawwall:
 add    a,c             ; add the wall reference to the base
 dec    a               ; value and subtract one
.dodraw:
 ld     [hl],a          ; put the data on the map

.donedrawing:
 inc    hl              ; move to the next tile

 inc    e               ; increase the x counter
 ld     a,e             ; get the x counter
 cp     32              ; have we done 32 tiles (one row)
 jp     nz,.xloop       ; if not, go back and do another

 inc    d               ; increase the y counter
 ld     a,d             ; get the y counter
 cp     32              ; have we done 32 rows?
 jp     nz,.yloop       ; if not, go back and do another

 ret                    ; we're done, return
