is a pixel lit?

Anything QL Software or Programming Related.
Post Reply
AndyRed64
ROM Dongle
Posts: 6
Joined: Fri Jul 11, 2025 9:20 pm
Location: Southend-on-Sea, Essex

is a pixel lit?

Post by AndyRed64 »

On the ql is there a peek command i can use to find whether a given pixel is lit in mode 4?


stephen_usher
Super Gold Card
Posts: 576
Joined: Tue Mar 11, 2014 8:00 pm
Location: Oxford, UK.
Contact:

Re: is a pixel lit?

Post by stephen_usher »

You can read the two bytes which contain the 8 pixel group and then mask the value to determine of the bits are set.

Each scan line of the screen contains 128 bytes, or 64 pairs of bytes. In mode 4 each byte is a bit map of pixels, the first byte is red and the second green (from memory).

You should be able to easily work out the address of the consecutive bytes holding the pixel you're interested in from that.

i.e. <screen base address> + (128 x <pixels down from the top>) + (abs(<pixels across> / 8) x 2)


User avatar
Andrew
QL Wafer Drive
Posts: 1053
Joined: Tue Jul 17, 2018 9:10 pm

Re: is a pixel lit?

Post by Andrew »

AndyRed64 wrote: Sun Jul 27, 2025 4:27 pm On the ql is there a peek command i can use to find whether a given pixel is lit in mode 4?
In Do It Yourself Toolkit - volume G - you can find the PIXEL% function
PIXEL% can automatically distinguish between MODE 8 and MODE 4 displays. The function PIXEL% tells you the colour of a specified dot on the QL screen.

You can download the DIY toolkit from Dilwyn's page: https://dilwyn.theqlforum.com/tk/diytk2.zip


User avatar
dilwyn
Mr QL
Posts: 3139
Joined: Wed Dec 01, 2010 10:39 pm

Re: is a pixel lit?

Post by dilwyn »

If you want to be able to handle high resolution and high colour modes as well, try this set of functions written in BASIC (or can be downloaded as a single zipped file from the link below).

https://dilwyn.theqlforum.com/basic/pixelcolours.zip

It's some time since I wrote them, not tested with the latest hardware like QIMSI Gold, but I don't think there's any major difference there.

They work using absolute co-ordinates - top left of screen is 0,0 - as opposed to being window based.

Code: Select all

1000 DEFine PROCedure ScreenDetails
1010   REMark QDOS ROM defaults
1020   screenbase = 131072 : REMark base address of screen
1030   screenllen = 128    : REMark screen line width in bytes
1040   IF VER$ = 'HBA' THEN
1050     REMark use SBASIC functions on hires systems
1060     screenbase = SCR_BASE
1070     screenllen = SCR_LLEN
1080   END IF
1090 END DEFine ScreenDetails
1100 :
1110 DEFine FuNction PIXEL4%(x,y)
1120   LOCal screenbase,screenllen,pixel,word,green,red,addr
1130   ScreenDetails
1140   pixel = 7-(x MOD 8) : REMark pixel number across colour byte
1150   word  = 2*(x DIV 8)
1160   addr  = screenbase+(y*screenllen)+word
1170   green = 4*((PEEK(addr)&&(2^pixel))<>0)
1180   red   = 2*((PEEK(addr+1)&&(2^pixel))<>0)
1190   RETurn green+red+(green<>0 AND red<>0) : REMark 4+2->7 for white
1200 END DEFine PIXEL4%
1210 :
1220 DEFine FuNction PIXEL8%(x,y)
1230   LOCal screenbase,screenllen,pixel,word,green,red,blue,addr
1240   ScreenDetails
1250   pixel = 7-((x&&254) MOD 8) : REMark pixel number across colour byte
1260   word  = 2*(x DIV 8)
1270   addr  = screenbase+(y*screenllen)+word
1280   green = 4*((PEEK(addr)&&(2^pixel))<>0)
1290   red   = 2*((PEEK(addr+1)&&(2^pixel))<>0)
1300   blue  = (PEEK(addr+1)&&(2^(pixel-1)))<>0
1310   RETurn green+red+blue
1320 END DEFine PIXEL8%
1330 :
1340 DEFine FuNction PIXEL16%(x,y)
1350   REMark returns value of MODE 16 (256 colour) pixel from screen
1360   ScreenDetails
1370   RETurn PEEK(screenbase+(y*screenllen)+x)
1380 END DEFine PIXEL16%
1390 :
1400 DEFine FuNction PIXEL32%(x,y)
1410   ScreenDetails
1420   REMark returns MODE 32 colour as GGGBBBBB RRRRRGGG as stored in memory
1430   RETurn PEEK_W(screenbase+(y*screenllen)+(2*x))
1440 END DEFine PIXEL32%
1450 :
1460 DEFine FuNction PIXEL32_REV%(x,y)
1470   LOCal addr,word
1480   ScreenDetails
1490   addr = screenbase+(y*screenllen)+(2*x)
1500   REMark byte reverse MODE 32 systems
1510   REMark to get RRRRRGGG GGGBBBBB
1520   word = PEEK(addr+1)*256 + PEEK(addr)
1530   IF word > 32767 THEN word = word-65536
1540   RETurn word
1550 END DEFine PIXEL32_REV%
1560 :
1570 DEFine FuNction PIXEL33%(x,y)
1580   REMark return value of mode 33 pixel
1590   ScreenDetails
1600   REMark colour is GGGGGRRR RRBBBBBW
1610   RETurn PEEK_W(screenbase+(y*screenllen)+(2*x))
1620 END DEFine PIXEL33%
INSTRUCTIONS:
PIXEL COLOUR FUNCTIONS

by Dilwyn Jones, 2022


