The Lush Engine








Introduction
Background
Introduction
bgtiles.asm
bgtiled.asm
bgtilem.asm
putstile.asm
putdtile.asm
puthtile.asm
putvtile.asm
putmtile.asm
wallmeld.asm
Math
Objects
Palettes
Tiles
Utilities

Wall Meld Routine

The following file is a routine written for the expedition project which corrects the display of the wall tiles in the background or window. There are two files for this routine, the actual routine and it's accompanying data table.

You can download the files as well if you don't want to cut and paste the text.

wallmeld.asm
walltab.asm

To download the files using a PC, right-click a link and select the option "Save Target As" then save the file as you would any other file from windows.

Explanation

Source

;*************************************************************
; 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

;********************************
; walltab.asm
;  data file for wallmeld.asm
;********************************
 DB 00,00,00,00,00,00,00,07,00,00
 DB 00,00,00,00,00,07,00,00,00,00
 DB 00,00,00,04,00,00,00,00,08,04
 DB 08,04,00,00,00,00,00,07,00,07
 DB 00,00,00,00,00,07,00,07,00,00
 DB 00,00,00,00,00,04,00,00,00,00
 DB 08,04,08,04,00,00,00,06,00,03
 DB 00,03,00,06,00,06,00,03,00,03
 DB 00,02,05,02,01,13,01,13,00,02
 DB 05,02,01,13,01,13,00,00,00,00
 DB 00,03,00,03,00,06,00,06,00,03
 DB 00,03,05,02,05,02,01,13,01,13
 DB 05,02,05,02,01,13,01,12,00,00
 DB 00,00,00,00,00,07,00,00,00,00
 DB 00,00,00,07,00,00,00,00,08,04
 DB 08,04,00,00,00,00,08,04,08,04
 DB 00,00,00,00,00,00,00,00,00,00
 DB 00,00,00,00,00,07,00,00,00,00
 DB 00,04,00,04,00,00,00,00,08,04
 DB 08,04,00,06,00,06,00,03,00,03
 DB 00,06,00,06,00,03,00,03,00,02
 DB 00,02,01,13,01,13,00,02,05,02
 DB 01,13,01,09,00,06,00,06,00,03
 DB 00,03,00,06,00,06,00,03,00,03
 DB 05,02,05,02,01,13,01,12,05,02
 DB 05,02,01,11,01,13

Buttons created using the interactive button maker at Coolarchive