Alright! I'm here. And with the scrolling / tilemapping routine all in one. I can't remeber who developed this, but much thanks to them. Now onto the code, basically viewx and viewy are what control the window. Increasing either by 32 will cause the engine to rotate one pixel next cycle. This way, you can have the screen scroll 2 pixels if viewx is 64, and so on. viewx and viewy can also be less than 32, scrolling the map less than one pixel per frame. Quite useful, and comes with a tilemapping routine! Here is the code:
Code: ;------------------
;- backgroundDraw -
;------------------
; this is the all-purpose scrolling routine!
; no need to modify anything here, just cut-and-paste
backgroundDraw:
di
ld a,$80
out ($10),a;row inc mode
ld hl,(viewX)
call convHLtoPixels
ld a,l
cpl
and 7
add a,a
ld h,0
ld l,a
ld bc,shfXadrs
add hl,bc
ld a,(hl)
ld (shfXadr),a
inc hl
ld a,(hl)
ld (shfXadr+1),a
ld hl,(viewY)
call convHLtoPixels
ld a,l
and 7
ld (shfY),a
;viewY/8 * mapWidth
ld hl,(viewY)
ld a,(mapWidth)
ld e,a
Mul8b:; this routine performs the operation HL=H*E
ld d,0; clearing D and L
ld l,d
ld b,8; we have 8 bits
Mul8bLoop:
add hl,hl; advancing a bit
jp nc,Mul8bSkip; if zero, we skip the addition (jp is used for speed)
add hl,de
Mul8bSkip:
djnz Mul8bLoop
ex de,hl
;viewX/8
ld hl,(viewX)
ld l,h
ld h,0
add hl,de
ld de,(mapAdress)
add hl,de;hl = tilemappos
ld ix,plotsscreen
ld a,$20
ld c,a
bigloop:
;increment column
inc c
out ($10),a
push bc
push ix;save plotsscreen
;=== draw upper tile
ld a,(shfY)
ld (Ybegin),a
cpl
and 7
inc a
ld (Ylength),a
;=== set row to zero (temp between here)
ld a,$80
out ($10),a
push hl
call drawtile
pop hl
ld de,(mapWidth)
add hl,de
;=== draw middle 7 tiles
ld a,8
ld (Ylength),a
xor a
ld (Ybegin),a
ld b,7
midloop:
push bc
push hl
call drawtile
pop hl
pop bc
ld de,(mapWidth)
add hl,de
djnz midloop
;=== draw bottom tile
ld a,(shfY)
and 7
ld (Ylength),a
xor a
ld (Ybegin),a
push hl
call drawtile
pop hl
;ld de,32
;add hl,de
ex de,hl
ld hl,(mapWidth)
add hl,hl
add hl,hl
add hl,hl
ex de,hl
or a
sbc hl,de
inc hl
pop ix
inc ix
pop bc
ld a,c
cp $20+12
jr nz,bigloop
ret
;========================
; drawtile
;========================
; this is needed by drawBackground!
; INPUT: hl = tile
; YScroll = mod(Y/
drawtile:
push hl
ld a,(hl)
ld h,0
ld l,a
add hl,hl
add hl,hl
add hl,hl
ld de,tiles
add hl,de
Ybegin = $+1
ld bc,$00
add hl,bc;add Y scroll
ex de,hl;de = tilepos 1
pop hl
inc hl
ld a,(hl)
ld h,0
ld l,a
add hl,hl
add hl,hl
add hl,hl
push bc
ld bc,tiles
add hl,bc
pop bc
add hl,bc;add Y scroll
;hl = tilepos 2
Ylength = $+1
ld b,0
ld a,b
or a
ret z
push hl
ld hl,(shfXadr)
jp (hl)
shf1:
pop hl
shf1loop:
ld a,(de)
ld c,a
ld a,(hl)
srl c
rr a
call screenupd
djnz shf1loop
ret
shf2:
pop hl
shf2loop:
ld a,(de)
ld c,a
ld a,(hl)
srl c
rr a
srl c
rr a
call screenupd
djnz shf2loop
ret
shf3:
pop hl
shf3loop:
ld a,(de)
ld c,a
ld a,(hl)
srl c
rr a
srl c
rr a
srl c
rr a
call screenupd
djnz shf3loop
ret
shf4:
pop hl
shf4loop:
ld a,(de)
ld c,a
ld a,(hl)
srl c
rr a
srl c
rr a
srl c
rr a
srl c
rr a
call screenupd
djnz shf4loop
ret
shf5:
pop hl
shf5loop:
ld a,(de)
ld c,(hl)
.db $CB, $31;SLL c (unsupported by tasm)
rl a
.db $CB, $31
rl a
.db $CB, $31
rl a
call screenupd
djnz shf5loop
ret
shf6:
pop hl
shf6loop:
ld a,(de)
ld c,(hl)
.db $CB, $31
rl a
.db $CB, $31
rl a
call screenupd
djnz shf6loop
ret
shf7:
pop hl
shf7loop:
ld a,(de)
ld c,(hl)
.db $CB, $31
rl a
call screenupd
djnz shf7loop
ret
shf8:
pop hl
shf8loop:
ld a,(de)
call screenupd
djnz shf8loop
ret
screenupd:
push bc
ld b,(ix)
xor b
out ($11),a
ld bc,12
add ix,bc
pop bc
inc hl
inc de
ret
shfY: .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
shfXadr: .dw 0
shfXadrs: .dw shf1, shf2, shf3, shf4
.dw shf5, shf6, shf7, shf8
speed: .dw 0
speed2: .dw 0
time: .dw 0
time2: .dw 0
angle: .dw 0
angle2: .dw 0
angle3: .dw 0
calcmapvar: .dw 0
hlvar: .dw 0
;=== convHLtoPixels
; drawBackground and drawTile need this routine!
; INPUT: HL
; converts the detailed fixed point coord in HL to coord in pixels
; hl = (BBBBBBBB BBB.BBBBB) -> (BBB BBBBBBBB)
convHLtoPixels:
push de
ld d,h
ld e,l
srl d
rr e
srl d
rr e
srl d
rr e
srl d
rr e
srl d
rr e
ld h,d
ld l,e
pop de
ret
;=====================
;=== MAP VARIABLES ===
;=====================
; this are the variables needed by the map drawing routines
; you can change these in-game, of course!
; viewX is the X location of the left boundary of the screen.
; viewY is the Y location of the upper boundary of the screen.
; You can increase/decrease the coordinates by increasing/decreasing
; it by 32. You can also increase it by less then one pixel,
; this will make the screen increase/decrease by one pixel each few frames.
viewX: .dw 0;starting X
viewY: .dw 0;starting Y
;viewx equ saferam2
;viewy equ saferam2+5
mapAdress: .dw map;location of current map
mapWidth: .db 20;width of current map (in # of tiles)
.db 0;just leave this here
;================
;=== MAP DATA ===
;================
; here comes your map!
Map:;data examples
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
.db 1,0,1,0,1,0,1,0,1,0,1,0,2,1,2,1,2,1,2,1
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,2,1,2,1,2,1,2
;=================
;=== TILE DATA ===
;=================
; here come your tiles!
Tiles:
.db 00,00,00,00,00,00,00,00;tile 0
.db %00010000;tile 1
.db %10000010
.db %00100000
.db %00000100
.db %01000000
.db %00010010
.db %00000000
.db %10000100
.db %01010101
.db %10101010
.db %01010101
.db %10101010
.db %01010101
.db %10101010
.db %01010101
.db %10101010
Copy and paste, and let me know if you have difficulties, I may have left something out.
-Mike |