Draw a pixel

You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Create a window and draw a pixel in it, subject to the following:
- the window is 320 x 240
- the color of the pixel must be red (255,0,0)
- the position of the pixel is x = 100, y = 100
Action!
The solution of this task is tricky because of technical limitation of Atari 8-bit computer. The computer supports high resolution graphics mode of 320 pixels width, 192 pixels height and 1 bit per pixel color. The color of the pixel cannot be set independently from the background color and only different luminance can be specified. To draw a red pixel the background must be set to light-red color.
PROC Main()
BYTE
CH=$02FC, ;Internal hardware value for last key pressed
PALNTSC=$D014 ;To check if PAL or NTSC system is used
Graphics(8+16) ;Graphics 320x192 with 2 luminances
IF PALNTSC=15 THEN
SetColor(1,4,6) ;Red color for NTSC
SetColor(2,4,15)
ELSE
SetColor(1,2,6) ;Red color for PAL
SetColor(2,2,15)
FI
Color=1
Plot(100,100)
DO UNTIL CH#$FF OD
CH=$FF
RETURN
- Output:
Screenshot from Atari 8-bit computer
Ada
with SDL.Video.Windows.Makers;
with SDL.Video.Renderers.Makers;
with SDL.Events.Events;
procedure Draw_A_Pixel is
Width : constant := 320;
Height : constant := 200;
Window : SDL.Video.Windows.Window;
Renderer : SDL.Video.Renderers.Renderer;
procedure Wait is
use type SDL.Events.Event_Types;
Event : SDL.Events.Events.Events;
begin
loop
while SDL.Events.Events.Poll (Event) loop
if Event.Common.Event_Type = SDL.Events.Quit then
return;
end if;
end loop;
delay 0.100;
end loop;
end Wait;
begin
if not SDL.Initialise (Flags => SDL.Enable_Screen) then
return;
end if;
SDL.Video.Windows.Makers.Create (Win => Window,
Title => "Draw a pixel",
Position => SDL.Natural_Coordinates'(X => 10, Y => 10),
Size => SDL.Positive_Sizes'(Width, Height),
Flags => 0);
SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface);
Renderer.Set_Draw_Colour ((0, 0, 0, 255));
Renderer.Fill (Rectangle => (0, 0, Width, Height));
Renderer.Set_Draw_Colour ((255, 0, 0, 255));
Renderer.Draw (Point => (100, 100));
Window.Update_Surface;
Wait;
Window.Finalize;
SDL.Finalise;
end Draw_A_Pixel;
ARM Assembly
/* ARM assembly Raspberry PI */
/* program dpixel.s */
/* compile with as */
/* link with gcc and options -lX11 -L/usr/lpp/X11/lib */
/********************************************/
/*Constantes */
/********************************************/
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
/* constantes X11 */
.equ KeyPressed, 2
.equ ButtonPress, 4
.equ MotionNotify, 6
.equ EnterNotify, 7
.equ LeaveNotify, 8
.equ Expose, 12
.equ ClientMessage, 33
.equ KeyPressMask, 1
.equ ButtonPressMask, 4
.equ ButtonReleaseMask, 8
.equ ExposureMask, 1<<15
.equ StructureNotifyMask, 1<<17
.equ EnterWindowMask, 1<<4
.equ LeaveWindowMask, 1<<5
.equ ConfigureNotify, 22
/*******************************************/
/* DONNEES INITIALISEES */
/*******************************************/
.data
szWindowName: .asciz "Windows Raspberry"
szRetourligne: .asciz "\n"
szMessDebutPgm: .asciz "Program start. \n"
szMessErreur: .asciz "Server X not found.\n"
szMessErrfen: .asciz "Can not create window.\n"
szMessErreurX11: .asciz "Error call function X11. \n"
szMessErrGc: .asciz "Can not create graphics context.\n"
szTitreFenRed: .asciz "Pi"
szTexte1: .asciz "<- red pixel is here !!"
.equ LGTEXTE1, . - szTexte1
szTexte2: .asciz "Press q for close window or clic X in system menu."
.equ LGTEXTE2, . - szTexte2
szLibDW: .asciz "WM_DELETE_WINDOW" @ special label for correct close error
/*************************************************/
szMessErr: .ascii "Error code hexa : "
sHexa: .space 9,' '
.ascii " decimal : "
sDeci: .space 15,' '
.asciz "\n"
/*******************************************/
/* DONNEES NON INITIALISEES */
/*******************************************/
.bss
.align 4
ptDisplay: .skip 4 @ pointer display
ptEcranDef: .skip 4 @ pointer screen default
ptFenetre: .skip 4 @ pointer window
ptGC: .skip 4 @ pointer graphic context
ptGC1: .skip 4 @ pointer graphic context1
key: .skip 4 @ key code
wmDeleteMessage: .skip 8 @ ident close message
event: .skip 400 @ TODO event size ??
PrpNomFenetre: .skip 100 @ window name proprety
buffer: .skip 500
iWhite: .skip 4 @ rgb code for white pixel
iBlack: .skip 4 @ rgb code for black pixel
/**********************************************/
/* -- Code section */
/**********************************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessDebutPgm @
bl affichageMess @ display start message on console linux
/* attention r6 pointer display*/
/* attention r8 pointer graphic context */
/* attention r9 ident window */
/*****************************/
/* OPEN SERVER X11 */
/*****************************/
mov r0,#0
bl XOpenDisplay @ open X server
cmp r0,#0 @ error ?
beq erreurServeur
ldr r1,iAdrptDisplay
str r0,[r1] @ store display address
mov r6,r0 @ and in register r6
ldr r2,[r0,#+132] @ load default_screen
ldr r1,iAdrptEcranDef
str r2,[r1] @ store default_screen
mov r2,r0
ldr r0,[r2,#+140] @ load pointer screen list
ldr r5,[r0,#+52] @ load value white pixel
ldr r4,iAdrWhite @ and store in memory
str r5,[r4]
ldr r3,[r0,#+56] @ load value black pixel
ldr r4,iAdrBlack @ and store in memory
str r3,[r4]
ldr r4,[r0,#+28] @ load bits par pixel
ldr r1,[r0,#+8] @ load root windows
/**************************/
/* CREATE WINDOW */
/**************************/
mov r0,r6 @ address display
mov r2,#0 @ window position X
mov r3,#0 @ window position Y
mov r8,#0 @ for stack alignement
push {r8}
push {r3} @ background = black pixel
push {r5} @ border = white pixel
mov r8,#2 @ border size
push {r8}
mov r8,#240 @ hauteur
push {r8}
mov r8,#320 @ largeur
push {r8}
bl XCreateSimpleWindow
add sp,#24 @ stack alignement 6 push (4 bytes * 6)
cmp r0,#0 @ error ?
beq erreurF
ldr r1,iAdrptFenetre
str r0,[r1] @ store window address in memory
mov r9,r0 @ and in register r9
/*****************************/
/* add window property */
/*****************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
ldr r2,iAdrszWindowName @ window name
ldr r3,iAdrszTitreFenRed @ window name reduced
mov r4,#0
push {r4} @ parameters not use
push {r4}
push {r4}
push {r4}
bl XSetStandardProperties
add sp,sp,#16 @ stack alignement for 4 push
/**************************************/
/* for correction window close error */
/**************************************/
mov r0,r6 @ display address
ldr r1,iAdrszLibDW @ atom address
mov r2,#1 @ False créate atom if not exists
bl XInternAtom
cmp r0,#0 @ error X11 ?
ble erreurX11
ldr r1,iAdrwmDeleteMessage @ recept address
str r0,[r1]
mov r2,r1 @ return address
mov r0,r6 @ display address
mov r1,r9 @ window address
mov r3,#1 @ number of protocols
bl XSetWMProtocols
cmp r0,#0 @ error X11 ?
ble erreurX11
/**********************************/
/* create graphic context */
/**********************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
mov r2,#0 @ not use for simply context
mov r3,#0
bl XCreateGC
cmp r0,#0 @ error ?
beq erreurGC
ldr r1,iAdrptGC
str r0,[r1] @ store address graphic context
mov r8,r0 @ and in r8
@ create other GC
mov r0,r6 @ display address
mov r1,r9 @ window address
mov r2,#0 @ not use for simply context
mov r3,#0
bl XCreateGC
cmp r0,#0 @ error ?
beq erreurGC
ldr r1,iAdrptGC1
str r0,[r1] @ store address graphic context 1
mov r1,r0
mov r0,r6
mov r2,#0xFF0000 @ color red
bl XSetForeground
cmp r0,#0
beq erreurGC
/****************************/
/* modif window background */
/****************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
ldr r2,iGris1 @ background color
bl XSetWindowBackground
cmp r0,#0 @ error ?
ble erreurX11
/***************************/
/* OUF!! window display */
/***************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
bl XMapWindow
/****************************/
/* Write text1 in the window */
/****************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
mov r2,r8 @ address graphic context
mov r3,#105 @ position x
sub sp,#4 @ stack alignement
mov r4,#LGTEXTE1 - 1 @ size string
push {r4} @ on the stack
ldr r4,iAdrszTexte1 @ string address
push {r4}
mov r4,#105 @ position y
push {r4}
bl XDrawString
add sp,sp,#16 @ stack alignement 3 push and 1 stack alignement
cmp r0,#0 @ error ?
blt erreurX11
/****************************/
/* Write text2 in the window */
/****************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
mov r2,r8 @ address graphic context
mov r3,#10 @ position x
sub sp,#4 @ stack alignement
mov r4,#LGTEXTE2 - 1 @ size string
push {r4} @ on the stack
ldr r4,iAdrszTexte2 @ string address
push {r4}
mov r4,#200 @ position y
push {r4}
bl XDrawString
add sp,sp,#16 @ stack alignement 3 push and 1 stack alignement
cmp r0,#0 @ error ?
blt erreurX11
/****************************************/
/* draw pixel */
/****************************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
ldr r2,iAdrptGC1
ldr r2,[r2] @ address graphic context 1
mov r3,#100 @ position x
sub sp,sp,#4 @ stack alignement
mov r4,#100 @ position y
push {r4} @ on the stack
bl XDrawPoint
add sp,sp,#8 @ stack alignement 1 push and 1 stack alignement
cmp r0,#0 @ error ?
blt erreurX11
/****************************/
/* Autorisations */
/****************************/
mov r0,r6 @ display address
mov r1,r9 @ window address
ldr r2,iFenetreMask @ autorisation mask
bl XSelectInput
cmp r0,#0 @ error ?
ble erreurX11
/****************************/
/* Events loop */
/****************************/
1:
mov r0,r6 @ display address
ldr r1,iAdrevent @ events address
bl XNextEvent @ event ?
ldr r0,iAdrevent
ldr r0,[r0] @ code event
cmp r0,#KeyPressed @ key ?
bne 2f
ldr r0,iAdrevent @ yes read key in buffer
ldr r1,iAdrbuffer
mov r2,#255
ldr r3,iAdrkey
mov r4,#0
push {r4} @ stack alignement
push {r4}
bl XLookupString
add sp,#8 @ stack alignement 2 push
cmp r0,#1 @ is character key ?
bne 2f
ldr r0,iAdrbuffer @ yes -> load first buffer character
ldrb r0,[r0]
cmp r0,#0x71 @ character q for quit
beq 5f @ yes -> end
b 4f
2:
/* */
/* for example clic mouse button */
/************************************/
cmp r0,#ButtonPress @ clic mouse buton
bne 3f
ldr r0,iAdrevent
ldr r1,[r0,#+32] @ position X mouse clic
ldr r2,[r0,#+36] @ position Y
@ etc for eventuel use
b 4f
3:
cmp r0,#ClientMessage @ code for close window within error
bne 4f
ldr r0,iAdrevent
ldr r1,[r0,#+28] @ code message address
ldr r2,iAdrwmDeleteMessage @ equal code window créate ???
ldr r2,[r2]
cmp r1,r2
beq 5f @ yes -> end window
4: @ loop for other event
b 1b
/***********************************/
/* Close window -> free ressources */
/***********************************/
5:
mov r0,r6 @ display address
ldr r1,iAdrptGC
ldr r1,[r1] @ load context graphic address
bl XFreeGC
cmp r0,#0
blt erreurX11
mov r0,r6 @ display address
mov r1,r9 @ window address
bl XDestroyWindow
cmp r0,#0
blt erreurX11
mov r0,r6 @ display address
bl XCloseDisplay
cmp r0,#0
blt erreurX11
mov r0,#0 @ return code OK
b 100f
erreurF: @ create error window but possible not necessary. Display error by server
ldr r1,iAdrszMessErrfen
bl displayError
mov r0,#1 @ return error code
b 100f
erreurGC: @ error create graphic context
ldr r1,iAdrszMessErrGc
bl displayError
mov r0,#1
b 100f
erreurX11: @ erreur X11
ldr r1,iAdrszMessErreurX11
bl displayError
mov r0,#1
b 100f
erreurServeur: @ error no found X11 server see doc putty and Xming
ldr r1,iAdrszMessErreur
bl displayError
mov r0,#1
b 100f
100: @ standard end of the program
mov r7, #EXIT
svc 0
iFenetreMask: .int KeyPressMask|ButtonPressMask|StructureNotifyMask
iGris1: .int 0xFFA0A0A0
iAdrWhite: .int iWhite
iAdrBlack: .int iBlack
iAdrptDisplay: .int ptDisplay
iAdrptEcranDef: .int ptEcranDef
iAdrptFenetre: .int ptFenetre
iAdrptGC: .int ptGC
iAdrptGC1: .int ptGC1
iAdrevent: .int event
iAdrbuffer: .int buffer
iAdrkey: .int key
iAdrszLibDW: .int szLibDW
iAdrszMessDebutPgm: .int szMessDebutPgm
iAdrszMessErreurX11: .int szMessErreurX11
iAdrszMessErrGc: .int szMessErrGc
iAdrszMessErreur: .int szMessErreur
iAdrszMessErrfen: .int szMessErrfen
iAdrszWindowName: .int szWindowName
iAdrszTitreFenRed: .int szTitreFenRed
iAdrszTexte1: .int szTexte1
iAdrszTexte2: .int szTexte2
iAdrPrpNomFenetre: .int PrpNomFenetre
iAdrwmDeleteMessage: .int wmDeleteMessage
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registres
mov r2,#0 @ counter length
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index
cmp r1,#0 @ if 0 its over
addne r2,r2,#1 @ else add 1 in the length
bne 1b @ and loop
@ so here r2 contains the length of the message
mov r1,r0 @ address message in r1
mov r0,#STDOUT @ code to write to the standard output Linux
mov r7, #WRITE @ code call system "write"
svc #0 @ call systeme
pop {r0,r1,r2,r7,lr} @ restaur registers
bx lr @ return
/***************************************************/
/* display error message */
/***************************************************/
/* r0 contains error code r1 : message address */
displayError:
push {r0-r2,lr} @ save registers
mov r2,r0 @ save error code
mov r0,r1
bl affichageMess
mov r0,r2 @ error code
ldr r1,iAdrsHexa
bl conversion16 @ conversion hexa
mov r0,r2 @ error code
ldr r1,iAdrsDeci @ result address
bl conversion10 @ conversion decimale
ldr r0,iAdrszMessErr @ display error message
bl affichageMess
100:
pop {r0-r2,lr} @ restaur registers
bx lr @ return
iAdrszMessErr: .int szMessErr
iAdrsHexa: .int sHexa
iAdrsDeci: .int sDeci
/******************************************************************/
/* Converting a register to hexadecimal */
/******************************************************************/
/* r0 contains value and r1 address area */
conversion16:
push {r1-r4,lr} @ save registers
mov r2,#28 @ start bit position
mov r4,#0xF0000000 @ mask
mov r3,r0 @ save entry value
1: @ start loop
and r0,r3,r4 @value register and mask
lsr r0,r2 @ move right
cmp r0,#10 @ compare value
addlt r0,#48 @ <10 ->digit
addge r0,#55 @ >10 ->letter A-F
strb r0,[r1],#1 @ store digit on area and + 1 in area address
lsr r4,#4 @ shift mask 4 positions
subs r2,#4 @ counter bits - 4 <= zero ?
bge 1b @ no -> loop
100:
pop {r1-r4,lr} @ restaur registers
bx lr @return
/******************************************************************/
/* Converting a register to a decimal unsigned */
/******************************************************************/
/* r0 contains value and r1 address area */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes */
.equ LGZONECAL, 10
conversion10:
push {r1-r4,lr} @ save registers
mov r3,r1
mov r2,#LGZONECAL
1: @ start loop
bl divisionpar10U @ unsigned r0 <- dividende. quotient ->r0 reste -> r1
add r1,#48 @ digit
strb r1,[r3,r2] @ store digit on area
cmp r0,#0 @ stop if quotient = 0
subne r2,#1 @ else previous position
bne 1b @ and loop
@ and move digit from left of area
mov r4,#0
2:
ldrb r1,[r3,r2]
strb r1,[r3,r4]
add r2,#1
add r4,#1
cmp r2,#LGZONECAL
ble 2b
@ and move spaces in end on area
mov r0,r4 @ result length
mov r1,#' ' @ space
3:
strb r1,[r3,r4] @ store space in area
add r4,#1 @ next position
cmp r4,#LGZONECAL
ble 3b @ loop if r4 <= area size
100:
pop {r1-r4,lr} @ restaur registres
bx lr @return
/***************************************************/
/* division par 10 unsigned */
/***************************************************/
/* r0 dividende */
/* r0 quotient */
/* r1 remainder */
divisionpar10U:
push {r2,r3,r4, lr}
mov r4,r0 @ save value
ldr r3,iMagicNumber @ r3 <- magic_number raspberry 1 2
umull r1, r2, r3, r0 @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
mov r0, r2, LSR #3 @ r2 <- r2 >> shift 3
add r2,r0,r0, lsl #2 @ r2 <- r0 * 5
sub r1,r4,r2, lsl #1 @ r1 <- r4 - (r2 * 2) = r4 - (r0 * 10)
pop {r2,r3,r4,lr}
bx lr @ leave function
iMagicNumber: .int 0xCCCCCCCD
/***************************************************/
/* integer division unsigned */
/***************************************************/
division:
/* r0 contains dividend */
/* r1 contains divisor */
/* r2 returns quotient */
/* r3 returns remainder */
push {r4, lr}
mov r2, #0 @ init quotient
mov r3, #0 @ init remainder
mov r4, #32 @ init counter bits
b 2f
1: @ loop
movs r0, r0, LSL #1 @ r0 <- r0 << 1 updating cpsr (sets C if 31st bit of r0 was 1)
adc r3, r3, r3 @ r3 <- r3 + r3 + C. This is equivalent to r3 ? (r3 << 1) + C
cmp r3, r1 @ compute r3 - r1 and update cpsr
subhs r3, r3, r1 @ if r3 >= r1 (C=1) then r3 <- r3 - r1
adc r2, r2, r2 @ r2 <- r2 + r2 + C. This is equivalent to r2 <- (r2 << 1) + C
2:
subs r4, r4, #1 @ r4 <- r4 - 1
bpl 1b @ if r4 >= 0 (N=0) then loop
pop {r4, lr}
bx lr
AutoHotkey
From AHK Forum
Gui, Add, Picture, x100 y100 w2 h2 +0x4E +HWNDhPicture
CreatePixel("FF0000", hPicture)
Gui, Show, w320 h240, Example
return
CreatePixel(Color, Handle) {
VarSetCapacity(BMBITS, 4, 0), Numput("0x" . Color, &BMBITS, 0, "UInt")
hBM := DllCall("Gdi32.dll\CreateBitmap", "Int", 1, "Int", 1, "UInt", 1, "UInt", 24, "Ptr", 0, "Ptr")
hBM := DllCall("User32.dll\CopyImage", "Ptr", hBM, "UInt", 0, "Int", 0, "Int", 0, "UInt", 0x2008, "Ptr")
DllCall("Gdi32.dll\SetBitmapBits", "Ptr", hBM, "UInt", 3, "Ptr", &BMBITS)
DllCall("User32.dll\SendMessage", "Ptr", Handle, "UInt", 0x172, "Ptr", 0, "Ptr", hBM)
}
BASIC
Applesoft BASIC
100 WIDTH = 320
110 HEIGHT = 240
120 C = 1: REM RED
130 X = 100
140 Y = 100
150 DEF FN X(X) = INT ((X - 1) / 14)
160 DEF FN Y(Y) = INT ((Y - 1) / 8)
170 W = FN X(WIDTH)
180 H = FN Y(HEIGHT)
190 WX = INT ( RND (1) * (40 - W))
200 WY = INT ( RND (1) * (48 - H))
210 C$ = "0123456789:;<=>?"
220 C$ = MID$ (C$,C,I) + MID$ (C$,C + 2, LEN (C$) - C - 1)
230 I = INT ( RND (1) * LEN (C$))
240 COLOR= ASC ( MID$ (C$,I + 1)) - 48
250 C$ = MID$ (C$,1,I) + MID$ (C$,I + 2, LEN (C$) - I - 1)
260 A = PEEK (49234) + PEEK (49240) + PEEK (49232)
270 FOR I = 0 TO 39
280 VLIN 0,47 AT I
290 NEXT
300 COLOR= ASC ( MID$ (C$, INT ( RND (1) * LEN (C$)) + 1)) - 48
310 FOR I = WX TO WX + W
320 VLIN WY,WY + H AT I
330 NEXT
340 COLOR= C
350 PLOT WX + FN X(X),WY + FN Y(Y)
360 WAIT 49152,128
370 TEXT
380 HOME
BASIC256
It seems that the program should be this. And the BASIC256 tutorial programs work on my ubuntu system. This program neither draws the pixel nor resizes the window. Can't see anything when I plot many spots. Oh well. I've tried the rgb(255,0,0) function as well as the fastgraphics/refresh statements.
rem http://rosettacode.org/wiki/Draw_a_pixel
graphsize 320, 240
color red
plot 100, 100
BBC BASIC
VDU 23, 22, 320; 240; 8, 8, 8, 128, 18, 0, 9, 25, 69, 100; 100;
Commodore BASIC
The Commodore 8-bit machines only had 200 lines of vertical resolution (and the VIC-20 rarely used more than 160 of them for bitmap graphics), so these examples do not quite fit the task's 240-line requirement.
Example 1: VIC-20 with SuperExpander Cartridge
Version 2 of Commodore BASIC, which shipped on the VIC-20 and Commodore 64, did not have any graphics support. A stock VIC didn't have enough memory for high-resolution graphics anyway, so they mostly weren't used. But Commodore shipped a "SuperExpander" cartridge for the VIC which not only included enough extra RAM to support a 160x160-pixel bitmap, but also extended BASIC to include statements for drawing on it. One oddity about the VIC's iteration of the SuperExpander is that, despite the low 160x160 resolution, it treats the screen as having 1024x1024 pixels; the below program compensates for this by asking for a dot at 640,640, which maps to the physical pixel at 100,100.
10 COLOR 0,0,2,2: REM BLACK BACKGROUND AND BORDER, RED TEXT AND EXTRA COLOR
20 GRAPHIC 2:SCNCLR:REM SELECT HI-RES GRAPHICS AND CLEAR THE SCREEN
30 POINT 2,640,640:REM DRAW A POINT AT 640/1024*160,640/1024*160
40 GET K$:IF K$="" THEN 40: REM WAIT FOR KEYPRESS
50 GRAPHIC 0:REM BACK TO TEXT MODE
Example 2: Commodore 64 with built-in BASIC
The C-64 shipped with much better graphics capabilities than the VIC-20, and was originally supposed to have an extended BASIC to take advantage of them, but Commodore ran out of time before the Christmas shopping deadline and shipped it with the same BASIC that was in the VIC. It was feasible to do graphics from the onboard BASIC, as this program demonstrates; it's just slow and awkward, so programmers usually built hi-res graphics routines using machine language.
To create graphics via manual memory manipulation, it's necessary to understand the layout of the screen. Unlike many other bitmap systems, the C64's bitmap was broken up into the 8x8-pixel cells used for text characters, even in high-resolution graphics mode. So while the first byte of video RAM unsurprisingly contains the leftmost 8 pixels on the top row of the screen, the second byte contains the 8 pixels directly below those, and so on for eight rows, before the ninth byte returns us to the top row for its 9th through 16th pixels. This requires calculation on the programmer's part to translate X,Y coordinates into a specific memory address/value combination (lines 30 through 60).
10 REM PLOT A RED PIXEL AT 100,100
20 REM INITIALIZE BITMAP MODE
21 POKE 53280,0:PRINT CHR$(147);"CLEARING BITMAP... PLEASE WAIT..."
22 BASE=8192:FOR I=BASE TO BASE+7999:POKE I,0:NEXT
23 PRINT CHR$(147);
24 POKE 53272,PEEK(53272) OR 8:REM SET BITMAP MEMORY AT 8192 ($2000)
25 POKE 53265,PEEK(53265) OR 32:REM ENTER BITMAP MODE
26 REM PLOT PIXEL
30 X=100:Y=100
40 MEM=BASE+INT(Y/8)*320+INT(X/8)*8+(Y AND 7)
50 PX=7-(X AND 7)
60 POKE MEM,PEEK(MEM) OR 2^PX
65 REM WAIT FOR KEYPRESS
70 GET K$:IF K$="" THEN 70
75 REM CLEAR PIXEL, RETURN TO TEXT MODE
80 POKE MEM,0:POKE 53265,PEEK(53265) AND 223:POKE 53272,PEEK(53272) AND 247
90 POKE 53280,14:POKE 53281,6:POKE 646,14:END
Example 3: Commodore 64 with SuperExpander Cartridge
Commodore released a version of the SuperExpander Cartridge for the C64 that was similar to the one for the VIC-20, but not identical. Besides some differences in the actual BASIC statements, it also does not have the artificial scale factor; graphics statements instead take physical pixel coordinates.
10 COLOR 0,2,,,0: REM SET BACKGROUND AND BORDER TO BLACK, FOREGROUND TO RED
20 GRAPHIC 2,1:REM SELECT HIRES GRAPHICS AND CLEAR THE SCREEN
30 DRAW 1,100,100:REM DRAW A PIXEL AT 100,100
40 GET K$:IF K$="" THEN 40:REM WAIT FOR A KEYPRESS
50 GRAPHIC 0:REM RETURN TO TEXT MODE
Example 4: Commodore Plus/4, C-16, and 128 (40-column display)
By the time the Commodore Plus/4 and C-16 were released, Commodore was ready to ship them with a version of BASIC, dubbed version 3.5, that included graphic support out of the box. The statements were again similar to but slightly different from what had come before in the SuperExpander cartridges. When the Commodore 128 was released, its version of BASIC, 7.0, included all of 3.5 essentially unchanged.
10 COLOR 0,1:COLOR 1,3: REM SET BACKGROUND TO BLACK AND PIXEL COLOR TO RED
15 GRAPHIC 1,1 : REM ENTER BITMAP GRAPHICS MODE AND CLEAR SCREEN
20 DRAW 1,100,100 : REM PLOT PIXEL AT 100,100
30 GETKEY K$: REM WAIT FOR KEYPRESS THE NEW WAY
40 GRAPHIC 0,1 : REM RETURN TO TEXT MODE
Example 5: Commodore 128 (80-column display)
While the Commodore 128's BASIC 7.0 had impressive support for graphics on the 40-column display, it had no such support for bitmap graphics on the double-resolution 80-column display provided by its VDC chip. For that, we turn to BASIC 8, which was released as a separate software package that had to be loaded (or installed as a chip on the C128's motherboard). It was developed outside of Commodore and has a syntax very different from the standard BASIC's graphic commands, but it supports 3D graphics out of the box, including viewport clipping, scaling, etc. Note that the below program specifies a Z coordinate of 0 for the dot, which places it on the surface of the viewport.
10 @MODE,0:REM SELECT SCREEN SET
20 @COLOR,0,9,0:REM BACKGROUND BLACK, FOREGROUND BRIGHT RED
30 @SCREEN,0,0:REM SELECT MONOCHROME MODE
40 @CLEAR,0:REM CLEAR THE SCREEN
50 @DRWMODA,2,0,0,0,0,0,0:REM USE @COLOR COLORS
60 @SCALE,0:REM NO SCALING
70 @DOT,100,100,0:REM DRAW DOT
80 GETKEY K$:REM WAIT FOR KEYPRESS
90 @TEXT:REM BACK TO TEXT MODE
ProgressBASIC
ProgressBASIC can't create windows due to obvious reasons
10 COLOR 13 20 PLOT 100,100
IS-BASIC
100 SET VIDEO X 40:SET VIDEO Y 26:SET VIDEO MODE 5:SET VIDEO COLOR 0
110 OPEN #101:"video:"
120 DISPLAY #101:AT 1 FROM 1 TO 26
130 SET PALETTE BLACK,RED
140 PLOT 100,100
SmallBASIC
w = window()
w.setSize(320, 240)
pset 100, 100, rgb(255, 0, 0)
C
Requires the WinBGIm library.
#include<graphics.h>
int main()
{
initwindow(320,240,"Red Pixel");
putpixel(100,100,RED);
getch();
return 0;
}
Plain Xlib version
Which is why most people use a framework :)
// dotrosetta.c - https://rosettacode.org/wiki/Draw_a_pixel
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
Atom wm_both_protocols[1];
Atom wm_delete;
Atom wm_protocols;
Display *display;
GC gc;
Window root;
Window window;
XEvent event;
XSetWindowAttributes attr;
int more = 1;
display = XOpenDisplay(NULL);
if(display == NULL)
{
fprintf(stderr,"Error: The display cannot be opened\n");
exit(1);
}
root = DefaultRootWindow(display);
wm_delete = XInternAtom(display, "WM_DELETE_WINDOW", False);
wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False);
attr.background_pixel = 0x000000;
attr.event_mask = ExposureMask;
window = XCreateWindow(display, root,
0, 0, 320, 240, 0,
CopyFromParent, InputOutput, CopyFromParent,
CWBackPixel | CWEventMask,
&attr
);
XStoreName(display, window, "Draw a Pixel");
wm_both_protocols[0] = wm_delete;
XSetWMProtocols(display, window, wm_both_protocols, 1);
gc = XCreateGC(display, window, 0, NULL);
XSetForeground(display, gc, 0xFF0000);
XMapWindow(display, window);
while(more)
{
XNextEvent(display, &event);
switch(event.type)
{
case Expose:
XDrawPoint(display, window, gc, 100, 100);
break;
case ClientMessage: // for close request from WM
if(event.xclient.window == window &&
event.xclient.message_type == wm_protocols &&
event.xclient.format == 32 &&
event.xclient.data.l[0] == wm_delete)
{
more = 0;
}
break;
default:
printf("unexpected event.type %d\n", event.type);;
}
}
XCloseDisplay(display);
exit(0);
}
Delphi
Console version using windows api, thanks for RRUZ ([1])
program Draw_a_pixel;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Windows,
Messages,
SysUtils;
var
Msg: TMSG;
LWndClass: TWndClass;
hMainHandle: HWND;
procedure Paint(Handle: hWnd); forward;
procedure ReleaseResources;
begin
PostQuitMessage(0);
end;
function WindowProc(hWnd, Msg: Longint; wParam: wParam; lParam: lParam): Longint; stdcall;
begin
case Msg of
WM_PAINT:
Paint(hWnd);
WM_DESTROY:
ReleaseResources;
end;
Result := DefWindowProc(hWnd, Msg, wParam, lParam);
end;
procedure CreateWin(W, H: Integer);
begin
LWndClass.hInstance := hInstance;
with LWndClass do
begin
lpszClassName := 'OneRedPixel';
Style := CS_PARENTDC or CS_BYTEALIGNCLIENT;
hIcon := LoadIcon(hInstance, 'MAINICON');
lpfnWndProc := @WindowProc;
hbrBackground := COLOR_BTNFACE + 1;
hCursor := LoadCursor(0, IDC_ARROW);
end;
RegisterClass(LWndClass);
hMainHandle := CreateWindow(LWndClass.lpszClassName,
'Draw a red pixel on (100,100)', WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU
or WS_VISIBLE, ((GetSystemMetrics(SM_CXSCREEN) - W) div 2), ((GetSystemMetrics
(SM_CYSCREEN) - H) div 2), W, H, 0, 0, hInstance, nil);
end;
procedure ShowModal;
begin
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
procedure Paint(Handle: hWnd);
var
ps: PAINTSTRUCT;
Dc: HDC;
begin
Dc := BeginPaint(Handle, ps);
// Fill bg with white
FillRect(Dc, ps.rcPaint, CreateSolidBrush($FFFFFF));
// Do the magic
SetPixel(Dc, 100, 100, $FF);
EndPaint(Handle, ps);
end;
begin
CreateWin(320, 240);
ShowModal();
end.
- Output:
EasyLang
The Easylang graphic does not work with pixels. Although the drawing area is set to be 100x100 units - not pixels - this can be scaled and it can be drawn on intermediate positions. A pixel can be simulated by a small filled square.
color 900
move 50 50
rect 0.5 0.5
F#
Uses Windows Forms
open System.Windows.Forms
open System.Drawing
let f = new Form()
f.Size <- new Size(320,240)
f.Paint.Add(fun e -> e.Graphics.FillRectangle(Brushes.Red, 100, 100 ,1,1))
Application.Run(f)
Factor
USING: accessors arrays images images.testing images.viewer
kernel literals math sequences ;
IN: rosetta-code.draw-pixel
: draw-pixel ( -- )
B{ 255 0 0 } 100 100 <rgb-image> 320 240 [ 2array >>dim ]
[ * ] 2bi [ { 0 0 0 } ] replicate B{ } concat-as >>bitmap
[ set-pixel-at ] keep image-window ;
MAIN: draw-pixel
Evaldraw
Assumes you resize your Evaldraw instance to 320x240 or open it from commandline with "evaldraw program.kc /320x240"
()
cls(0);
setcol(255,0,0);
setpix(100,100);
Forth
\ Bindings to SDL2 functions
s" SDL2" add-lib
\c #include <SDL2/SDL.h>
c-function sdl-init SDL_Init n -- n
c-function sdl-quit SDL_Quit -- void
c-function sdl-createwindow SDL_CreateWindow a n n n n n -- a
c-function sdl-createrenderer SDL_CreateRenderer a n n -- a
c-function sdl-setdrawcolor SDL_SetRenderDrawColor a n n n n -- n
c-function sdl-drawpoint SDL_RenderDrawPoint a n n -- n
c-function sdl-renderpresent SDL_RenderPresent a -- void
c-function sdl-delay SDL_Delay n -- void
: pixel ( -- )
$20 sdl-init drop
s\" Rosetta Task : Draw a pixel\x0" drop 0 0 320 240 $0 sdl-createwindow
( window ) -1 $2 sdl-createrenderer
dup ( renderer ) 255 0 0 255 sdl-setdrawcolor drop
dup ( renderer ) 100 100 sdl-drawpoint drop
( renderer ) sdl-renderpresent
5000 sdl-delay
sdl-quit
;
pixel
FreeBASIC
' version 27-06-2018
' compile with: fbc -s console
' or: fbc -s gui
Screen 13 ' Screen 18: 320x200, 8bit colordepth
'ScreenRes 320, 200, 24 ' Screenres: 320x200, 24bit colordepth
If ScreenPtr = 0 Then
Print "Error setting video mode!"
End
End If
Dim As UInteger depth, x = 100, y = 100
' what is color depth
ScreenInfo ,,depth
If depth = 8 Then
PSet(x, y), 40 ' palette, index 40 = RGB(255, 0, 0)
Else
PSet(x, y), RGB(255, 0, 0) ' red
End If
' empty keyboard buffer
While Inkey <> "" : Wend
WindowTitle IIf(depth = 8, "Palette","True Color") + ", hit any key to end program"
Sleep
End
Frink
i = new image[320,240]
i.setPixel[100,100,1,0,0]
i.show[]
FutureBasic
void local fn BuildWindow
CGRect r = fn CGRectMake( 0, 0, 320, 240 )
window 1, @"Single Pixel", r, NSWindowStyleMaskTitled + NSWindowStyleMaskClosable
oval fill fn CGRectMake( 100-0.5, 100-0.5, 1, 1 ), fn ColorRed
end fn
void local fn DoDialog( ev as long, tag as long, wnd as long )
select ( ev )
case _windowWillClose : end
end select
end fn
on dialog fn DoDialog
fn BuildWindow
HandleEvents
GB BASIC
The resolution of the Game Boy's screen is only 160×144, so the window requirement is out, but the pixel is easy. Also, GB BASIC doesn't support displaying the color red, so the Game Boy's grayscale equivalent, dark gray, is used instead:
10 color 1
20 point 100,100
GML
draw_point(100, 100);
Go
package main
import (
"fmt"
"image"
"image/color"
"image/draw"
)
func main() {
rect := image.Rect(0, 0, 320, 240)
img := image.NewRGBA(rect)
// Use green background, say.
green := color.RGBA{0, 255, 0, 255}
draw.Draw(img, rect, &image.Uniform{green}, image.ZP, draw.Src)
// Set color of pixel at (100, 100) to red
red := color.RGBA{255, 0, 0, 255}
img.Set(100, 100, red)
// Check it worked.
cmap := map[color.Color]string{green: "green", red: "red"}
c1 := img.At(0, 0)
c2 := img.At(100, 100)
fmt.Println("The color of the pixel at ( 0, 0) is", cmap[c1], "\b.")
fmt.Println("The color of the pixel at (100, 100) is", cmap[c2], "\b.")
}
- Output:
The color of the pixel at ( 0, 0) is green. The color of the pixel at (100, 100) is red.
Create a PNG image?
package main import ( "image" "image/color" "image/draw" "image/png" "os" ) func main() { // Create a 320 x 240 image img := image.NewRGBA(image.Rect(0, 0, 320, 240)) // fill img in white draw.Draw(img, img.Bounds(), &image.Uniform{color.RGBA{0, 0, 0, 0}}, image.ZP, draw.Src) // Draw a red dot at (100, 100) img.Set(100, 100, color.RGBA{255, 0, 0, 255}) // Save to new.png w, _ := os.OpenFile("new.png", os.O_WRONLY|os.O_CREATE, 0600) defer w.Close() png.Encode(w, img) }
GUI "window" rather than an image?
package main // first run" go get github.com/zserge/webview" // simple GUI "window" import "github.com/zserge/webview" func main() { // Open wikipedia in a 320*240 resizable window webview.Open("Minimal webview example", "https://en.m.wikipedia.org/wiki/Main_Page", 320, 240, true) }
Icon and Unicon
#
# draw-pixel.icn
#
procedure main()
&window := open("pixel", "g", "size=320,240")
Fg("#ff0000")
DrawPoint(100, 100)
Event()
end
J
require 'gl2'
coinsert 'jgl2'
wd'pc Rosetta closeok;cc task isidraw; set task wh 320 200;pshow'
glpaint glpixel 100 100 [ glpen 1 1 [ glrgb 255 0 0 [ glclear ''
Note that this single pixel tends to be invisible or almost invisible on "modern" screens. You may wish to change this to use glpen 4 1
if this is a problem on your system (though that technically would violate the requirements of this task, since we would not longer be drawing a single red pixel).
Java
Basic Implementation via subclass of JFrame:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class DrawAPixel extends JFrame{
public DrawAPixel() {
super("Red Pixel");
setSize(320, 240);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
@Override
public void paint(Graphics g) {
g.setColor(new Color(255, 0, 0));
g.drawRect(100, 100, 1, 1);
}
public static void main(String[] args) {
new DrawAPixel();
}
}
Advanced Implementation via subclass of JPanel (more powerful especially while repainting):
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawAPixel extends JPanel{
private BufferedImage puffer;
private JFrame window;
private Graphics g;
public DrawAPixel() {
window = new JFrame("Red Pixel");
window.setSize(320, 240);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLayout(null);
setBounds(0, 0, 320, 240);
window.add(this);
window.setVisible(true);
}
@Override
public void paint(Graphics gr) {
if(g == null) {
puffer = (BufferedImage) createImage(getWidth(), getHeight());
g = puffer.getGraphics();
}
g.setColor(new Color(255, 0, 0));
g.drawRect(100, 100, 1, 1);
gr.drawImage(puffer, 0, 0, this);
}
public static void main(String[] args) {
new DrawAPixel();
}
}
Julia
using Gtk, Graphics
const can = @GtkCanvas()
const win = GtkWindow(can, "Draw a Pixel", 320, 240)
draw(can) do widget
ctx = getgc(can)
set_source_rgb(ctx, 255, 0, 0)
move_to(ctx, 100, 100)
line_to(ctx, 101,100)
stroke(ctx)
end
show(can)
const cond = Condition()
endit(w) = notify(cond)
signal_connect(endit, win, :destroy)
wait(cond)
Kotlin
This task seems very similar to the Bitmap task and so therefore is the code to accomplish it.
// Version 1.2.41
import java.awt.Color
import java.awt.Graphics
import java.awt.image.BufferedImage
class BasicBitmapStorage(width: Int, height: Int) {
val image = BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)
fun fill(c: Color) {
val g = image.graphics
g.color = c
g.fillRect(0, 0, image.width, image.height)
}
fun setPixel(x: Int, y: Int, c: Color) = image.setRGB(x, y, c.getRGB())
fun getPixel(x: Int, y: Int) = Color(image.getRGB(x, y))
}
fun main(args: Array<String>) {
val bbs = BasicBitmapStorage(320, 240)
with (bbs) {
fill(Color.white) // say
setPixel(100, 100, Color.red)
// check it worked
val c = getPixel(100, 100)
print("The color of the pixel at (100, 100) is ")
println(if (c == Color.red) "red" else "white")
}
}
- Output:
The color of the pixel at (100, 100) is red
Lambdatalk
1) html/css
{div {@ style="position:relative;
left:0; top:0; width:320px; height:240px;
border:1px solid #000;"}
{div {@ style="position:absolute; left:100px; top:100px;
width:1px; height:1px; background:#f00; border:0;"}}}
2) svg
{svg {@ width="320" height="240"
style="border:1px solid #000;"}
{rect {@ x="100" y="100" width="1" height="1"
style="fill:#f00; stroke-width:0; stroke:#f00;"}}}
3) canvas
{canvas {@ id="canvas" width="320" height="240"
style="border:1px solid #000;"}}
{script
var canvas_pixel = function(x, y, canvas) {
var ctx = document.getElementById( canvas )
.getContext( "2d" );
ctx.fillStyle = "#f00";
ctx.fillRect(x,y,1,1);
};
setTimeout( canvas_pixel, 1, 100, 100, "canvas" )
}
Lua
The luasdl2 library is required.
local SDL = require "SDL"
local ret = SDL.init { SDL.flags.Video }
local window = SDL.createWindow {
title = "Pixel",
height = 320,
width = 240
}
local renderer = SDL.createRenderer(window, 0, 0)
renderer:clear()
renderer:setDrawColor(0xFF0000)
renderer:drawPoint({x = 100,y = 100})
renderer:present()
SDL.delay(5000)
M2000 Interpreter
Version 2
M2000 Console used for text and graphics too. So for this version we plot a pixel in console and in a form (a window above console). Form is open as modal, but console is something different, so we can show or hide it.
All forms are above console (for any kind, modal or not modal form), and we can hide console using Title statement. So in this example we hide/show console (behind form window) by clicking the form. In any state of showing console, when we close form and Interpreter need to input from console (like in prompt state), console state get visible.
There is also a PSet statement for pixel drawing (from 9.5 version). Just replace the module call to PlotPixel with Pset.
Module CheckIt {
Module PlotPixel (a as single, b as single) {
Move a*TwipsX, b*TwipsX
Draw TwipsX, TwipsY
}
Cls 5,0 \\ clear console with Magenta (5) and set split screen from 0 (no split screen)
Pen #55FF77 {
PlotPixel 1000, 200
}
Wait 1000
Title "", 1
Declare DrawPixelForm Form
With DrawPixelForm, "Title", "Draw a Pixel at 100,100"
Layer DrawPixelForm {
\\ 12 for 12pt fonts
\\ use ; to center window
Window 12, 320*twipsx, 240*twipsy;
Cls #333333
Pen Color(255,0,0) {
PlotPixel 100, 100
}
}
\\ code to show/hide console clicking form
\\ console shown behind form
k=0
Function DrawPixelForm.Click {
Title "Rosetta Code Example", abs(k)
if k then show
k~
}
Method DrawPixelForm, "Show", 1
Declare DrawPixelForm Nothing
}
CheckIt
Mathematica /Wolfram Language
CreateWindow[PaletteNotebook[{Graphics[{Red, Point[{100, 100}]}]}], WindowSize -> {320, 240}]
Maxima
/* Matrix that represents the window and the pixel positioned in it */
ematrix(320,240,1,100,100)$
/* Drawing the window and the pixel as needed */
wxdraw2d(palette = [white,gray,red], image(%,0,0,320,240))$
Microsoft Small Basic
GraphicsWindow.Width = 320
GraphicsWindow.Height = 240
GraphicsWindow.SetPixel(100, 100, GraphicsWindow.GetColorFromRGB(255, 0, 0))
MiniScript
gfx.clear color.black, 320, 240
gfx.setPixel 100, 100, rgb(255,0,0)
Nim
import rapid/gfx
var
window = initRWindow()
.size(320, 240)
.title("Rosetta Code - draw a pixel")
.open()
surface = window.openGfx()
surface.loop:
draw ctx, step:
ctx.clear(gray(0))
ctx.begin()
ctx.point((100.0, 100.0, rgb(255, 0, 0)))
ctx.draw(prPoints)
discard step # Prevent unused variable warnings
update step:
discard step
Another version using SDL2.
import sdl2
discard sdl2.init(INIT_EVERYTHING)
let window = createWindow("Pixel", 100, 100, 320, 240, SDL_WINDOW_SHOWN)
let renderer = createRenderer(window, -1, Renderer_Accelerated)
renderer.clear()
renderer.setDrawColor((255u8, 0u8, 0u8, 0u8))
renderer.drawPoint(100, 100)
renderer.present()
delay(5000)
Oberon
With basic module XYplane, the size of the drawing plane cannot be set. Tested with OBNC.
MODULE pixel;
IMPORT XYplane;
BEGIN
XYplane.Open;
XYplane.Dot(100, 100, XYplane.draw);
REPEAT UNTIL XYplane.Key() = "q"
END pixel.
Objeck
use Game.SDL2;
use Game.Framework;
class DrawPixel {
@framework : GameFramework;
function : Main(args : String[]) ~ Nil {
DrawPixel->New()->Run();
}
New() {
@framework := GameFramework->New(320, 240, "RGB");
@framework->SetClearColor(Color->New(0, 0, 0));
}
method : Run() ~ Nil {
if(@framework->IsOk()) {
e := @framework->GetEvent();
quit := false;
while(<>quit) {
@framework->FrameStart();
@framework->Clear();
while(e->Poll() <> 0) {
if(e->GetType() = EventType->SDL_QUIT) {
quit := true;
};
};
@framework->GetRenderer()->SetDrawColor(255, 0, 0, 255);
@framework->GetRenderer()->DrawPoint(100, 100);
@framework->Show();
@framework->FrameEnd();
};
}
else {
"--- Error Initializing Game Environment ---"->ErrorLine();
return;
};
leaving {
@framework->Quit();
};
}
}
OCaml
Using the Graphics library provided with the standard OCaml distribution:
module G = Graphics
let () =
G.open_graph "";
G.resize_window 320 240;
G.set_color G.red;
G.plot 100 100;
ignore (G.read_key ())
run with:
$ ocaml graphics.cma draw_a_pixel.ml
open Sdl
let () =
let width, height = (320, 240) in
Sdl.init [`VIDEO];
let window, renderer =
Render.create_window_and_renderer ~width ~height ~flags:[]
in
let rgb = (255, 0, 0) and a = 255 in
Render.set_draw_color renderer ~rgb ~a;
Render.draw_point renderer (100, 100);
Render.render_present renderer;
Timer.delay 3000;
Sdl.quit ()
run with:
$ ocaml -I $(ocamlfind query sdl2) sdl2.cma draw_a_pixel.ml
Odin
package main
import "vendor:sdl2"
main :: proc() {
using sdl2
window: ^Window = ---
renderer: ^Renderer = ---
event: Event = ---
Init(INIT_VIDEO)
CreateWindowAndRenderer(
640, 480,
WINDOW_SHOWN,
&window, &renderer
)
SetWindowTitle(window, "Empty window")
SetRenderDrawColor(renderer, 50, 255, 100, 255)
RenderDrawPoint(renderer, 100, 100)
RenderPresent(renderer)
for event.type != .QUIT {
Delay(10)
PollEvent(&event)
}
DestroyRenderer(renderer)
DestroyWindow(window)
Quit()
}
Ol
(import (lib gl))
(import (OpenGL version-1-0))
; init
(glClearColor 0.3 0.3 0.3 1)
(glOrtho 0 320 0 240 0 1)
; draw loop
(gl:set-renderer (lambda (mouse)
(glClear GL_COLOR_BUFFER_BIT)
(glBegin GL_POINTS)
(glColor3f 255 0 0)
(glVertex2f 100 100)
(glEnd)))
PascalABC.NET
uses GraphWPF;
begin
Window.SetSize(320,240);
SetPixel(100,100,Colors.Red);
end.
Perl
use Gtk3 '-init';
my $window = Gtk3::Window->new();
$window->set_default_size(320, 240);
$window->set_border_width(10);
$window->set_title("Draw a Pixel");
$window->set_app_paintable(TRUE);
my $da = Gtk3::DrawingArea->new();
$da->signal_connect('draw' => \&draw_in_drawingarea);
$window->add($da);
$window->show_all();
Gtk3->main;
sub draw_in_drawingarea
{
my ($widget, $cr, $data) = @_;
$cr->set_source_rgb(1, 0, 0);
$cr->set_line_width(1);
$cr->rectangle( 100, 100, 1, 1);
$cr->stroke;
}
Alternate with Perl/Tk
#!/usr/bin/perl
use strict; # https://rosettacode.org/wiki/Draw_a_pixel
use warnings;
use Tk;
my $mw = MainWindow->new;
my $canvas = $mw->Canvas( -width => 320, -height => 240 )->pack;
$canvas->createRectangle( 100, 100, 100, 100, -outline => 'red' );
MainLoop;
Alternate with X11::Protocol
#!/usr/bin/perl
use strict; # https://rosettacode.org/wiki/Draw_a_pixel
use warnings;
use X11::Protocol;
my $x = new X11::Protocol or die "X11 connection failed";
$x->CreateWindow(my $id = $x->new_rsrc, $x->root, 'InputOutput',
$x->root_depth, 'CopyFromParent',
0, 0, 320, 240, 0,
background_pixel => 0x000000,
event_mask => $x->pack_event_mask( qw( Exposure )),
);
$x->ChangeProperty($id, $x->atom('WM_NAME'), $x->atom('STRING'),
8, 'Replace', 'Draw a Pixel');
$x->ChangeProperty($id, $x->atom('WM_PROTOCOLS'), $x->atom('ATOM'),
32, 'Replace', pack('L', $x->atom('WM_DELETE_WINDOW')));
$x->CreateGC(my $gc = $x->new_rsrc, $id, foreground => 0xff0000);
$x->MapWindow($id);
$x->event_handler('queue');
my ($more, $name, %e) = 1;
while($more)
{
%e = $x->next_event;
$name = $e{name};
EVENT->$name;
}
sub EVENT::Expose { $x->PolyPoint($id, $gc, 'ORIGIN', 100, 100) }
sub EVENT::ConfigureNotify { }
sub EVENT::ClientMessage
{
if($e{type} == $x->atom('WM_PROTOCOLS') &&
unpack('L', $e{data}) == $x->atom('WM_DELETE_WINDOW'))
{
$more = 0;
}
else
{
warn "Unknown $name, $e{type}\n";
}
}
sub EVENT::AUTOLOAD { die "Sorry, no handler for $name\n" }
Phix
You can run this online here.
with javascript_semantics include pGUI.e cdCanvas cdcanvas function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/) cdCanvasActivate(cdcanvas) cdCanvasPixel(cdcanvas, 100, 100, CD_RED) cdCanvasFlush(cdcanvas) return IUP_DEFAULT end function function map_cb(Ihandle ih) cdcanvas = cdCreateCanvas(CD_IUP, ih) return IUP_DEFAULT end function procedure main() IupOpen() Ihandle canvas = IupCanvas(NULL) IupSetAttribute(canvas, "RASTERSIZE", "320x240") IupSetCallback(canvas, "MAP_CB", Icallback("map_cb")) Ihandle dlg = IupDialog(canvas) IupSetAttribute(dlg, "TITLE", "Draw a pixel") IupSetCallback(canvas, "ACTION", Icallback("redraw_cb")) IupShow(dlg) if platform()!=JS then IupMainLoop() IupClose() end if end procedure main()
Plain English
To run:
Start up.
Make a box 320 pixels by 240 pixels.
Draw the box with the white color and the white color.
Make a spot with 100 pixels and 100 pixels.
Draw the spot with the red color.
Refresh the screen.
Wait for the escape key.
Shut down.
Processing
A static-mode sketch containing setting one pixel on the canvas pixels array:
size(320, 240);
set(100, 100, color(255,0,0));
The same sketch in active mode sketch is:
void setup() {
size(320, 240);
set(100, 100, color(255,0,0));
}
Or a pixel can be manipulated through loading and modifying the pixels array. The formula to access a pixel is x + y * image width.
void setup() {
size(320, 240);
loadPixels();
pixels[width*100 + 100] = color(255,0,0);
updatePixels();
}
Processing can also draw a dot on the canvas using the `point()` command will also draw a dot on the canvas...
size(320, 240);
stroke(color(255,0,0));
point(100, 100);
...however, whether a point corresponds to a single pixel on the screen may depend on device-specific factors such as `pixelDensity()`, render features such as 2D / 3D mode or `smooth()`, or style settings such as `strokeWidth()` or `strokeCap()`.
PureBasic
If OpenWindow(0, 0, 0, 320, 240, "Rosetta Code Draw A Pixel in PureBasic")
If CreateImage(0, 320, 240) And StartDrawing(ImageOutput(0))
Plot(100, 100,RGB(255,0,0))
StopDrawing()
ImageGadget(0, 0, 0, 320, 240, ImageID(0))
EndIf
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Python
from PIL import Image
img = Image.new('RGB', (320, 240))
pixels = img.load()
pixels[100,100] = (255,0,0)
img.show()
QB64
Screen _NewImage(320, 240, 32)
PSet (100, 100), _RGB(255, 0, 0)
QBasic
' http://rosettacode.org/wiki/Draw_a_pixel
' This program can run in QBASIC, QuickBASIC, gw-BASIC (adding line numbers) and VB-DOS
SCREEN 1
COLOR , 0
PSET (100, 100), 2
END
Racket
#lang racket
(require racket/draw)
(let ((b (make-object bitmap% 320 240)))
(send b set-argb-pixels 100 100 1 1 (bytes 255 0 0 255))
b)
Raku
(formerly Perl 6)
Really? Draw a single pixel? Sigh.
use GTK::Simple;
use GTK::Simple::DrawingArea;
use Cairo;
my $app = GTK::Simple::App.new(:title('Draw a Pixel'));
my $da = GTK::Simple::DrawingArea.new;
gtk_simple_use_cairo;
$app.set-content( $da );
$app.border-width = 5;
$da.size-request(320,240);
sub rect-do( $d, $ctx ) {
given $ctx {
.rgb(1, 0, 0);
.rectangle(100, 100, 1, 1);
.fill;
}
}
my $ctx = $da.add-draw-handler( &rect-do );
$app.run;
ReScript
type document // abstract type for a document object
type context = { mutable fillStyle: string, }
@val external doc: document = "document"
@send external getElementById: (document, string) => Dom.element = "getElementById"
@send external getContext: (Dom.element, string) => context = "getContext"
@send external fillRect: (context, int, int, int, int) => unit = "fillRect"
let canvas = getElementById(doc, "my_canvas")
let ctx = getContext(canvas, "2d")
ctx.fillStyle = "#F00"
fillRect(ctx, 100, 100, 1, 1)
<!DOCTYPE html>
<html>
<head>
<title>Draw a Pixel</title>
<style rel="stylesheet" type="text/css">
body {
background-color:#777;
}
canvas {
background-color:#888;
margin:60px 120px;
border:1px solid #555;
box-shadow: -1px 2px 6px 1px rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<canvas id="my_canvas" width="320" height="240">
No support for HTML5 Canvas.<br />
</canvas>
<script type="text/javascript" src="draw.bs.js"></script>
<noscript>
No support for Javascript.<br />
</noscript>
</body>
</html>
REXX
This REXX version only works for:
- PC/REXX
- Personal/REXX
/*REXX program displays (draws) a pixel at a specified screen location in the color red.*/
parse upper version !ver .
!pcrexx= 'REXX/PERSONAL'==!ver | 'REXX/PC'==!ver /*obtain the REXX interpreter version. */
parse arg x y txt CC . /*obtain optional arguments from the CL*/
if x=='' | x=="," then x= 100 /*Not specified? Then use the default.*/
if y=='' | y=="," then y= 100 /* " " " " " " */
if CC=='' | CC="," then CC= 4 /* " " " " " " */
if txt=='' | txt="," then tzt= '·' /* " " " " " " */
if ¬!pcrexx then do; say; say "***error*** PC/REXX[interpreter] isn't being used."; say
exit 23
end
call scrWrite x,y,txt,,,CC /*stick a fork in it, we're all done. */
Ring
# Project : Draw a pixel
load "guilib.ring"
new qapp {
win1 = new qwidget() {
setwindowtitle("Drawing Pixels")
setgeometry(100,100,320,240)
label1 = new qlabel(win1) {
setgeometry(10,10,300,200)
settext("")
}
new qpushbutton(win1) {
setgeometry(200,200,100,30)
settext("draw")
setclickevent("draw()")
}
show()
}
exec()
}
func draw()
p1 = new qpicture()
color = new qcolor() {
setrgb(255,0,0,255)
}
pen = new qpen() {
setcolor(color)
setwidth(5)
}
new qpainter() {
begin(p1)
setpen(pen)
drawpoint(100,100)
endpaint()
}
label1 { setpicture(p1) show() }
Output image: Draw a pixel
Robotic
We can technically draw a pixel through the use of Sprites.
One of the requirements (fixed screen resolution) could not be met.
. "Set the sprite's reference character located at the"
. "upper-left corner of the board (char 0)"
set "SPR0_REFX" to 0
set "SPR0_REFY" to 0
. "Offset that reference by 256, leading to the first character"
. "in the extended character set"
set "SPR0_OFFSET" to 256
. "Set the width and height of the sprite"
set "SPR0_WIDTH" to 1
set "SPR0_HEIGHT" to 1
. "Unbound the sprite, removing the grid restriction"
set "SPR0_UNBOUND" to 1
. "Mark the sprite for display on the overlay (this may not be necessary)"
set "SPR0_OVERLAY" to 1
set "xPos" to 100
set "yPos" to 100
. "Display the sprite at the given location"
put c0c Sprite p00 at "('xPos')" "('yPos')"
I highly recommend you check out this tutorial for the usage of Sprites in order to get a better understanding of all this.
RPL
HP devices running RPL have only black-and-white LCD screens, so so much for the red color. Screen resolution goes from 137x32 to 131x80 depending on the model, but the user can freely define coordinates for the bottom-left pixel (minimum value) and for the top-right pixel (maximum value), so the program below works on any model:
≪ CLLCD (0,0) PMIN (320,240) PMAX (100,100) PIXEL ≫ EVAL
Ruby
require 'gtk3'
Width, Height = 320, 240
PosX, PosY = 100, 100
window = Gtk::Window.new
window.set_default_size(Width, Height)
window.title = 'Draw a pixel'
window.signal_connect(:draw) do |widget, context|
context.set_antialias(Cairo::Antialias::NONE)
# paint out bg with white
# context.set_source_rgb(1.0, 1.0, 1.0)
# context.paint(1.0)
# draw a rectangle
context.set_source_rgb(1.0, 0.0, 0.0)
context.fill do
context.rectangle(PosX, PosY, 1, 1)
end
end
window.signal_connect(:destroy) { Gtk.main_quit }
window.show
Gtk.main
Rust
- Output Image:
extern crate piston_window;
extern crate image;
use piston_window::*;
fn main() {
let (width, height) = (320, 240);
let mut window: PistonWindow =
WindowSettings::new("Red Pixel", [width, height])
.exit_on_esc(true).build().unwrap();
// Since we cant manipulate pixels directly, we need to manipulate the pixels on a canvas.
// Only issue is that sub-pixels exist (which is probably why the red pixel looks like a smear on the output image)
let mut canvas = image::ImageBuffer::new(width, height);
canvas.put_pixel(100, 100, image::Rgba([0xff, 0, 0, 0xff]));
// Transform into a texture so piston can use it.
let texture: G2dTexture = Texture::from_image(
&mut window.factory,
&canvas,
&TextureSettings::new()
).unwrap();
// The window event loop.
while let Some(event) = window.next() {
window.draw_2d(&event, |context, graphics| {
clear([1.0; 4], graphics);
image(&texture,
context.transform,
graphics);
});
}
}
Scala
Scala idiom
A more Scalesque version could be with the use of its idiom:
- Output:
Best experienced in your browser with Scastie (remote JVM).
import java.awt.image.BufferedImage
import java.awt.Color
import scala.language.reflectiveCalls
object RgbBitmap extends App {
class RgbBitmap(val dim: (Int, Int)) {
def width = dim._1
def height = dim._2
private val image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)
def apply(x: Int, y: Int) = new Color(image.getRGB(x, y))
def update(x: Int, y: Int, c: Color) = image.setRGB(x, y, c.getRGB)
def fill(c: Color) = {
val g = image.getGraphics
g.setColor(c)
g.fillRect(0, 0, width, height)
}
}
object RgbBitmap {
def apply(width: Int, height: Int) = new RgbBitmap(width, height)
}
/** Even Javanese style testing is still possible.
*/
private val img0 = new RgbBitmap(50, 60) { // Wrappers to enable adhoc Javanese style
def getPixel(x: Int, y: Int) = this(x, y)
def setPixel(x: Int, y: Int, c: Color) = this(x, y) = c
}
img0.fill(Color.CYAN)
img0.setPixel(5, 6, Color.BLUE)
// Testing in Java style
assert(img0.getPixel(0, 1) == Color.CYAN)
assert(img0.getPixel(5, 6) == Color.BLUE)
assert(img0.width == 50)
assert(img0.height == 60)
println("Tests successfully completed with no errors found.")
}
SmileBASIC
I almost said that the 320x240 requirement was not going to happen. Then I realised the 3DS bottom screen is exactly 320x240.
XSCREEN 3
DISPLAY 1
GPSET 100, 100, RGB(255, 0, 0)
WAIT 60
Standard ML
Works with PolyML
open XWindows ;
open Motif ;
val imgWindow = fn () =>
let
val shell = XtAppInitialise "" "demo" "top" [] [ XmNwidth 320, XmNheight 240 ] ;
val main = XmCreateMainWindow shell "main" [ XmNmappedWhenManaged true ] ;
val canvas = XmCreateDrawingArea main "drawarea" [ XmNwidth 320, XmNheight 240 ] ;
val usegc = DefaultGC (XtDisplay canvas) ;
val put = fn (w,s,t) => ( XSetForeground usegc 0xff0000 ;
XDrawPoint (XtWindow canvas) usegc ( XPoint {x=100,y=100} ) ; t);
in
(
XtSetCallbacks canvas [ (XmNexposeCallback , put) ] XmNarmCallback ;
XtManageChild canvas ;
XtManageChild main ;
XtRealizeWidget shell
)
end;
call
imgWindow () ;
Tcl
package require Tcl 8.5
package require Tk
pack [canvas .c -width 320 -height 240 -bg #fff] -anchor nw
.c create rectangle 100 100 100 100 -fill #f00 -outline ""
True BASIC
SET WINDOW 0, 320, 0, 240
SET COLOR 4
PLOT 100,100
END
Uiua
Run it using Uiua Pad to see the teeny-weeny dot.
↯240_320_3 0
⍜(⊡[100 100]|[1 0 0]◌)
Uxntal
( $ uxnasm draw-pixel.tal draw-pixel.rom && uxnemu draw-pixel.rom )
|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
|0100
( set theme )
#0f00 .System/r DEO2
#0000 .System/g DEO2
#0000 .System/b DEO2
( set screen size )
#0140 .Screen/width DEO2
#00f0 .Screen/height DEO2
( set position )
#0064 .Screen/x DEO2
#0064 .Screen/y DEO2
( draw pixel )
#01 .Screen/pixel DEO
BRK
VBA
Word
Sub draw()
Dim sh As Shape, sl As Shape
Set sh = ActiveDocument.Shapes.AddCanvas(100, 100, 320, 240)
Set sl = sh.CanvasItems.AddLine(100, 100, 101, 100)
sl.Line.ForeColor.RGB = RGB(Red:=255, Green:=0, Blue:=0)
End Sub
V (Vlang)
import gg
import gx
fn main() {
mut context := gg.new_context(
width: 320
height: 240
frame_fn: frame
)
context.run()
}
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_pixel(100, 100, gx.red)
ctx.end()
}
Wee Basic
Since the resolution of the Nintendo DS's bottom screen is only 256×192 (the same applies to the top screen), the window requirement is out, but the pixel is easy:
keyhide
plot 0 100,100,5
end
Wren
import "dome" for Window
import "graphics" for Canvas, Color
class Game {
static init() {
Window.title = "Draw a pixel"
Window.resize(320, 240)
Canvas.resize(320, 240)
var red = Color.rgb(255, 0, 0)
Canvas.pset(100, 100, red)
// check it worked
var col = Canvas.pget(100, 100)
System.print("The color of the pixel at (100, 100) is %(getRGB(col))")
}
static update() {}
static draw(dt) {}
static getRGB(col) { "{%(col.r), %(col.g), %(col.b)}" }
}
- Output:
$ ./dome draw_pixel.wren The color of the pixel at (100, 100) is {255, 0, 0}
X86 Assembly
This doesn't quite meet the requirements, but it shows how little code is needed to draw a pixel on an IBM-PC VGA screen. The executable program is a mere 32 bytes long. The "window" in this case is 320x200. Palette register 28 hex is set to bright red by the BIOS at boot-up time. About half the code is used to wait for a keystroke before returning to the OS, so the pixel can be seen. Borland's tasm and tlink /t were used to create an executable .com file.
.model tiny
.code
org 100h
start: mov ax, 0013h ;set 320x200x8 graphic screen
int 10h
push 0A000h ;point to graphic memory segment
pop es
mov byte ptr es:[320*100+100], 28h ;draw bright red pixel
mov ah, 0 ;wait for keystroke
int 16h
mov ax, 0003h ;restore normal text mode screen
int 10h
ret ;return to OS
end start
XPL0
This is all that's required to plot a pixel on the Raspberry Pi version of XPL0. It can do tens of millions of them per second. (FB = Frame Buffer.)
[SetFB(320, 240, 24); Point(100, 100, $FF0000)]
Yabasic
open window 320, 240
color 255, 0, 0
dot 100, 100
ZX Spectrum Basic
The ZX Spectrum screen is only 256x224 (unless you're running one of the games like Starion or Dark Star which used scary machine code timing tricks to draw on the border), meaning the window requirement is out, but the pixel is easy:
PLOT INK 2;100,100
- Programming Tasks
- GUI
- Basic language learning
- Simple
- Action!
- Ada
- SDLAda
- ARM Assembly
- AutoHotkey
- BASIC
- Applesoft BASIC
- BASIC256
- BBC BASIC
- Commodore BASIC
- ProgressBASIC
- IS-BASIC
- SmallBASIC
- C
- Delphi
- Windows
- Messages
- SysUtils
- EasyLang
- F Sharp
- Factor
- Evaldraw
- Forth
- SDL2
- FreeBASIC
- Frink
- FutureBasic
- GB BASIC
- GML
- Go
- Icon
- Unicon
- J
- Java
- Julia
- Kotlin
- Lambdatalk
- Lua
- M2000 Interpreter
- Mathematica
- Wolfram Language
- Maxima
- Pages with broken file links
- Microsoft Small Basic
- MiniScript
- Nim
- Rapid
- Oberon
- Objeck
- OCaml
- OCamlSDL2
- Odin
- Ol
- OpenGL
- PascalABC.NET
- Perl
- Gtk3
- Phix
- Phix/pGUI
- Phix/online
- Plain English
- Processing
- PureBasic
- Python
- PIL
- QB64
- QBasic
- Racket
- Raku
- ReScript
- REXX
- Ring
- Robotic
- RPL
- Ruby
- Rust
- Piston window
- Image
- Scala
- SmileBASIC
- Standard ML
- Tcl
- Tk
- True BASIC
- Uiua
- Uxntal
- VBA
- V (Vlang)
- Wee Basic
- Wren
- DOME
- X86 Assembly
- XPL0
- Yabasic
- ZX Spectrum Basic