As SBASIC and SuperBASIC do not have functions to read the colour of a pixel
from the screen, I decided to write these BASIC functions to do the job, so that
you do not have to rely on toolkit BASIC extensions in your programs to do this
elementary programming task.

These functions will read the colour value for a pixel in screen memory and
should work on high resolution and high colour systems.

All the functions take two parameters, x and y, the number of pixels across (x)
and down (y) the screen. Note: this is across the entire screen, not a window -
tu use in screen window channels, add the x and y offsets to the window origin
co-ordinates

ScreenDetails - this procedure is called from all of the functions. Its purpose
is to check if being used on an SBASIC system (VER$='HBA') and if so, it assumes
it should use the SCR_BASE and SCR_LLEN functions of SBASIC to tell it the
screen base address in memory and the width of each line of video memory in
bytes, used in calculating the address of individual pixels. This helps ensure
that these routines work on high resolution and high colour systems. For
traditional QDOS systems, the routines justa ssume the screen is fixed at
address decimal 131072 and always has a line width of 128 bytes. In reality,
uQLx and sQLux emulators using QDOS can have certain fixed sizes of higher
resolution screens and may need a test for these emulators to be added to the=is
procedure.

PIXEL4%(x,y) returns the colour of a pixel at co-ordinates x and y across and
down the screen respectively in the 4-colour mode on a QL.

PIXEL8%(x,y) returns the colour of a pixel at co-ordinates x and y across and
down the screen respectively in the 8-colour mode on a QL.

PIXEL16%(x,y) returns the 8-bit colour value of a pixel at co-ordinates x and y
across and down the screen respectively on a MODE 16 8-bit or 256 colour
display. The colour bits are stored as GRBGRBGc where c is the red/blue bit (see
SMSQ/E documentation.

PIXEL32%(x,y) returns the 16-bit colour value of a pixel at co-ordinates x and y
across and down the screen respectively on a MODE 32 (QPC2, QXL etc little
endian system. Note that the two bytes forming the stored colour words are
returned in the order stored in the video display on Intel-style systems. That
is, the Red, Green and Blue are stored as GGGBBBBB RRRRRGGG format. If you want
the returned value to be byte-reversed to make it easier to handle, use the next
version.

PIXEL32_REV%(x,y) returns the 16-bit byte reversed colour value of a pixel at
co-ordinates x and y across and down the screen respectively on a mode 32
little-endian system such as an Intel PC. This returns the colour bits as
RRRRRGGG GGGBBBBB which is probably easier to handle and conforms to
SMSQ/E colour format documentation for GD2 sprites etc.

PIXEL33%(x,y) returns the 16-bit colour value of a pixel at co-ordinates x and y
across and down the screen respectively on a MODE 33 display on 680x0 processors
such as Q40, Q60 and Q68. The red, green and blue components of the colour value
are stored as GGGGGRRR RRBBBBBW.

If you would prefer to have just a single function to do this work across all
modes, it should be fairly easy to add a third parameter to pass the mode number
to, then a SELect on mode statement to call the appropriate routine. I've
included an example function called PIXEL%(x,y,mode_number) to let you call the
routine just by specifying which screen mode you are using, e.g.

PRINT PIXEL%(0,0,33)

would return the pixel colour at co-ordinates 0,0 across a Q40 screen.


Derek_Stewart
Font of All Knowledge
Posts: 4809
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: is a pixel lit?

Post by Derek_Stewart »

Hi,

I have been trying to convert Spectrum games that use ATTR function, that returns the state of the pixel.

I like the fact that Dilwyn's excellent code is just S*BASIC, so can run on all machines.

I will give it a try and upload the games.


Regards, Derek
Mad Fritz
ROM Dongle
Posts: 19
Joined: Wed Feb 26, 2020 12:42 pm
Location: Switzerland
Contact:

Re: is a pixel lit?

Post by Mad Fritz »

IIRC , ATTR gives you the attributes of the choosen row/column (or vice versa).
Was it POINT instead?
Need to go back to Spectrum Basic...


User avatar
ql_freak
Super Gold Card
Posts: 556
Joined: Sun Jan 18, 2015 1:29 am

Re: is a pixel lit?

Post by ql_freak »

AndyRed64 wrote: Sun Jul 27, 2025 4:27 pm On the ql is there a peek command i can use to find whether a given pixel is lit in mode 4?
I'm afraid, there is not such a function, which can detect the MODE (4 or 8) from a single pixel.

In both modes a pixel is made of 4 bits and in both modes all 4 bits may be set or unset.

So I say: NO, it's not possible from just one pixel to decide, if you're in MODE 4 or MODE 8.

The operating system (QDOS) displays the pixel as is (if in Mode 4 or 8). This is a problem
(only) in MODE 8. As MODE 8 does not support 16 colours but just 8 with 1 bit used as (hardware!)
blink. If you switch from mode 4 to mode 8, it may be that a lot of pixels on the screen will blink.


http://peter-sulzer.bplaced.net
GERMAN! QL-Download page also available in English: GETLINE$() function, UNIX-like "ls" command, improved DIY-Toolkit function EDLINE$ - All with source. AND a good Python 3 Tutorial (German) for Win/UNIX :-)
User avatar
RalfR
QL Wafer Drive
Posts: 1217
Joined: Fri Jun 15, 2018 8:58 pm

Re: is a pixel lit?

Post by RalfR »

It is more easy with the PE and QPTR.


7000 4E75
AndyRed64
ROM Dongle
Posts: 6
Joined: Fri Jul 11, 2025 9:20 pm
Location: Southend-on-Sea, Essex

Re: is a pixel lit?

Post by AndyRed64 »

Thank you so much everyone. This is really helpful :)


Post Reply