These changes are about the current source code. These are effected once new binary release is published
Fixed: Concanationing did not work with arrays
a$+= 5 ' worked
arr$(1) += 5 ' did not work
' but works now with ver. 1.3bAdded: several more example codes. Rosett-code solutions counter now a bit over 130.
Added: MOUSEHIDE and MOUSESHOW statemetens
MOUSEHIDE hides mouse cursor on graphics screen
MOUSESHOW brings it back.
Both works only when graphical screen is initialized (SCREEN 'mode')
Added: INBETWEEN. Returns true, if n is between min and max and not equal to them
INBETWEEN(1, 1, 10) ' false
INBETWEEN(2, 1, 10) ' true
BETWEEN(1, 1, 10) ' true
BETWEEN(2, 1, 10) ' trueUnlike BETWEEN which returns true if n is equal or between min and max, INBETWEEN returns true if n is not equal and between min and max
Added: ATAN2().
PRINT ATAN2(x$, y$) ' 0.4636476090008061Fixed: LOADSHEET — sprite indexing now starts at 0
Sprites loaded from a sheet are now indexed from 0, consistent with all other arrays in BazzBasic. Previously the first sprite was at index 1.
Fixed: VSYNC — keyboard input no longer breaks after toggling VSync at runtime
VSYNC(TRUE/FALSE) now uses SDL_RenderSetVSync to switch vertical sync without destroying the renderer. Previously the renderer was recreated on each call, causing the window to briefly lose focus and SDL to reset the keyboard state — making KEYDOWN and INKEY unresponsive until the next keypress.
Version 1.3 released as binary
Added: DRAWSTRING and LOADFONT — text rendering in graphics mode
Renders text directly to the SDL2 graphics surface. Requires SDL2_ttf.dll in the same directory as the interpreter. Prefer over PRINT in graphics mode — PRINT bypasses the SDL2 rendering pipeline and causes flickering.
' Default font (Arial, size 20)
DRAWSTRING "Hello!", 100, 200, RGB(255, 255, 255)
' Load alternative font — becomes the new active font
LOADFONT "myfont.ttf", 24
DRAWSTRING "Hello!", 100, 200, RGB(255, 255, 255)
' Reset to default (Arial, size 20)
LOADFONTDRAWSTRING positions text by its top-left corner. Copy .ttf files next to your .bas for portability — Windows system fonts can be referenced by full path but are not recommended for distribution.
Added: ROWCOUNT — count array rows
Returns the number of distinct first-dimension keys in an array.
PRINT ROWCOUNT(myArray$)Added: ARGCOUNT and ARGS() — command-line arguments
Access command-line arguments passed to the program.
PRINT ARGCOUNT ' Number of arguments
PRINT ARGS(0) ' First argumentAdded: compound assignment operators
Shorthand for common arithmetic assignments. Works on variables ($), not constants (#).
x$ += 5 ' x$ = x$ + 5
x$ -= 2 ' x$ = x$ - 2
x$ *= 3 ' x$ = x$ * 3
x$ /= 4 ' x$ = x$ / 4
str$ += " world" ' String concatenationChanged: INSTR() — case-sensitivity parameter
INSTR now accepts an optional case-sensitivity flag.
PRINT INSTR("Hello World", "world") ' 0 (case-sensitive, not found)
PRINT INSTR("Hello World", "world", 0) ' 7 (case-insensitive)Changed: math constants now use # suffix
PI, HPI, QPI, and TAU are now PI#, HPI#, QPI#, TAU# for consistency with the rest of the language.
Changed: IDE and CLI improvements
| Menu | Shortcut | Action | CLI option |
|---|---|---|---|
| File | Ctrl+N | New file | BazzBasic.exe |
| File | Ctrl+O | Open file | none |
| File | Ctrl+S | Save file | none |
| File | Ctrl+Shift+S | Save As | none |
| File | Ctrl+W | Close tab | none |
| File | Alt+F4 | Exit | none |
| Edit | Ctrl+F | Find | none |
| Edit | Ctrl+H | Replace | none |
| Run | F5 | Run Program | BazzBasic.exe file.bas |
| Run | — | Compile as Exe | BazzBasic.exe -exe file.bas |
| Run | — | Compile as Library (.bb) | BazzBasic.exe -lib file.bas |
| Help | — | About | BazzBasic.exe -v |
| Help | — | Beginner's Guide | BazzBasic.exe -guide |
| Help | — | Check For Updates | BazzBasic.exe -checkupdates |
New files now open with a starter template:
' BazzBasic version 1.3
' https://ekbass.github.io/BazzBasic/Bugfix: early RETURN inside FOR loop left function scope dirty
If a function returned early (e.g. via RETURN inside a FOR loop), local variables were not cleared. This caused stale values on subsequent calls to the same function. Now fixed.
Released as version 1.2 with some bug fixes and new features.
A Beginners Guide to BazzBasic is now available. It covers all the basics of programming in BazzBasic with what beginner can star at.
https://github.com/EkBass/BazzBasic-Beginners-Guide/blob/main/BazzBasic_Beginners_Guide.md
Added: BBVER# — version constant
Returns the running BazzBasic version as a string. Value is read directly from Version.cs at startup.
PRINT "Running BazzBasic "; BBVER# ' Output: Running BazzBasic 1.1dAdded: JOIN — merge two arrays
Merges src1$ and src2$ into dest$. If both source arrays share a key, src2$ overwrites src1$.
JOIN dest$, src1$, src2$Added: CURPOS("row"/"col") — read cursor position
Returns the current cursor row or column (1-based). Useful after PRINT or LOCATE.
LOCATE 5, 10
PRINT "Hello"
PRINT CURPOS("row") ' Output: 5
PRINT CURPOS("col") ' Output: 15Renamed: ROOT# → PRG_ROOT#
The built-in system constant holding the program's base directory path has been renamed to PRG_ROOT# for clarity.
ROOT#.
Bugfix: SCREEN reinitialization
Calling SCREEN more than once no longer causes a crash or corrupted graphics state. Reinitializing the window mid-program now works correctly.
I spent a couple of hours editing the already somewhat confusing documentation.
I think the new structure and division is clearer now and it's easier to find what you need.
Ek
Due MOUSE issue below is pretty major, BazzBasic 1.1d released as source and binary
Bugfix: Mouse button detection rewrite
MOUSEB AND MOUSE_LEFT# did not work correctly because AND in BazzBasic is logical, not bitwise — any non-zero value is TRUE, so all three buttons appeared pressed simultaneously.
Removed:
MOUSE_LEFT#,MOUSE_RIGHT#,MOUSE_MIDDLE#built-in constantsMOUSEBkeyword (token kept internally for binary compatibility)
Added:
MOUSELEFT— returns 1 if left mouse button is pressed, 0 otherwiseMOUSERIGHT— returns 1 if right mouse button is pressed, 0 otherwiseMOUSEMIDDLE— returns 1 if middle mouse button is pressed, 0 otherwise
WHILE INKEY <> KEY_ESC#
LOCATE 1, 1
PRINT "X:"; MOUSEX; " Y:"; MOUSEY; " "
IF MOUSELEFT THEN PRINT "Left clicked "
IF MOUSERIGHT THEN PRINT "Right clicked "
IF MOUSEMIDDLE THEN PRINT "Middle clicked"
SLEEP 10
WENDQuick "rerelease" as 1.1b
- I forgot to update version from source
- I forgot to update syntax files for Notepad++, VS Code, Geany and built-in IDE
- Headers "support" not documented
HTTPGET(url$) ' works as before
HTTPGET(url$, headers$) ' new, optional
HTTPPOST(url$, body$) ' works as before
HTTPPOST(url$, body$, headers$) ' new, optionalSee OpenAI API example for more.
Released as version 1.1
At Rosetta code I got inspired to create pendulum animation. pendulum_animation.bas
BazzBasic-AI_guide.md is a tutorial for modern AI's. With it, AI can easily teach the user how to use BazzBasic.
Just download the file, attach it as project file or via prompt to AI and you are cool to go.
Unfortunately, the GamePad support I planned didn't make it to version 1.1
The reason is that the SDL2 library has been having problems for some time, especially with Bluetooth gamepads.
I didn't want to do something half-hearted, so the gamepad support is now on hold until SDL2 gets its library back in condition.
Instead, I added three other functions that I've had in mind for some time: BASE64ENCODE, BASE64DECODE and SHA256
Added JSON support: ASJSON, ASARRAY, LOADJSON, SAVEJSON
DIM data$
data$("name") = "Alice"
data$("score") = 9999
data$("address,city") = "New York"
LET json$ = ASJSON(data$)
' Output: {"name":"Alice","score":9999,"address":{"city":"New York"}}
DIM back$
LET count$ = ASARRAY(back$, json$)
PRINT back$("name") ' Alice
PRINT back$("address,city") ' New York
SAVEJSON data$, "save.json"
DIM loaded$
LOADJSON loaded$, "save.json"Added BASE64ENCODE, BASE64DECODE and SHA256
LET encoded$ = BASE64ENCODE("Hello, World!")
PRINT encoded$ ' SGVsbG8sIFdvcmxkIQ==
LET decoded$ = BASE64DECODE(encoded$)
PRINT decoded$ ' Hello, World!
LET hash$ = SHA256("password123")
PRINT hash$ ' ef92b778... (64-char lowercase hex)Problem: The old implementation loaded MP3/OGG/FLAC files with Mix_LoadMUS() which uses the SDL2_mixer's global Music channel — only one sound at a time.
Fixes:
- All sounds are now loaded with
Mix_LoadWAV()→ play on their own Mix_Channels in parallel SDL_INIT_AUDIOadded toSDL_Init()call inGraphics.csSoundManagercallsSDL_Init+SDL_InitSubSystemto ensure audio subsystem even withoutSCREENcommandSDL_AUDIODRIVER=directsoundset inProgram.csto work around WASAPI issues (Nahimic middleware causes "Invalid Handle" error in WASAPI)PlayOnceWaitgets 50ms delay before polling loop due to DirectSound startup delay
Added HTTP support for LOADIMAGE
LET sprite$ = LOADIMAGE("https://example.com/sprite.png")
' → downloads "sprite.png" to root of your program
' → sprite$ works just as with normal file load
' to remove or move the downloaded file
SHELL("move sprite.png images\sprite.png") ' move to subfolder
' or
FileDelete "sprite.png" ' just delete itAdded WAITKEY() function.
Halts the execution until requested key is pressed.
' Wait just the ENTER key
PRINT "ENTER"
PRINT WAITKEY(KEY_ENTER#) ' output: 13
' Wait any of "a", "b" or "esc" keys
PRINT "A, B or ESC"
PRINT WAITKEY(KEY_A#, KEY_B#, KEY_ESC#) ' output: depends of your choice of key
PRINT "Press any key..."
LET a$ = WAITKEY()
PRINT a$ ' output: val of key you pressedAdded SHELL feature
' SHELL arg$, timeout$
' Sends a command to the system command interpreter
' Param *timeout$* is optional. If not given, standard 5000 milliseconds used for timeout.
' with default timeout option
LET a$ = SHELL("dir *.txt")
PRINT a$
' sets timeout to 2 seconds
' 1000ms = 1 second etc.
LET a$ = SHELL("dir *.txt", 2000)
PRINT a$- Released as version 1.0, source and binary
- FILEREAD and FILEWRITE now supports arrays too.
- Example with array:
LET FILENAME# = "array.txt"
DIM a$
a$("first") = 1
a$("second") = 2
a$("third") = 3
a$("fourth") = "Four"
a$("fourth", "temp") = "Temp"
FileWrite FILENAME#, a$
DIM b$ = FileRead(FILENAME#)
PRINT b$("fourth", "temp") ' Output: Temparray.txt content:
first=1
second=2
third=3
fourth=Four
fourth,temp=Temp
- Added statements HTTPPOST and HTTPGET. These statements allow you to send HTTP POST and GET requests to a specified URL and retrieve the response as a string.
DIM response$
LET response$ = HTTPGET("https://httpbin.org/get")
PRINT response$
DIM postResult$
LET postResult$ = HTTPPOST("https://httpbin.org/post", "{""key"":""value""}")
PRINT postResult$- Added statement LOADSHEET(, , )
REM ============================================
REM LOADSHEET demo: countdown 9 -> 0
REM sheet_numbers.png: 640x256, 128x128 sprites
REM Sprite 1=0, 2=1, 3=2 ... 10=9
REM ============================================
SCREEN 640, 480, "Countdown!"
DIM sprites$
LOADSHEET sprites$, 128, 128, "examples/sheet_numbers.png"
REM Center position for a 128x128 sprite on 640x480 screen
LET x# = 256
LET y# = 176
REM Count down from 9 to 0
REM Sprite index = number + 1 (sprite 10 = digit 9, sprite 1 = digit 0)
FOR i$ = 9 TO 0 STEP -1
CLS
LET spriteIndex$
LET spriteIndex$ = i$ + 1
MOVESHAPE sprites$(spriteIndex$), x#, y#
DRAWSHAPE sprites$(spriteIndex$)
SLEEP 500
NEXT
END-
- Added FULLSCREEN TRUE/FALSE. Enables or disables borderless fullscreen mode.
SCREEN 640, 480, "My title"
FULLSCREEN TRUE ' borderless fullscreen on
FULLSCREEN FALSE ' Windowed mode- Fixed INPUT and LINE INPUT when using GFX. Binary release also updated
- Added KEYDOWN(<key constant#>) function with what it's possible to check state of all key constants
- Added key constants to all keys I could imagine. Will add more if figured out some is missing
- Released as version 0.9
- Added LERP(start, end, t). Linear interpolation between two values. Returns a value between start and end based on parameter t (0.0 to 1.0).
- Added EULER, which returns raw coded value of e (EULER) 2.718281828459045
- Added VSYNC(TRUE/FALSE). VSync limits frame rate to display refresh rate (typically 60 FPS) but prevents screen tearing. Disabling VSync allows unlimited frame rate but may cause visual artifacts.
- Added DISTANCE(x1, y1, x2, y2) or DISTANCE(x1, y1, z1, x2, y2, z2) which returns distance of 2D or 3D coordinates
- Added CLAMP(n, min, max). If the given parameter n falls below or exceeds the given limit values min or max, it is returned within the limits
LET brightness$ = CLAMP(value$, 20, 255)
' Replaces lines
' IF brightness$ < 20 THEN brightness$ = 20
' IF brightness$ > 255 THEN brightness$ = 255- Added TAU, which returns raw coded value of PI * 2
- Added QPI, which returns raw coded value of PI / 4
- Added BETWEEN(value, min, max) which returns TRUE if value is between min and max.
Version 0.8 released as binary
- Succesfully changed audio from NAudio to SDL2_mixer.
For graphics-intensive applications (games, raycasting, animations), BazzBasic provides fast trigonometric functions using pre-calculated lookup tables. These are significantly faster than standard SIN/COS functions but have 1-degree precision.
Performance: ~20x faster than SIN(RAD(x)) for integer degree values.
Memory: Uses ~5.6 KB when enabled (360 values 2 tables 8 bytes).
Enables or disables fast trigonometry lookup tables.
Parameters:
TRUE(or any non-zero value) - Creates lookup tablesFALSE(or 0) - Destroys lookup tables and frees memory
Important: Must call FastTrig(TRUE) before using FastSin, FastCos, or FastRad.
' Enable at program start
FastTrig(TRUE)
' Use fast trig functions...
LET x$ = FastCos(45)
LET y$ = FastSin(45)
' Disable at program end to free memory
FastTrig(FALSE)Returns the sine of an angle (in degrees) using a lookup table.
Parameters:
angle- Angle in degrees (automatically normalized to 0-359)
Returns: Sine value (-1.0 to 1.0)
Precision: 1 degree (sufficient for most games and graphics)
FastTrig(TRUE)
PRINT FastSin(0) ' Output: 0
PRINT FastSin(90) ' Output: 1
PRINT FastSin(180) ' Output: 0
PRINT FastSin(270) ' Output: -1
' Angles are automatically wrapped
PRINT FastSin(450) ' Same as FastSin(90) = 1
PRINT FastSin(-90) ' Same as FastSin(270) = -1
FastTrig(FALSE)Returns the cosine of an angle (in degrees) using a lookup table.
Parameters:
angle- Angle in degrees (automatically normalized to 0-359)
Returns: Cosine value (-1.0 to 1.0)
Precision: 1 degree (sufficient for most games and graphics)
FastTrig(TRUE)
PRINT FastCos(0) ' Output: 1
PRINT FastCos(90) ' Output: 0
PRINT FastCos(180) ' Output: -1
PRINT FastCos(270) ' Output: 0
' Use in raycasting
FOR angle$ = 0 TO 359
LET dx$ = FastCos(angle$)
LET dy$ = FastSin(angle$)
' Cast ray in direction (dx, dy)
NEXT
FastTrig(FALSE)Converts degrees to radians using an optimized formula.
Parameters:
angle- Angle in degrees (automatically normalized to 0-359)
Returns: Angle in radians
Note: This function doesn't require FastTrig(TRUE) but is included for consistency.
PRINT FastRad(90) ' Output: 1.5707963267948966 (HPI)
PRINT FastRad(180) ' Output: 3.141592653589793 (PI)
PRINT FastRad(360) ' Output: 6.283185307179586 (2*PI)REM Fast raycasting demo
SCREEN 12
' Enable fast trigonometry
FastTrig(TRUE)
LET player_angle$ = 0
LET num_rays# = 320
[mainloop]
' Update player rotation
LET player_angle$ = player_angle$ + 1
IF player_angle$ >= 360 THEN player_angle$ = 0
' Cast all rays
FOR ray$ = 0 TO num_rays# - 1
LET ray_angle$ = player_angle$ + ray$
' Fast lookup instead of SIN(RAD(angle))
LET dx$ = FastCos(ray_angle$)
LET dy$ = FastSin(ray_angle$)
' Raycast logic here...
' (20x faster than using SIN/COS!)
NEXT
IF INKEY = KEY_ESC# THEN GOTO [cleanup]
GOTO [mainloop]
[cleanup]
' Free memory
FastTrig(FALSE)
ENDUse FastTrig when:
- Rendering graphics at high frame rates (60+ FPS)
- Raycasting or ray tracing
- Rotating sprites or shapes
- Particle systems with many particles
- Any loop that calls
SIN/COShundreds of times per frame
Use regular SIN/COS when:
- Math calculations requiring high precision
- One-time calculations
- Angles are not in integer degrees
- Memory is extremely limited
- Added keyword HPI which returns raw coded 1,5707963267929895
- Added keyword PI which returns 3.14159265358979
- Added keywords RAD & DEG
PI and HPI are raw coded values, so no math involved. Should make performance much better.
REM Test RAD and DEG functions
PRINT "Testing RAD() and DEG() functions"
PRINT
REM Test degrees to radians
PRINT "90 degrees = "; RAD(90); " radians"
PRINT "180 degrees = "; RAD(180); " radians"
PRINT "360 degrees = "; RAD(360); " radians"
PRINT
REM Test radians to degrees
PRINT "PI radians = "; DEG(PI); " degrees"
PRINT "PI/2 radians = "; DEG(PI/2); " degrees"
PRINT
REM Test with trigonometry
PRINT "SIN(RAD(90)) = "; SIN(RAD(90))
PRINT "COS(RAD(180)) = "; COS(RAD(180))
PRINT
ENDTesting RAD() and DEG() functions
90 degrees = 1.5707963267948966 radians
180 degrees = 3.141592653589793 radians
360 degrees = 6.283185307179586 radians
PI radians = 179.99999999999983 degrees
PI/2 radians = 89.99999999999991 degrees
SIN(RAD(90)) = 1
COS(RAD(180)) = -1The documentation has been worked on and is now a bit better than good.
BazzBasic supports creating libraries: bazzbasic.exe -lib file.bas
LINE INPUT is now in the list of supported commands
Version 0.7 released to this date
With all the previous add-ons, BazzBasic ver. 0.6 is now available as binary and source.
Merging BazzBasic and basic code into a single executable file is now possible.
bazzbasic.exe -exe filename.bas produces the filename.exe file.
BazzBasic does not compile the BASIC code, but rather includes it as part of itself.
Read more https://ekbass.github.io/BazzBasic/manual/#/packaging
Finished working with PNG and Alpha-color supports.
LOCATE in graphical screen now overdraws old text instead of just writing new top of it.
Supported Formats
Format: PNG
Transparency: Full alpha (0-255)
Recomended
Format: BMP
Transparency: None
Legacy support
Generated a manual with Docify.
BazzBasic homepage now links to it.
Major idea is, that github wiki becomes a as development wiki and this docify as user wiki.
Fixed a bug that prevented to use custom resolution with SCREEN 0
Terminal now closes if no errors when running via IDE
Small gap between IDE line numbers and user code.
BazzBasic has now in-built simple IDE.
Start bazzbasic.exe with out params to open it.
If opened with params, the .bas file is interpreted normally.
After few new features, released as version 0.6
Generated vsix file to add BazzBasic syntaxes for VS Code.
See https://github.com/EkBass/BazzBasic/blob/main/extras/readme.md
Released first one, version 0.5