Help with a routine

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Help with a routine

Post by sludge »

A few years ago someone on the WoS site wrote me a 2x2 tile printing routine, I managed to adapt it for 4x4 and 2x1 tiles no problem.

Now I want to use it for 1x2 tiles but have encountered difficulties.

Despite the original block of code coming annotated I spent the best part of last evening trying to work out where its going wrong but to no avail.

Maybe someone on here can work out whats gone wrong?

Code: Select all

org 60000-4
	
xcor			db	0
ycor			db	0
gnum			db 	1
nop 


do_tile:		;draw&colour tile (gnum) at x,y

	ld a,(gnum)	;get tile number
	call get_tile	;find the correct graphic data
	ld de,(xcor)	;point D at ycor, E at xcor
	call xy2screen	;find screen position
	push de		;save screen position
	call draw_tile
	pop de		;get screen position back
	call screen2att	;find corresponding attribute
	call colour_tile
	ret

graphicsource	dw	graphics

	;
draw_tile		;arrive with HL pointing at graphic, DE at screen

	ld b,16		;16 lines per tile
ptlp	ld a,(hl)	;puy 2 bytes of graphic data on screen
	ld (de),a
	inc e
	inc hl

;	ld a,(hl)
;	ld (de),a	;part of original code
;	inc hl

	dec e		;back to start of line

	call nextlinedn	;move DE down one line
	djnz ptlp
	ret
	;
colour_tile		;DE pointing at attributes, HL at colours

	ex de,hl	;better with HL at attributes, DE at colours
	ld a,(de)
	ld (hl),a
	inc de
	inc l
	ld a,(de)
;	ld (hl),a	;dont need to colour this cell
	inc de
	ld bc,32
	add hl,bc
	ld a,(de)
;	ld (hl),a	;dont need to colour this cell
	inc de
	dec l
	ld a,(de)
	ld (hl),a
	ret
	
get_tile		;tile graphic & attrs are 36 bytes apart, so need to multiply A by 36

	ld h,0
	ld l,a
	add hl,hl	;x2
	ld b,h		;store x 2 value in BC
	ld c,l

	add hl,hl	;x4
	add hl,hl	;x8
	add hl,hl	;x16

;	add hl,hl	;x32
;	add hl,bc	;x36	;part of original code

	inc hl
	inc hl		;increase by 2 attributes

	ld bc,graphics
	add hl,bc	;HL now pointing at correct graphic
	ret
	
screen2att:		;change DE at screen to DE at attribute

	ld a,d
	rra
	rra
	rra
	and 3
	or 88
	ld d,a
	ret
	
xy2screen:		;arrive with d=y (0-23), e=x (0-31),convert to corresponding char square on screen

	ld a,d
	rrca
	rrca
	rrca
	and 224
	or e
	ld e,a
	ld a,d
	and 24
	or 64
	ld d,a
	ret
	
nextlinedn		;converts DE to next line down, modified from various

	ld a,d
	inc d
	cp 7
	ret nz
	ld a,e
	add a,32
	ld e,a
	ret c
	ld a,d
	sub 8
	ld d,a
	ret
	
graphics

	defb 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 6, 0, 0
	defb 71, 69	;tile 1


	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2

User avatar
g0blinish
Manic Miner
Posts: 287
Joined: Sun Jun 17, 2018 2:54 pm

Re: Help with a routine

Post by g0blinish »

Code: Select all

nextlinedn		;converts DE to next line down, modified from various
;replaced to routine
nbde    INC D:LD A,D:AND 7:RET NZ
        LD A,E:ADD A,#20:LD E,A:RET C
        LD A,D:SUB 8:LD D,A:RET

User avatar
R-Tape
Site Admin
Posts: 6415
Joined: Thu Nov 09, 2017 11:46 am

Re: Help with a routine

Post by R-Tape »

Hi @sludge. That was based on my code from way back. Not sure what went wrong with the 'nextlinedown' routine, but that was one of the problems as goblinish points out.

Here's a fix. Compare the extra bits I blanked out - you tried to draw and colour sideways when you only need to go down. Also, your 'get tile' routine wouldn't work for more than two tiles. Your tiles are 18 bytes apart, so you need to multiply by 18 - multiplying by 16 and adding 2 is not the same thing - see how I changed it.

Looking forward to the next deathsquad release!

Code: Select all

org 32768
do_tile:		;draw&colour tile (gnum) at x,y

	ld a,(gnum)	;get tile number
	call get_tile	;find the correct graphic data
	ld de,(xcor)	;point D at ycor, E at xcor
	call xy2screen	;find screen position
	push de		;save screen position
	call draw_tile
	pop de		;get screen position back
	call screen2att	;find corresponding attribute
	call colour_tile
	ret
	;
xcor			db	8
ycor			db	8
gnum			db 	8

graphicsource	dw	graphics

	;
draw_tile		;arrive with HL pointing at graphic, DE at screen

	ld b,16		;16 lines per tile
ptlp	ld a,(hl)	;puy 2 bytes of graphic data on screen
	ld (de),a
;	inc e
	inc hl

;	ld a,(hl)
;	ld (de),a	;part of original code
;	inc hl

;	dec e		;back to start of line

	call nextlinedn	;move DE down one line
	djnz ptlp
	ret
	;
colour_tile		;DE pointing at attributes, HL at colours

	ex de,hl	;better with HL at attributes, DE at colours
	ld a,(de)
	ld (hl),a
	inc de
;	inc l
;	ld a,(de)
;	ld (hl),a	;dont need to colour this cell
;	inc de
	ld bc,32
	add hl,bc
	ld a,(de)
	ld (hl),a	;dont need to colour this cell
;	inc de
;	dec l
;	ld a,(de)
;	ld (hl),a
	ret
	
get_tile		;tile graphic & attrs are 36 bytes apart, so need to multiply A by 36
	ld h,0
	ld l,a
	add hl,hl	;x2
	
	ld b,h
	ld c,l

	add hl,hl	;x4
	add hl,hl	;x8
	add hl,hl	;x16
	add hl,bc	;x18

	ld bc,graphics
	add hl,bc	;HL now pointing at correct graphic
	ret
	
screen2att:		;change DE at screen to DE at attribute

	ld a,d
	rra
	rra
	rra
	and 3
	or 88
	ld d,a
	ret
	
xy2screen:		;arrive with d=y (0-23), e=x (0-31),convert to corresponding char square on screen

	ld a,d
	rrca
	rrca
	rrca
	and 224
	or e
	ld e,a
	ld a,d
	and 24
	or 64
	ld d,a
	ret
	
nextlinedn		;converts DE to next line down, modified from various
	inc d
	ld a,d
	and 7
	ret nz
	ld a,e
	add a,32
	ld e,a
	ret c
	ld a,d
	sub 8
	ld d,a
	ret
	
graphics

	defb 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 6, 0, 0
	defb 71, 69	;tile 1


	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
	defb 0, 0, 54, 127, 127, 107, 107, 62, 0, 65, 127, 62, 0, 54, 48, 0
	defb 71, 69	;tile 2
User avatar
sludge
Drutt
Posts: 33
Joined: Sat Feb 24, 2024 4:38 pm

Re: Help with a routine

Post by sludge »

Thanks very much guys, I'll have a good study when I get back in this afternoon.

I thought it could have been one of yours R-Tape, I've modified it many a time over the years but always to increase size.

Reducing size (horizontally) stumped me, I woke up 5.15am this morning and thats all I could think of.

Thankyou both!
Post Reply