PixelProtocol 3 is a simple binary protocol for defining what is being sent between a GUI client and a game engine.
It's for implementing games where old-school looking pixel art can be appreciated.
- 256 indexed colors.
- A resolution of 320x200 pixels is recommended.
- Should be possible to implement both in 16-bit assembly for DOS and in a modern browser.
- Aiming to be WebSocket-friendly.
- Pixels are not sent over the network, only commands for drawing them.
- It should be possible to create a DosBox server for serving games over this protocol.
- It should be possible to create a mobile client for playing games over this protocol.
- The music is extremely simple 4-track MIDI.
Name | Type | Description |
---|---|---|
ver |
uint16 |
protocol version |
width |
uint16 |
width |
height |
uint16 |
height |
commands |
[]uint16 |
list of commands (uint8 cmd + uint8 argument) |
The commands can be streamed.
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x00 |
palsel |
color index, 0..255 | choose palette color, prepare for filling the palette |
0x01 |
setred |
red value, 0..255 | set red value of chosen palette color |
0x02 |
setgreen |
set green value of chosen palette color | set blue value of chosen palette color |
0x03 |
setblue |
set blue value of chosen palette color | set green value of chosen palette color |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x04 |
setcol |
pixel color from palette, 0..255 | set the active color |
Cmd | Name | uint16 argument | Description |
---|---|---|---|
0x05 |
setx |
x position, 0..65535 | set active x position |
0x06 |
sety |
y position, 0..65535 | set active y position |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x07 |
plot |
n pixels | plot one or more pixels from (x,y) |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x08 |
clear |
fill color from palette, 0..255 | clear everything with the selected color |
0x09 |
rfill |
fill color from palette, 0..255 | draw linewise until nonzero color or end, for filling the pixel buffer |
0x0a |
lfill |
fill color from palette, 0..255 | draw backwards linewise until nonzero color or end, for filling the pixel buffer |
Cmd | Name | no argument | Description |
---|---|---|---|
0x0b |
flip |
update all pixels | |
0x0c |
spriteflip |
update pixels where sprites have been drawn since last time this command was executed |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x0d |
setlcs |
color for start of line | prepare to draw a line |
0x0e |
setlce |
color for end of line | prepare to draw a line |
- colors are interpolated linearly, component-wise (r, g, b, a)
Cmd | Name | uint16 argument | Description |
---|---|---|---|
0x11 |
lisx |
x coordinate for start of line | prepare to draw a line |
0x12 |
lisy |
y coordinate for start of line | prepare to draw a line |
0x13 |
liex |
x coordinate for end of line | prepare to draw a line |
0x14 |
liey |
y coordinate for end of line | prepare to draw a line |
Cmd | Name | no argument | Description |
---|---|---|---|
0x15 |
ldraw |
draw the line |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x1a |
setcp0 |
set color for p0 | prepare to draw a triangle |
0x1b |
setcp1 |
set color for p1 | prepare to draw a triangle |
0x1c |
setcp2 |
set color for p2 | prepare to draw a triangle |
Cmd | Name | uint16 argument | Description |
---|---|---|---|
0x1d |
setxp0 |
x coordinate for p0 | prepare to draw a triangle |
0x1e |
setyp0 |
y coordinate for p0 | prepare to draw a triangle |
0x1f |
setxp1 |
x coordinate for p1 | prepare to draw a triangle |
0x20 |
setyp1 |
y coordinate for p1 | prepare to draw a triangle |
0x21 |
setxp2 |
x coordinate for p2 | prepare to draw a triangle |
0x22 |
setyp2 |
y coordinate for p2 | prepare to draw a triangle |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x23 |
tdraw |
0 for empty, 1 for filled | draw a filled or empty triangle |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x30 |
spid |
sprite ID | select a sprite ID to work with |
0x31 |
spw |
sprite width | set sprite width |
0x32 |
sph |
sprite height | set sprite height |
0x33 |
spclr |
color | clear contents with the given color |
0x34 |
spush |
amount of pixels | add N pixels of the active color |
0x35 |
spt |
amount of pixels | add N transparent pixels |
0x36 |
sprot |
value from 0..255, used as float from 0..2*PI |
rotate the current sprite |
0x37 |
spscale |
value from 0..255, used as float from -20..20 | scale the current sprite |
0x38 |
spcopy |
sprite ID | copy to another sprite ID |
Cmd | Name | uint16 argument | Description |
---|---|---|---|
0x39 |
spx |
x coordinate | set x coordinate for where to draw the sprite |
0x3a |
spy |
y coordinate | set y coordinate for where to draw the sprite |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x3b |
blit |
number of sprites to draw | draw n instances of this sprite, following the pixel buffer direction |
0x3c |
blitinc |
number of sprites to draw | like blit , but increases the sprite ID at every step |
- The "pixel buffer direction" is from left to right, then starting on the next y coordinate (+ sprite height) when reaching the end of the line.
- Several sprites can be placed in a row with the
blit
command. They are placed next to each other, without overlapping. - For the
blitinc
command, increasing the value from 255 wraps around and sets to current sprite ID to 0. - Sprites can have a resolution up to
128*128
(inclusive).
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x40 |
con0 |
value from 0..255, used as float from -20..20 | set convolution filter value 0 |
0x41 |
con1 |
value from 0..255, used as float from -20..20 | set convolution filter value 1 |
0x42 |
con2 |
value from 0..255, used as float from -20..20 | set convolution filter value 2 |
0x43 |
con3 |
value from 0..255, used as float from -20..20 | set convolution filter value 3 |
0x44 |
con4 |
value from 0..255, used as float from -20..20 | set convolution filter value 4 |
0x45 |
con5 |
value from 0..255, used as float from -20..20 | set convolution filter value 5 |
0x46 |
con6 |
value from 0..255, used as float from -20..20 | set convolution filter value 6 |
0x47 |
con7 |
value from 0..255, used as float from -20..20 | set convolution filter value 7 |
0x48 |
con8 |
value from 0..255, used as float from -20..20 | set convolution filter value 8 |
0x49 |
condiv |
convolution division, 0..255, used as float from -20..20 | set convolution division value |
0x4a |
apply |
apply convolution filter to all pixels | |
0x4b |
consp |
apply convolution filter to the current sprite |
The convolution filter parameters 0..255 are treated as if they were floats between -20 and 20 (inclusive).
Example filters:
- blur is 0,1,0,1,1,1,0,1,0 div 5
- flame is 0,1,0,1,1,1,0,0,0 div 4
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x50 |
radd |
utf-8 byte | add a byte to the current UTF-8 rune |
Cmd | Name | no argument | Description |
---|---|---|---|
0x51 |
rclear |
clear the current UTF-8 rune | |
0x52 |
rsprite |
fill the current sprite with the current rune |
At a minimum, these glyphs must exist:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,._:;"'[]{}()-\/|*#@?!☃
Implementations should supply at least a font that works at 8x8 character size.
The snowman is useful for identifying if the protocol can correctly support at least one non-ASCII character.
Use an ø
if no glyph is available for an UTF-8 rune.
For returning the state of the client.
A channel must be set up for receiving theuint16
values that are returned by these functions.
Commands that return an uint16
:
Cmd | Name | no argument | Description |
---|---|---|---|
0x60 |
kesc |
is Escape being pressed? | |
0x61 |
kup |
is W, up or joystick up pressed? args: 0 for any, 1..4 for Player 1..4 | |
0x62 |
kleft |
is A, left or joystick left pressed? args: 0..5 | |
0x63 |
kdown |
is S, down or joystick down pressed? args: 0..5 | |
0x64 |
kright |
is D, right or joystick right pressed? args: 0..5 | |
0x65 |
ka |
is Return, comma (,) or joystick A button pressed? args: 0..5 | |
0x66 |
kb |
is Space, dot (.) or joystick B button pressed? args: 0..5 |
- P1 means Player 1, P2 means Player 2.
- Player 1 has WASD keys, lshift, lctrl and/or Joystick 1.
- Player 2 has the arrow keys, comma (,), dot (.) and/or Joystick 2.
- Player 3 has the numpad arrows and/or Joystick 3.
- Player 4 has Joystick 4.
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x67 |
kshift |
0 for left, 1 for right, 2 for any | returns 1 if Shift is held down |
0x68 |
kalt |
0 for left, 1 for right, 2 for any | returns 1 if Alt is held down |
0x69 |
kctrl |
0 for left, 1 for right, 2 for any | returns 1 if Ctrl is held down |
0x6a |
ksuper |
0 for left, 1 for right, 2 for any | returns 1 if Super is held down |
Cmd | Name | no argument | Description |
---|---|---|---|
0x6b |
kget |
returns 0 if keybuffer is empty, keycode of first in keybuffer if not empty |
Cmd | Name | no argument | Description |
---|---|---|---|
0x6c |
mx |
get mouse x coordinate | |
0x6d |
my |
get mouse y coordinate | |
0x6e |
mbtn |
get mouse buttons, returns: 0 for none, 1 for left, 2 for right and 3 for middle |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x6f |
jbtn |
joystick button ID | check if joystick button is pressed, returns 1 for pressed |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x70 |
t0prog |
MIDI program | select a MIDI program for track 0 (there are 4 tracks) |
0x71 |
t1prog |
MIDI program | select a MIDI program for track 1 (there are 4 tracks) |
0x72 |
t2prog |
MIDI program | select a MIDI program for track 2 (there are 4 tracks) |
0x73 |
t3prog |
MIDI program | select a MIDI program for track 3 (there are 4 tracks) |
Cmd | Name | uint8 argument | Description |
---|---|---|---|
0x80 |
t0note |
MIDI note | play the MIDI note for track 0 for 20 ms, where note 00 is C3, 01 is D3, 02 is D3 etc (A4 is 432 Hz) |
0x81 |
t1note |
MIDI note | play the MIDI note for track 1 for 20 ms, where note 00 is C3, 01 is D3, 02 is D3 etc (A4 is 432 Hz) |
0x82 |
t2note |
MIDI note | play the MIDI note for track 1 for 20 ms, where note 00 is C3, 01 is D3, 02 is D3 etc (A4 is 432 Hz) |
0x83 |
t3note |
MIDI note | play the MIDI note for track 1 for 20 ms, where note 00 is C3, 01 is D3, 02 is D3 etc (A4 is 432 Hz) |
Cmd | Name | no argument | Description |
---|---|---|---|
0xff |
exit |
end the program, disconnect | |
0x90 |
esc |
exit if Escape has been pressed |
All state values are expected to be zeroed at the start of the program.
Description | Type |
---|---|
r, g, b, a * 256 palette info | 4 * 256 * uint8 |
x position for pixel | uint16 |
y position for pixel | uint16 |
color index for pixel | uint16 |
x1 position for line | uint16 |
y1 position for line | uint16 |
x2 position for line | uint16 |
y2 position for line | uint16 |
c1 color for line start | uint8 |
c2 color for line end | uint8 |
x1 position for triangle | uint16 |
y1 position for triangle | uint16 |
x2 position for triangle | uint16 |
y2 position for triangle | uint16 |
x3 position for triangle | uint16 |
y3 position for triangle | uint16 |
c1 color for triangle point 1 | uint8 |
c2 color for triangle point 2 | uint8 |
c3 color for triangle point 3 | uint8 |
convolution filter + division, 10 bytes | 10 * uint8 |
sprites | 128 * 128 * uint8 |
current sprite ID | uint8 |
If you implement something using this protocol, please let me know. :)
- Version: 3.0.0
- Author: Alexander F. Rødseth
- License: CC0
- GitHub Project