befunge-with-graphics
- This language is a derivative of Befunge.
As its name suggests, befunge-with-graphics is befunge-93 but with graphics. Its name can be shortened to bwg and will be for the rest of this article. It adds two more regular commands, however, which help with the graphics programming.
Changes and additions to befunge, excluding graphics
On top of the befunge instruction set, bwg adds two extra commands;:
Command | Function |
---|---|
j | Jump command - pops y then x off the stack, pushes the current instruction pointer and direction to the return stack and sets the ip to x,y and the direction to right. |
r | Return command - pops the x, y and direction off of the return stack and sets the instruction pointer to those values. |
On top of this, bwg extends the playfield almost indefinitely. Although not mentioned on the befunge wiki page, bwg makes it clear that every cell in the playfield and the stack can hold 64 bit signed integers.
Graphics implementation
The reference interpreter uses SDL2 to render graphics and as such the graphics commands are similar to that of SDL.
Graphics command | Function |
---|---|
s | Pops y then x off of the stack and uses them as dimensions to create a screen. This must be run before any other graphics command, otherwise they will be ignored. |
f | Pops three values, b, g, then r, and sets the render colour to those values. This is used for clearing the screen and drawing. |
x | Pops y then x off the stack and sets the pixel at those coords to the current colour. |
c | Fills screen with current colour. |
u | Updates the screen after it's been drawn |
l | Pops y2, x2, y1, x1 off of the stack and draws a line from x1y1 to x2y2. |
z | Polls SDL for an event, if one is present then push it to the stack along with any data accompanying the event. See the events section. |
Future features and bug fixes
Virtual Jumps
The main reason jumps were added is so that "virtual jumps" can be used. These are jumps where the x, the y, or both are negative. These will be processed by the interpreter into graphics commands, such as drawing circles, rects, and other higher level things like that. They may support other operations in the future, depending on how I implement this.
Virtual jump coordinates (x, y) | Operation |
---|---|
(-1, 0) | Pop y, then x, then radius, and draw a circle outline at (x, y) with the specified radius. |
(-1, 1) | Pop y, then x, then radius, and draw a filled circle at (x, y) with the specified radius. (unimplemented) |
(-2, 0) | Pop y, then x, then width, then height; and draw a rectangle outline with those parameters. (unimplemented) |
(-2, 1) | Pop y, then x, then width, then height; and draw a filled rectangle with those parameters. (unimplemented) |
Misc
Because I'm bad at coding in C++, the reference interpreter is bad. Please help by submitting an issue or a pull request.
Event handling
The event handling is rather simple but can be quirky. The z command polls SDL for an event and pushes any relevant data to the stack. An example event handler is shown here.
>z:1-!#@_>:2-!#v_> > >v >$"c"-#^_"c key pressed"^ ^ <
This works by first polling for events, then duplicating the event ID (below) which will always be at the top of the stack. The event ID is then compared to the first kind of event (ID 1, Window close event) and if it matches it exits. If not, it duplicates and compares again, taking into account any data that might be pushed and making sure to pop it to avoid contaminating the stack.
The events are currently as follows.
Event | What is pushed to the stack |
---|---|
No event | 0 |
Window close event | 1 |
Key down event | Key code, 2 |
Key up event | Key code, 3 |
Example programs
Hello Graphics
A basic program that opens a window and closes it if you so wish.
68*52**88*52**sv vcf000< < < >uz:1-!#@_>^
Example with drawing and keyboard input
This code moves one pixel around using the wasd keys.
vXY >010p020p052*j "jump to initialisation" "draw()" >10g20gxr "keyboard events" >v >v >v >v >: "d" -|>: "s" -|>: "a" -|>: "w" -|>r v1+1g01$<vp02+1g02$<vp01-1g01$<vp02-1g02$< >0p > > > ^ "initialisation" >68*52**88*52**sv v ucf000< v f::-1*4*88 cf000 < >03jv v < >v >v >u >z:1-|>:2-|> ^ @$< v$< vj60< > ^