Slow big letter routine...

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
zup
Manic Miner
Posts: 209
Joined: Wed Jul 08, 2020 8:42 am

Slow big letter routine...

Post by zup »

I'm bored, so I thought on flooding CSSCGC with crappy minigames. The trouble is that my first routines are too crappy to be crappy :/

My games are going to have this (self imposed) restrictions:
- I'm going to use ZX Spin to enter the code.
- They're going to be 100% BASIC programs, without any machine code.
- The games must seem to be "amateur", so they can't have optimizations beyond the obvious.
- They're going to have many common routines.

One of my first routines is a "big letter" drawing routine. The games must be slow (so BASIC use is obvious), but this routine is awfully slow.

This is my code:

Code: Select all

1 LET score=23: GO SUB 9998: GO SUB 9950
8999 GO TO 9999
9700 REM PLOT PRINT
9720 LET x1=x: FOR i=1 TO LEN s$: IF s$(i)=" " THEN GO TO 9840
9730 LET y1=192-17-y: LET dir=8*(CODE s$(i))+PEEK 23606+256*PEEK 23607
9740 FOR j=0 TO 7: LET byte=PEEK dir
9750 FOR k=7 TO 0 STEP -1: LET bit=2^k
9760 FOR l=1 TO ph: FOR m=1 TO pw
9780 IF byte>=bit THEN PLOT x1+8*pw-k*pw+m,y1-j*ph-l
9810 NEXT m: NEXT l: IF byte>=bit THEN LET byte=byte-bit
9820 NEXT k
9830 LET dir=dir+1: NEXT j
9840 LET x1=x1+8*pw: NEXT i
9850 RETURN 
9950 REM GAME OVER
9951 BORDER 2: PAPER 2: INK 7: CLS 
9952 LET s$="GAME OVER": LET pw=2: LET ph=3: LET y=50: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9953 LET s$="Score: ": FOR i=1 TO 5-LEN STR$ score: LET s$=s$+" ": NEXT i
9954 LET s$=s$+STR$ score
9955 LET pw=2: LET ph=2: LET y=100: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9956 RETURN 
9970 GO TO 9700
9998 POKE 23672,0: POKE 23673,0: POKE 23674,0: RETURN 
9999 LET time=PEEK 23672+256*PEEK 23673+65536*PEEK 23674: LET horas=INT (time/180000): LET time=time-horas*180000: LET minutos=INT (time/3000): LET time=time-minutos*3000: LET segundos=INT (time/50): LET time=time-segundos*50: PRINT AT 10,0;horas;"h:";minutos;"m:";segundos;"s.";time
This routine (GOSUB 9700) has the following parameters:
  • x,y: text coordinates, y being the TOP of the screen
  • ph,pw: height and width multipliers
  • s$: string to print
Using FRAMES as a timer (9998 and 9999), the punishment for failing is a Game Over screen that takes 4m 35s to be drawn.

Is PLOT so slow or maybe the maths involved? I've uploaded my program to mediafire.
User avatar
Kweepa
Manic Miner
Posts: 311
Joined: Sat Feb 03, 2018 6:14 pm
Location: Albuquerque, New Mexico

Re: Slow big letter routine...

Post by Kweepa »

I was able to reduce this to 36 sec with these changes:

Code: Select all

9700 REM PLOT PRINT
9720 LET x1=x: FOR i=1 TO LEN s$: IF s$(i)=" " THEN GO TO 9840
9730 LET y1=192-17-y: LET dir=8*( CODE s$(i))+PEEK 23606+256*PEEK 23607+1
9740 FOR j=1 TO 7: LET byte=PEEK dir
9745 IF byte=0 THEN GO TO 9830
9750 LET bit=128: FOR k=6 TO 1 STEP -1: LET bit=bit/2
9755 IF byte<bit THEN GO TO 9820
9760 LET xx=x1+(8-k)*pw: LET yy=y1-j*ph: FOR l=1 TO ph
9780 PLOT xx,yy-l: DRAW pw-1,0
9810 NEXT l: LET byte=byte-bit
9820 NEXT k
9830 LET dir=dir+1: NEXT j
9840 LET x1=x1+8*pw: NEXT i
9850 RETURN 
However, 4 minutes is certainly crappier.
catmeows
Manic Miner
Posts: 716
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Slow big letter routine...

