Read pixels

Two routines to read pixels off the screen or in a window. The colour
returned can be Native colour (RPIX%) or RGB 24 bit colour (RPIX24).

These functions are only compatible with the Graphic Device Interface
Version 2 (GD2) drivers in the three currently available modes: 16, 32,
and 33. This also means they are only compatible with SMSQ/E systems.


Read pixel within window:

        natcol% = RPIX%([#ch; ] xpos%, ypos%)

        Returns the native colour of pixel at xpos%, ypos% relative to
        channel #ch (defaults to #1)

        rgbcol = RPIX24([#ch; ] xpos%, ypos%)

        Returns the RGB colour code of pixel at xpos%, ypos% relative to
        channel #ch (defaults to #1)

Note: With this option the coordinates given MUST fall within the window's
borders or an Out of Range error will be thrown. Ie the top left pixel is

                                 0, 0

while the bottom rightmost pixel is

window_x_size - border_width * 4 - 1, window_y_size - border_width * 2 - 1

See example 1!

Note: If background refresh is switched on (PE_BGON) the pixel read comes
from the buffer. Ie if the window is buried it is still the pixel from the
actual window that is returned.

If background refresh is switched off (PE_BGOFF) and the window is
burried, program flow will be suspended until the window again is
uncovered. This is normal behaviour (in the unlikely event you didnt

Read pixel from the screen (note exclamation mark separator):

        natcol% = RPIX%([#ch; ] xpos%! ypos%)

        Returns the native colour of pixel at xpos%, ypos% in screen
        coordinates. An optional channel is still required and defaults
        to #1.

        rgbcol = RPIX24([#ch; ] xpos%! ypos%)

        Returns the RGB colour code of pixel at xpos%, ypos% in screen
        coordinates. An optional channel is still required and defaults
        to #1.

Note: It is always the visible pixel at a given location that is returned,
whether the given window channel is buried or not.


1) Demonstrates window limits

EXecute this code from dev4_ or adjust accordingly. Also adjust colour
values for display modes <> 32.

100 lrespr 'dev4_scr_rpx_RPIX_BIN'
110 lrespr 'dev4_scr_wpx_WPIX_BIN'
120 :
140 ch = FOPEN("con")
150 xs% = 200: ys% = 200: bd% = 2
160 WINDOW#ch; xs%, ys%, 300, 20
170 if bd% then
180  border#ch; bd%, -33: rem -2048
190  xs% = xs% - bd% * 4 - 1
200  ys% = ys% - bd% * 2 - 1
210 endif
220 :
230 CLS#ch
240 FOR i% = 0 TO 9999
250  x% = RND(0 TO xs%)
260  y% = RND(0 TO ys%)
270  c% = RND(-32765 TO 32766)
280  WPIX#ch; x%, y%, c%
290  k% = RPIX%(#ch; x%, y%)
300  IF k% <> c% THEN
310   AT#ch; 0,0: INK#ch; -33: PRINT#0; c%, k%,
320  END IF
330 END FOR i%
340 PAUSE#ch
350 QUIT

2) A block is drawn on the right side of the window with an alternating
dot pattern of another colour. Two sample dots are read and an identical
block is drawn on the left.

EXecute the code as an SBASIC job. Mode 16, 32, and 33 only!

100 LRESPR'win4_scr_rpx_RPIX24_BIN'
110 ch = FOPEN("con_216x108a10x20")
120 PAPER#ch; 7: INK#ch; 0: BORDER#ch; 4, 2: CLS#ch
130 :
160 :
180  max% = 255: min% = 0
190 ELSE
200  max% = 32767: min% = -32767
210 END IF
220 :
230 FOR i = 0 TO 10
240  nat1% = RND(min% TO max%)
250  nat2% = RND(min% TO max%)
260  BLOCK#ch; 100, 100, 100, 0, nat1%, nat2%, 0
270  Wait 10
280  res1% = RPIX%(#ch; 100, 0)
290  res2% = RPIX%(#ch; 101, 0)
300  BLOCK#ch; 100, 100, 0, 0, res1%, res2%, 0
310  Wait 20
320 END FOR i
330 BEEP 999, 1: Wait 100: QUIT
340 :
350 DEFine PROCedure Wait(t): IF CODE(INKEY$(#ch; t)) = 27: QUIT
360 :


Mag_bas is a slightly more elaborate program to magnify a portion of the
screen. EXecute it as an SBASIC program. Move the window sprite to a
suitable location and HIT the mouse button to magnify the area. To move the
display window, find a suitable location and DO the mouse button. Press
ESC to quit.

NB! Requires EasyPtr's ptrmen_cde or, with modification, Qptr.

New: A compiled version may be found at Knoware.no under Utilities

Programming notes:

RPIX% and RPIX24 share some common code, but can easily be separated. If
all you need is RPIX% then run your Make or linker with RPIX_link. If all
you want is RPIX24, there is not much to be gained by removing RPIX%, so I
leave it to you to sort out.

The bulk of the nat to RGB conversion code is due to the 8 bit, mode 16,
conversion table. I found the tabular conversion necessary, as I was not
satisfied with a purely calculated conversion. Perhaps someone else can to

The code base is designed to run on all GD2 platforms. If you know that a
program in which you intend to use RPIX24 will never run under mode 16, you
could remove the bits pertaining to that mode.

If mode 16 is important and you prefer speed over bulk, you could
reassemble the program with the cv16to24 conversion code (as opposed to
the cv16to24n used here). cv16to24 uses a 3x3 byte conversion table and
takes up all of 768 bytes, but uses fewer instructions to do the job, while
cv16to24n uses a 3x3 nybble conversion table, which takes up half the
space, but is marginally slower. No changes to the code is required: Just
un-comment the relevant line in the link file.

The source code for the conversion routines used are included here FYI.
The linker, however, will fetch the necessary code from the library. If
you add more of my toolkits that use colour conversion routines, you may
find that these routines get overwritten or added to. That is quite
normal. Should the library change in a significant way you may have to
update RPIX24 too if you need to re-assemble it.

Software status:

The cv32to24 and cv33to24 conversion routines were packaged by me and are
V0.01, ©W Lenerz, 2004.

The remainder is:

V0.01, pjw, November 13th 2018
V0.02, pjw, June 10th 2019, corrected and packaged.
V0.03, pjw, 2019 Aug 31, new conversion code file structure; no functional
V0.04, pjw, 2019 Oct 17, rewritten xt_rpx: Simplified & limit to inside

Conditions of use and disclaimer as per Knoware.no