Updates:
- 2024-01-09 – Corrected a PMODE 1 size typo from 8×18 to the correct 8×16, and a 16×17 typo.
Here is a quickie…
I did not know this was possible “back in the day,” and do not think I have ever tried it until now.
In Extended Color BASIC you can use “GET” to get a block of memory from the screen and store it in array memory. You can then “PUT” it back on to the screen.
But, if you know where the array memory is (using the VARPTR function) you can POKE bytes directly in to the array and then just PUT it without ever needing to GET.
10 ' GET/PUT ARRAY (2 ENTRIES)
20 DIM B(1)
30 ' PRE-ALLOCATE VARIABLES
40 DIM A,D,L,V
50 ' 256x192 (32X24 OF 8X8 CHARS)
60 PMODE 4,1:PCLS:SCREEN 1,1
70 ' GET ADDRESS OF ARRAY DATA
80 V=VARPTR(B(0))
90 ' POKE 8X8 DATA IN TO IT
100 FOR L=V TO V+7:READ D:POKE L,D:NEXT
110 ' PUT THE DATA ON THE SCREEN
120 PUT(0,0)-(7,7),B
130 GOTO 130
140 ' BOMB DATA
150 DATA 24,24,60,118,122,126,126,60
This demo puts an 8×8 bomb on the top left of the screen. The bomb was one of the characters from my VIC-20 game Factory TNT.
It does not look like you can use a multi-dimensional array got GET/PUT (does anyone know if this is possible?). Pity. If that were possible, I had something I wanted to try.
How much array memory do I need?
To know how many DIM array elements you need for an object, run this program:
0 REM pmodes.bas
5 CLS:INPUT "W,H";MW,MH:PRINT
10 FOR M=0 TO 4:READ M$
20 PRINT "PMODE";M;"(";M$;")"
30 NEXT
40 PRINT
50 PRINT "M W X H W X H PXLS BYT E"
60 PRINT "- -- -- -- -- ---- --- --"
70 FOR M=0 TO 4
80 W=MW:H=MH
90 PRINT USING "# ##X##";M;W;H;
100 PRINT" -> ";
110 IF M<4 THEN W=W/2
120 IF M<2 THEN H=H/2
130 P=W*H
140 B=P/(8-4*(M AND 1))
150 E=INT(B/5+.5)
160 PRINT USING "##X## #### ### ##";W;H;P;B;E
170 NEXT
180 IF INKEY$="" THEN 180
190 GOTO 5
999 GOTO 999
1000 DATA "128 X 96 X 2"
1010 DATA "128 X 96 X 4"
1020 DATA "128 X 192 X 2"
1030 DATA "128 X 192 X 4"
1040 DATA "256 X 192 X 2"
Type in the width/height and it shows you the memory requirements for that object on each PMODE screen. If it says it needs two elements, that is a DIM X(1) because DIM starts at 0. DIM X(3) would give you four — X(0), X(1), X(2) and X(3).
PMODE width and heights
Be aware that all PMODE screens use coordinates of 256×192, and scale to whatever resolution is being used (128×96, 128×192 or 256×192).
On a PMODE 4 screen (256×192), doing LINE(0,0)-(7,7),PSET,B draws a box that is truly 8 pixels wide by 8 pixels tall.
On a PMODE 2 or 3 screen (128×192), the same command would draw a box that was 4 pixels wide and 8 pixels tall.
On a PMODE 0 or 1 screen (128×96) would be drawing a box that was 4 pixels wide by 4 pixels tall.
If you truly wanted an 8×8 object on a PMODE 0 or 1 screen (128×96) screen, you would have to draw it as 16×16. An 8×8 object on a PMODE 2 or 3 screen (128×192) would be drawn as if it was 8×16.
Here is a short program that draws a 16×16 pixel box on each of the five PMODE screen types. It adjusts the width and height based on the mode to know how big of a box it has to draw which would appear as 16×16:
10 FOR M=0 TO 4
20 W=16:H=16
30 PMODE M,1:PCLS:SCREEN 1,1
40 IF M<4 THEN W=W*2
50 IF M<2 THEN H=H*2
60 LINE(0,0)-(W,H),PSET,B
70 LINE(0,0)-(W,H),PSET
80 LINE(W,0)-(0,H),PSET
90 IF INKEY$="" THEN 90
100 NEXT
999 GOTO 999
And that is not confusing at all ;-) But it did mean that you could draw anything as if it were a PMODE 4 screen and then draw it on any lower resolution screen without changes — you could just lose detail.
But I digress. It looks like I should write a new article series…
Pingback: PUT defined by ASCII strings | Sub-Etha Software