Post by catmeows »

Kweepa, I see you, cheater :lol: - you draw 6*6 character.
Anyway, with 6 bits, why not to unroll the l loop and use computed GOTO to jump one of 64 lines that would draw complete character line. That PLOT DRAW combo could unleash its full power ;)
Proud owner of Didaktik M
catmeows
Manic Miner
Posts: 716
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Slow big letter routine...

Post by catmeows »

zup wrote: Thu Sep 03, 2020 7:09 pm
Is PLOT so slow or maybe the maths involved? I've uploaded my program to mediafire.
The slowest thing is parsing of BASIC source. Once command is parsed, the ROM routine do the job in (less or more) reasonable time (including the CIRCLE command, which is alias for two arc drawing DRAWS (IMHO)).
Proud owner of Didaktik M
zup
Manic Miner
Posts: 209
Joined: Wed Jul 08, 2020 8:42 am

Re: Slow big letter routine...

Post by zup »

catmeows wrote: Fri Sep 04, 2020 12:00 pmKweepa, I see you, cheater :lol: - you draw 6*6 character.
Anyway, with 6 bits, why not to unroll the l loop and use computed GOTO to jump one of 64 lines that would draw complete character line. That PLOT DRAW combo could unleash its full power ;)
It seems more like 6 (wide) * 7 (height). My routine draws 8*8 characters, because it can be used with any font (it gets adresses based on CHARS). Even if it only uses the ROM font, drawing 7 pixels characters makes it a "copyleft" routine... the © character will miss a line of pixels (other characters like underlines will miss rows of pixels).

After writing my message, I discovered two things:
- BASin has a profiler.
- 2^k (specially when used in a loop) is VERY expensive.

Changing 2^k with a sentence using AND or with a matrix of values saves about 2 minutes. I guess I'll make a mix of some of my optimizations and some of Kweepa optimizations... it won't be so fast but it will make it a "crap" routine (instead of a WTF one).
zup
Manic Miner
Posts: 209
Joined: Wed Jul 08, 2020 8:42 am

Re: Slow big letter routine...

Post by zup »

After looking carefully to what Kweepa did, I've got the definitive routine:

Code: Select all

1 DIM b(8): FOR i=1 TO 8: LET b(i)=2^(i-1): NEXT i
10 LET score=23: GO SUB 9998: GO SUB 9950
8999 GO TO 9999
9700 REM PLOT PRINT
9720 LET x1=x: FOR i=1 TO LEN s$: LET x1=x1+8*pw: IF s$(i)=" " THEN GO TO 9840
9730 LET dir=8*( CODE s$(i))+PEEK 23606+256*PEEK 23607
9740 FOR j=0 TO 7: LET byte=PEEK dir: IF byte=0 THEN GO TO 9830
9745 LET y1=175-y-j*ph
9750 FOR k=7 TO 0 STEP -1: LET bit=b(k+1): IF byte<bit THEN GO TO 9820
9760 FOR l=1 TO ph
9790 PLOT x1-k*pw,y1-l: DRAW pw-1,0
9810 NEXT l: LET byte=byte-bit: IF byte=0 THEN GO TO 9830
9820 NEXT k
9830 LET dir=dir+1: NEXT j
9840 NEXT i
9850 RETURN 
9950 REM GAME OVER
9951 BORDER 2: PAPER 2: INK 7: CLS 
9952 LET s$="GAME OVER": LET pw=2: LET ph=3: LET y=50: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9953 LET s$="Score: ": FOR i=1 TO 5-LEN STR$ score: LET s$=s$+" ": NEXT i
9954 LET s$=s$+STR$ score
9955 LET pw=2: LET ph=2: LET y=100: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9956 RETURN 
9970 GO TO 9700
9998 POKE 23672,0: POKE 23673,0: POKE 23674,0: RETURN 
9999 LET time=PEEK 23672+256*PEEK 23673+65536*PEEK 23674: LET horas=INT (time/180000): LET time=time-horas*180000: LET minutos=INT (time/3000): LET time=time-minutos*3000: LET segundos=INT (time/50): LET time=time-segundos*50: PRINT AT 10,0;horas;"h:";minutos;"m:";segundos;"s.";time
The changes:
- Instead of 2^k, I use a look-up table to get bit value (initialized at line 1).
- Kweepa checked if a line of a character had pixels to plot (I copied that on line 9740)... good idea, it can be used again (in line 9810) to check if there are still pixels to plot.
- Another good idea was to delete the inner loop (m) and use a DRAW sentence to plot those pixels.
- Some calculations have been move to outer loops.

