-
Notifications
You must be signed in to change notification settings - Fork 5
Graphics and Multimedia
← Language Reference | Next: Command Reference
All graphics functions are available in the full build (Windows GDI or Linux/X11). They are absent in the tiny build, which targets minimal environments.
The coordinate system has its origin at the top-left corner of the working window client area, with X increasing to the right and Y increasing downward. All coordinates are in pixels.
Colors are packed RGB integers in GDI byte order (BGR stored in the low three bytes), so the
layout is &hBBGGRR:
| Color | nuBASIC constant |
|---|---|
| Red | &h0000FF |
| Green | &h00FF00 |
| Blue | &hFF0000 |
| Yellow | &h00FFFF |
| Cyan | &hFFFF00 |
| Magenta | &hFF00FF |
| White | &hFFFFFF |
| Black | &h000000 |
The Rgb(r, g, b) function computes a color from separate 0–255 components:
skyBlue% = Rgb(135, 206, 235)
sunYellow% = Rgb(255, 220, 50)Line x1, y1, x2, y2, color% ' straight line
Rect x1, y1, x2, y2, color% ' rectangle outline
FillRect x1, y1, x2, y2, color% ' filled rectangle
Ellipse x1, y1, x2, y2, color% ' ellipse outline (bounding box)
FillEllipse x1, y1, x2, y2, color% ' filled ellipseSetPixel x%, y%, color% ' write a pixel
c% = GetPixel(x%, y%) ' read a pixel's colorTextOut draws a text string at a pixel coordinate. Unlike Print, it does not move the
text cursor or scroll the buffer.
TextOut x%, y%, text$, color%
TextOut 10, 10, "Score: " + Str$(score%), &hFFFFFF
TextOut 200, 240, "GAME OVER", Rgb(255, 50, 50)PlotImage loads a BMP file and draws it at a pixel coordinate (native size, no scaling):
PlotImage "background.bmp", 0, 0
PlotImage "sprite.bmp", hero_x%, hero_y%Cls
MoveWindow GetWindowX(), GetWindowY(), 640, 480
FillRect 0, 0, 640, 480, Rgb(30, 30, 60) ' dark night sky
FillEllipse 520, 20, 600, 100, Rgb(255, 255, 200) ' moon
FillRect 0, 360, 640, 480, Rgb(0, 80, 0) ' green ground
For i% = 0 To 5
cx% = 80 + i% * 100
FillEllipse cx%, 200, cx%+60, 360, Rgb(20, 120, 20) ' trees
FillRect cx%+25, 330, cx%+35, 365, Rgb(80, 50, 20) ' trunks
Next i%
TextOut 10, 10, "nuBASIC Graphics Demo", &hFFFFFFThe Screen statement switches the console/graphics mode at runtime,
similar to GW-BASIC's SCREEN command.
| Mode | Instruction | Behaviour |
|---|---|---|
| 0 | Screen 0 |
Text / hybrid mode — text I/O via the real Windows console (stdout/stdin); all GDI drawing commands are silent no-ops. No GDI window is required. Ideal for scripts, CI pipelines and regression tests. |
| 1 | Screen 1 |
GDI console mode (default) — text I/O and graphics go through the custom GDI window, as in previous nuBASIC versions. |
The CLI flag -t / --text-mode pre-sets Screen 0 before the
interpreter starts, so programs that never call Screen 1 can run
fully headless:
nubasic.exe -t -e tests/test_math.bas
Example — switching modes at runtime:
Screen 0 ' text mode: Print/Input use the real console
Print "Hello from text mode"
Screen 1 ' back to GDI: drawing commands are active again
Line 0, 0, 200, 200, RGB(255, 0, 0)Tip for test files: add
Screen 0as the very first statement so the test runner can capture
When multiple drawing commands execute in sequence, each one immediately blits to the screen. The user sees each intermediate state — a cleared frame, a partial board, and so on — as visible flicker.
| Instruction | Effect |
|---|---|
ScreenLock |
Suspend automatic screen refresh; all drawing goes to the back buffer |
ScreenUnlock |
Present the back buffer to the screen in one blit; resume automatic refresh |
Refresh |
Force an immediate blit; lock state is unchanged |
While Not(game_over%)
ScreenLock
FillRect 0, 0, 640, 480, &h000000 ' clear previous frame
DrawBoard
DrawPlayer player_x%, player_y%
DrawEnemies
DrawHUD score%, lives%
ScreenUnlock
MDelay 16 ' pace to ~60 fps
WendFor x0 = -2 To 2 Step 0.013
ScreenLock
For y0 = -1.5 To 1.5 Step 0.013
' ... compute c ...
FillRect x0*d%+dx%, y0*d%+dy%, x0*d%+dx%+2, y0*d%+dy%+2, c%*16
Next y0
ScreenUnlock ' one column appears per iteration
Next x0x_old% = x% : y_old% = y%
x% = x% + dx% : y% = y% + dy%
ScreenLock
FillEllipse x_old%*10, y_old%*10, x_old%*10+10, y_old%*10+10, 0 ' erase old
FillEllipse x%*10, y%*10, x%*10+10, y%*10+10, &hffffff ' draw new
ScreenUnlockScreenLock
FillRect 150, 220, 490, 310, &hffff00
Rect 150, 220, 490, 310, &h000000
TextOut 180, 245, "Game over! Play again? (Y/N)", &h000000
ScreenUnlock
Refresh ' ensure dialog is visible before blocking
key$ = Input$(1)Mouse input is polled — there is no event queue.
btn% = GetMouseBtn() ' 0=none, 1=left, 2=middle, 4=right
x% = GetMouseX() ' cursor X in pixels from left edge
y% = GetMouseY() ' cursor Y in pixels from top edgebx1% = 40 : by1% = 60
bx2% = 200 : by2% = 100
FillRect bx1%, by1%, bx2%, by2%, &hffff00
TextOut bx1%+20, by1%+15, "Click me", &h000000
While 1
btn% = GetMouseBtn()
mx% = GetMouseX()
my% = GetMouseY()
If btn% = 1 And mx% >= bx1% And mx% <= bx2% And my% >= by1% And my% <= by2% Then
Print "Button clicked!"
MDelay 200
End If
MDelay 16
WendCls
FillRect 0, 0, 640, 480, &h000000
While 1
key$ = InKey$()
If key$ = "q" Or key$ = "Q" Then Exit While
If GetMouseBtn() = 1 Then
SetPixel GetMouseX(), GetMouseY(), &hffffff
End If
MDelay 5
WendMoveWindow GetWindowX(), GetWindowY(), 800, 600
Print "Position: "; GetWindowX(); ", "; GetWindowY()
Print "Size: "; GetWindowDx(); " x "; GetWindowDy()
Print "Canvas: "; GetSWidth(); " x "; GetSHeight()
SetTopMost() ' keep window above all othersTypical startup sequence:
Cls
MoveWindow 100, 100, 640, 480
FillRect 0, 0, 640, 480, &h000000PlaySound "background.wav", 1 ' async: returns immediately
PlaySound "explosion.wav", 0 ' sync: waits for completion
Beep ' system beepresult% = MsgBox("nuBASIC Demo", "Setup complete. Ready to play?")
If result% > 0 Then
Print "User confirmed."
End If← Language Reference | Next: Command Reference