Now the reference "game over" screen is drawn on 35 seconds. I guess it can be optimized... but then my game wouldn't be as crappy.
Last edited by zup on Fri Sep 04, 2020 2:11 pm, edited 3 times in total.
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

I've had a go like this....

Code: Select all

1 LET SCORE=23: GO SUB 9998
2 GO SUB 9950

8999 GO TO 9999

9800 REM PLOT PRINT
9810 PRINT AT 21,0;INK 2;S$:LET LEFTOFF=128-(LEN S$*8)
9820 FOR P=7 TO 0 STEP -1
9830 FOR Q=0 TO LEN S$*8-1
9840 IF POINT (Q,P) THEN PLOT Q+Q+LEFTOFF,P+P+HIGHOFF:DRAW 1,0:DRAW 0,1:DRAW -1,0
9850 NEXT Q:NEXT P:RETURN

9950 REM GAME OVER
9960 BORDER 2: PAPER 2: INK 7: CLS 
9970 LET S$="GAME OVER":LET HIGHOFF=100: GOSUB 9800
9980 LET S$="SCORE: "+STR$(SCORE):LET HIGHOFF=80: GOSUB 9800
9990 RETURN

9998 POKE 23672,0: POKE 23673,0: POKE 23674,0: RETURN 
9999 LET TIME=PEEK 23672+256*PEEK 23673+65536*PEEK 23674: LET HORAS=INT (TIME/180000): LET TIME=TIME-HORAS*180000: LET MINUTOS=INT (TIME/3000): LET TIME=TIME-MINUTOS*3000: LET SEGUNDOS=INT (TIME/50): LET TIME=TIME-SEGUNDOS*50: PRINT AT 20,0;HORAS;"H:";MINUTOS;"M:";SEGUNDOS;"S.";TIME
Which does it in a (slightly better) 17.45 seconds (according to frames timing).
And hopefully easy enough to see what I'm doing.

Swapping line 9820 to FOR P=6 TO 1 STEP -1 (thus ignoring the top and bottom line of characters), brings it down to 14.38secs. Removing the draw statements as well brings it down to 12.21secs for a speckled effect.

The variable HIGHOFF defines the position each big string is printed to the screen.

Note I'm using row 21 of the screen to print the text to there, and using POINT/PLOT to copy it from there rather than the peeking the character set.


(It's worth noting that this routine will become slower and slower the more lines the BASIC program has before it)
CLEAR 23855
zup
Manic Miner
Posts: 209
Joined: Wed Jul 08, 2020 8:42 am

Re: Slow big letter routine...

Post by zup »

uglifruit wrote: Fri Sep 04, 2020 2:01 pmI've had a go like this....
But that's no crappy routine! It's small and efficient!
uglifruit wrote: Fri Sep 04, 2020 2:01 pm(It's worth noting that this routine will become slower and slower the more lines the BASIC program has before it)
I didn't thought about that... I was putting common routines at top (i.e.: last lines of my programs), but it seems that they should be on the first lines. I guess that's fine (the program was meant for CSSCGC), but on other programs I should remember that.
User avatar
Kweepa
Manic Miner
Posts: 311
Joined: Sat Feb 03, 2018 6:14 pm
Location: Albuquerque, New Mexico

Re: Slow big letter routine...

Post by Kweepa »

I think this looks nice and chunky and is simple:

Code: Select all

0 GO TO 100
10 PRINT AT 21,0; INK 7;a$;AT 7,0;: FOR y=7 TO 0 STEP -1: FOR x=0 TO 8*LEN a$-1: PRINT PAPER c*POINT (x,y);" ";: NEXT x: NEXT y: RETURN 
100 CLS : POKE 23672,0: POKE 23673,0
110 LET a$="GAME": LET c=2: GO SUB 10: LET a$="OVER": GO SUB 10: LET c=3: LET a$="PTS:": GO SUB 10: LET c=4: LET score=23: LET a$=STR$ score: LET a$="    "(1 TO 4-LEN a$)+a$: GO SUB 10
120 PRINT AT 20,0;(PEEK 23672+256*PEEK 23673)/50;"sec"
(14.76sec)
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

Here's another alternative I've cobbled together, using the system chunky graphics character to enlarge what's printed on the screen at line 21.

It clocks in at a pretty respectable 9.26 seconds (using your frames timing method).

Code: Select all

1 LET SCORE=23
2 GO SUB 9950
3 STOP

9800 REM BIGCHR$_PRINT
9810 PRINT AT 21,0;INK 2;S$;at posx,0
9820 FOR P=7 TO 0 STEP -2
9830 FOR Q=0 TO len s$*8-1 step 2
9840 PRINT CHR$ (128+POINT (Q+1,P)+2*POINT (Q,P)+4*POINT (Q+1,P-1)+8*POINT (Q,P-1));
9850 NEXT Q:PRINT
9860 NEXT P:RETURN

9950 REM GAME OVER
9960 BORDER 2: PAPER 2: INK 7: CLS 
9970 LET S$="GAMEOVER":LET posx=5: GOSUB 9800
9980 LET S$="SCORE:"+STR$(SCORE):LET posx=10: GOSUB 9800
9990 RETURN
I had to spend a few minutes working out how to calculate which of the gfx characters to use, but it turns out they are laid out in a sensible order in the character set (as you'd hope).
CLEAR 23855
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

Because I enjoyed the thought behind my 'turning the pixels into the system chunky graphics characters' code, I've had a play in assembly.

Code: Select all

		org	32768			; Or wherever, it's relocatable
		
							; Call with A as the CHARACTER CODE to print.
bigchar:						;
		jr	skipcoordinates		; Jump to routine, to keep the variables 'pokable' easily.
bigposx:	defb	0				; Co-ordinates that the BIG CHAR will be printed.	
bigposy:	defb	0				;
skipcoordinates:

		push	af
		ld		a,22			; PRINT AT BIGPOSX,BIGPOSY
		rst		16
		ld		a,(bigposx)
		rst		16
		ld		a,(bigposy)
		rst		16
		pop		af
		or		a				; clear carry flag
		ld		hl,(23606)			; 23606 is CHARS.  data starts = CHARS+8*code
		ld		e,a
		ld		d,0
		rl		e
		rl		d
		rl		e
		rl		d
		rl		e
		rl		d
		add 		hl,de			; HL points at the character.
	
		call		bigrow			
		call		newline
		call		bigrow
		call		newline
		call 		bigrow
		call		newline		
		call		bigrow
		ld		a,(bigposx)
		dec		a
		dec		a
		dec		a
		ld		(bigposx),a
		
		ld		a,(bigposy)
		add		a,4
		ld		(bigposy),a
		
		cp 		29
		ret		c
		xor		a
		ld		(bigposy),a
		ld		a,(bigposx)
		add		a,4
		ld		(bigposx),a
		ret

bigrow:					; Loads A and E registers with two bytes of character that are to be parsed into a GFX CHR$
		ld		a,(hl)
		ld		e,a
		inc		hl
		ld		a,(hl)
		inc		hl
		ld		b,4		; it'll need to be turned into 4 GFX Characters
nextchar:					; 
		rlca				; bitwise fiddling to get the relevant bits into the least significant bits.
		rlca
		rlc e
		rlc e
		push		af
		call 		printbigchr		
		pop		af
		djnz 		nextchar		
		ret
			
printbigchr:				; prints the GFX char$ of that has it's top row in the least 2 significant bits of Registers A and E						
		and 		%11		; this is the maths/bit shuffling that makes it the 'right' character. 
		rla				; "
		rla				; "
		ld		d,a		; "
		ld		a,e		; "
		and		%11		; "
 		or		d		; "
		or 		128		; this'll make it into a GFX character
		
		rst 		16
		ret
		
newline:					; Steps down to the next line within the character
		ld		a,22
		rst		16
		ld		a,(bigposx)
		inc		a
		ld		(bigposx),a
		rst		16
		ld		a,(bigposy)
		rst		16
		ret
		
		end 	32768

It's a bit clunky, and using the ROM print routine but is still pacy (especially in comparison to BASIC, obviously).

Using a custom font makes it a far more interesting proposition:
Image

Maybe I'll use it in something CrapGamesCompo it at some point.



Edited:
Animated gif, with a different font:
Image

Tap file:
https://drive.google.com/file/d/1jT__rNxGFB0DR-4MIc9UC-_cbwqygv0Y/view?usp=sharing
CLEAR 23855
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

Because I just can't let it go...

Here's another M/Code version, that doesn't use the print routine (so happily uses the bottom two lines of the screen, and IS quick) with a different font again. I know this is now miles away from the initial post @zup made. I promise I'll not do any more. Promise.

Code: Select all

		org	32768		; freely relocatable
chunkyprint		
		jr	skipcoordinates	; to have easily poke-able co-ordinates
bigposx:	defb	0			; pixel address in up-down position
bigposy:	defb	0			; character address in left-right position
skipcoordinates:
	

bigchar:		; prints a 'big character' at the co-ordinates (bigposx,bigposy)


		ld		hl,(23606)
		ld		e,a
		ld		d,0
		rl		e
		rl		d
		rl		e
		rl		d
		rl		e
		rl		d
		add 	hl,de		;hl has the character address

						; need DE to point at the screen (get this from bigposx,bigposy)

		ex de,hl			; store HL for a bit

		ld		bc,(bigposx)

; Get screen address
;  B = LEFTRIGHT pixel position
;  C = UPDOWN pixel position
; Returns address in HL
Get_Pixel_Address:     
			LD A,C		                ; Calculate Y2,Y1,Y0
                        AND %00000111           	; Mask out unwanted bits
                        OR %01000000            	; Set base address of screen
                        LD H,A                  		; Store in H
                        LD A,C                  		; Calculate Y7,Y6
                        RRA                     		; Shift to position
                        RRA
                        RRA
                        AND %00011000           	; Mask out unwanted bits
                        OR H                    		; OR with Y2,Y1,Y0
                        LD H,A                  		; Store in H
                        LD A,C                 		; Calculate Y5,Y4,Y3
                        RLA                     		; Shift to position
                        RLA
                        AND %11100000           	; Mask out unwanted bits
                        LD L,A                  		; Store in L
                        LD A,B                  		; Calculate X4,X3,X2,X1,X0
                        AND %00011111           	; Mask out unwanted bits
                        OR L                   		; OR with Y5,Y4,Y3
                        LD L,A                 		; Store in L

		ex de,hl					; restore HL

		call	bigrow				; loops are for losers.
		inc		hl
		call	bigrow
		inc		hl
		call	bigrow
		inc		hl
		call	bigrow
		inc		hl		
		call	bigrow
		inc		hl
		call	bigrow
		inc		hl
		call	bigrow
		inc		hl
		call	bigrow
			
		; update print position
		
		ld		a,(bigposy)
		add		a,4
		ld		(bigposy),a
		
		cp 		29
		ret		c
		xor		a
		ld		(bigposy),a
		ld		a,(bigposx)
		add		a,32
		ld		(bigposx),a

		ret

bigrow:
		push	de				;save the destination
		ld		a,(hl)

		ld		b,4
nextchar:
		rlca
		rlca
		
		push	af
		call 	printbigbyte		
		pop		af
		inc		de
		djnz 	nextchar		

		pop		de		;restore the destination address

		call    moveDEdown
		call    moveDEdown
		call    moveDEdown
		call    moveDEdown		
		
		ret
			
printbigbyte:				; prints the bigbyte of A at de						
		and 		%11		; 
		rra				; rightmost bit into carry
		push	af			; store flags
		rra
		sbc  		a,a   	; set all bits in A to Carry (00 or FF)
		and 		%11110000
		ld		c,a
		pop		af		; restore flags
		sbc  		a,a   		; set all bits in A to Carry (00 or FF)
		and		%00001111
		or 		c
		
		ld		(de),a
		ld		c,a
		push		de
		call		moveDEdown
		ld		a,c
		ld		(de),a
		call		moveDEdown
		ld		a,c
		ld		(de),a
		call		moveDEdown
		ld		a,c
		ld		(de),a
		pop		de		
						
		ret
		

;;; Move DE down one pixel line

moveDEdown:
Pixel_Address_Down:     INC D		; Go down onto the next pixel line
                        LD A,D			; Check first three bits of high byte (Y0-Y2)
                        AND 7
                        RET NZ			; If any bits are set (we are inside a char line), we are done
;next char line
                        LD A,E			; we crossed the char line ((Y0-Y2)=0 i.e Y6=1)
                        ADD A,32			; (move down 1 char line) add the extra bit into (Y3-Y5)
                        LD E,A
                        RET C			; Check for a carry bit (crossed a third), if C is set we are done
;did not cross a third
                        LD A,D			; We better clean up the bit from (Y6)
                        SUB 8
                        LD D,A
        
	                RET			
		
		end 	32768
Image

Gif
Image

Tap file:
https://drive.google.com/file/d/1Nxv2yfUHn39R233az7CIpEiD64NocgxP/view?usp=sharing

Of moderate interest to me: I used the command:
SBC A,A to set all bits in A to the value of the carry flag. So A ends up as 00 or FF. I'd seen that mentioned before, but never had call to use it in the wild.

Also, this has Character position printing in the Horizontal direction, but pixel printing in the Vertical. Not sure why that'd be useful.

(This and the the font used in my previous posts are by @damieng from his amazing repository at https://damieng.com/zx-origins/)
CLEAR 23855
dfzx
Manic Miner
Posts: 681
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Re: Slow big letter routine...

Post by dfzx »

uglifruit wrote: Mon Sep 07, 2020 8:16 pm (This and the the font used in my previous posts are by @damieng from his amazing repository at https://damieng.com/zx-origins/)
404... :(

Is that the correct link?
Derek Fountain, author of the ZX Spectrum C Programmer's Getting Started Guide and various open source games, hardware and other projects, including an IF1 and ZX Microdrive emulator.
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

dfzx wrote: Tue Sep 08, 2020 9:33 am
uglifruit wrote: Mon Sep 07, 2020 8:16 pm (This and the the font used in my previous posts are by @damieng from his amazing repository at https://damieng.com/zx-origins/)
404... :(

Is that the correct link?
Ah no. It was. Once. I think.
It now lives at https://damieng.com/typography/zx-origins/
(Apologies)
CLEAR 23855
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

Obviously my routine needs to be used to do this. (Yes, I've done some more faffing with it, and used another of Damien's fonts... "Broadwary" this time).


Image
CLEAR 23855
User avatar
ZXDunny
Manic Miner
Posts: 498
Joined: Tue Nov 14, 2017 3:45 pm

Re: Slow big letter routine...

Post by ZXDunny »

How about using block graphics?

Code: Select all

  10 REM 4x4 Pixel magnifier
  20 CLS
  30 INPUT "Characters to render: "; LINE a$
  40 IF LEN (a$)>8 THEN PRINT AT 0,0;"Up to 8 Characters only!": PAUSE 0: CLS : GO TO 30
  50 PRINT AT 21,0; INK 7;a$
  60 FOR x=0 TO (LEN (a$)*8)-1 STEP 2
  70 FOR y=0 TO 8 STEP 2
  90 PRINT AT (8-y)/2,x/2;CHR$ (128+8*POINT (x,y)+4*POINT (x+1,y)+2*POINT (x,y+1)+POINT (x+1,y+1))
 100 NEXT y
 110 NEXT x
 120 PAUSE 0
 130 GO TO 20
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

ZXDunny wrote: Tue Sep 08, 2020 3:44 pm How about using block graphics?

Code: Select all

  10 REM 4x4 Pixel magnifier
  20 CLS
  30 INPUT "Characters to render: "; LINE a$
  40 IF LEN (a$)>8 THEN PRINT AT 0,0;"Up to 8 Characters only!": PAUSE 0: CLS : GO TO 30
  50 PRINT AT 21,0; INK 7;a$
  60 FOR x=0 TO (LEN (a$)*8)-1 STEP 2
  70 FOR y=0 TO 8 STEP 2
  90 PRINT AT (8-y)/2,x/2;CHR$ (128+8*POINT (x,y)+4*POINT (x+1,y)+2*POINT (x,y+1)+POINT (x+1,y+1))
 100 NEXT y
 110 NEXT x
 120 PAUSE 0
 130 GO TO 20
Thats the same technique I used on my 9sec one! (And I thought I was the only one who'd worked out how to calculate the character.)
CLEAR 23855
User avatar
ZXDunny
Manic Miner
Posts: 498
Joined: Tue Nov 14, 2017 3:45 pm

Re: Slow big letter routine...

Post by ZXDunny »

uglifruit wrote: Tue Sep 08, 2020 4:32 pm
ZXDunny wrote: Tue Sep 08, 2020 3:44 pm How about using block graphics?

Code: Select all

  10 REM 4x4 Pixel magnifier
  20 CLS
  30 INPUT "Characters to render: "; LINE a$
  40 IF LEN (a$)>8 THEN PRINT AT 0,0;"Up to 8 Characters only!": PAUSE 0: CLS : GO TO 30
  50 PRINT AT 21,0; INK 7;a$
  60 FOR x=0 TO (LEN (a$)*8)-1 STEP 2
  70 FOR y=0 TO 8 STEP 2
  90 PRINT AT (8-y)/2,x/2;CHR$ (128+8*POINT (x,y)+4*POINT (x+1,y)+2*POINT (x,y+1)+POINT (x+1,y+1))
 100 NEXT y
 110 NEXT x
 120 PAUSE 0
 130 GO TO 20
Thats the same technique I used on my 9sec one! (And I thought I was the only one who'd worked out how to calculate the character.)
That's been one of BASin's example files for more than a decade now :)
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

ZXDunny wrote: Tue Sep 08, 2020 4:48 pm That's been one of BASin's example files for more than a decade now :)
I'm reinventing the wheel again!
CLEAR 23855
User avatar
Joefish
Rick Dangerous
Posts: 2058
Joined: Tue Nov 14, 2017 10:26 am

Re: Slow big letter routine...

Post by Joefish »

Gonna give you this bit of BASIC for drawing 4x characters. Not machine-code fast, but at around 2 characters per second (and allowing for different fonts) it's not bad for BASIC.
It reads the character image bytes from memory, splits them into two nybbles, then has a prepared array telling it how to draw each of the 16 possible combinations in block graphics.
You only need to call 8800 once at the start of the program to initiate the arrays. Then LET a=row, LET b=column, LET a$=your text, set your INK and PAPER colour, then GOSUB 8000

Code: Select all

10 REM 4x Text Printer by Jason "Joefish" Railton
20 INK 7: PAPER 1: BORDER 1: BRIGHT 0: OVER 0: CLS : GO SUB 8800
30 LET a=3: LET b=0: LET a$="Write 4x": INK 7: GO SUB 8000
40 LET a=11: LET b=0: LET a$="BIG TextIn BASIC": INK 6: PAPER 2: BRIGHT 1: GO SUB 8000
50 PAUSE 0
60 STOP
7999 STOP 
8000 FOR c=1 TO LEN (a$)
8010 LET m=PEEK (23606)+256*PEEK (23607)+8* CODE (a$(c))
8020 FOR n=0 TO 3
8030 LET p=PEEK (m+2*n): LET q=INT (p/16): LET p=p-16*q
8040 PRINT AT a+n,b;t$(1,q+1);t$(1,p+1)
8050 LET p=PEEK (m+2*n+1): LET q=INT (p/16): LET p=p-16*q
8060 PRINT AT a+n,b; OVER 1;t$(2,q+1);t$(2,p+1)
8070 NEXT n
8080 LET b=b+4: IF b>28 THEN LET b=0: LET a=a+4: IF a>18 THEN RETURN 
8090 NEXT c
8100 RETURN 
8799 STOP 
8800 DIM t$(2,16,2)
8810 LET t$(2,1)="  ": LET t$(1,1)="  "
8820 LET t$(2,2)=" \ .": LET t$(1,2)=" \ '"
8830 LET t$(2,3)=" \. ": LET t$(1,3)=" \' "
8840 LET t$(2,4)=" \..": LET t$(1,4)=" \''"
8850 LET t$(2,5)="\ . ": LET t$(1,5)="\ ' "
8860 LET t$(2,6)="\ .\ .": LET t$(1,6)="\ '\ '"
8870 LET t$(2,7)="\ .\. ": LET t$(1,7)="\ '\' "
8880 LET t$(2,8)="\ .\..": LET t$(1,8)="\ '\''"
8890 LET t$(2,9)="\.  ": LET t$(1,9)="\'  "
8900 LET t$(2,10)="\. \ .": LET t$(1,10)="\' \ '"
8910 LET t$(2,11)="\. \. ": LET t$(1,11)="\' \' "
8920 LET t$(2,12)="\. \..": LET t$(1,12)="\' \''"
8930 LET t$(2,13)="\.. ": LET t$(1,13)="\'' "
8940 LET t$(2,14)="\..\ .": LET t$(1,14)="\''\ '"
8950 LET t$(2,15)="\..\. ": LET t$(1,15)="\''\' "
8960 LET t$(2,16)="\..\..": LET t$(1,16)="\''\''"
8970 RETURN 
Note that the listing uses the BASIN representation for graphics blocks, e.g. \.. is the solid bottom row, \ ' is the top-right square. You can copy the listing and paste it straight in to the BASIN or BASINC editor window.
User avatar
ZXDunny
Manic Miner
Posts: 498
Joined: Tue Nov 14, 2017 3:45 pm

Re: Slow big letter routine...

Post by ZXDunny »

Joefish wrote: Tue Sep 08, 2020 5:01 pm Gonna give you this bit of BASIC for drawing 4x characters. Not machine-code fast, but at around 2 characters per second (and allowing for different fonts) it's not bad for BASIC.
You know, that would be an excellent front-end system for say... a multicolour River Raid game or something like that.
User avatar
Joefish
Rick Dangerous
Posts: 2058
Joined: Tue Nov 14, 2017 10:26 am

Re: Slow big letter routine...

Post by Joefish »

ZXDunny wrote: Tue Sep 08, 2020 7:04 pmYou know, that would be an excellent front-end system for say... a multicolour River Raid game or something like that.
You wouldn't let it lie! :lol:

Been busy generating millions of Pac-Man mazes and converting those to multicolour lately. Distracting from my shoot-em-up, which is rapidly running out of memory!
User avatar
uglifruit
Manic Miner
Posts: 703
Joined: Thu Jan 17, 2019 12:41 pm
Location: Leicester
Contact:

Re: Slow big letter routine...

Post by uglifruit »

Joefish wrote: Tue Sep 08, 2020 5:01 pm Gonna give you this bit of BASIC for drawing 4x characters. Not machine-code fast, but at around 2 characters per second (and allowing for different fonts) it's not bad for BASIC.
This is great. Really neat way of doing it (and pretty pacy).
CLEAR 23855
Post Reply