Differences from the C API
The screen buffer
The screen buffer is a CFFI buffer object. It can be accessed with item syntax:
# (C API)
# char *screen = screenbuffer();
screen = screenbuffer()
# (C API)
# screen[0] = 0x40;
# screen[1] = 0x41;
# screen[2] = 0x42;
# screen[3] = 0x43;
screen[0] = b'\x40';
screen[1:4] = bytearray([0x41, 0x42, 0x43])
# (C API)
# print("%x\n", screen[2]); // 42
print(screen[2].hex()) # 42
Basic types
Functions with text arguments will accept CP437 encoded bytes, or strings as long
as they can be encoded in CP437:
# (C API)
# cputs("\xb0\xb1\xb2)");
cputs(b'\xb0\xb1\xb2')
# (C API)
# cputs("hello \x02");
cputs('hello ☻')
bool is used for true/false arguments and return values:
# (C API)
# setdoublebuffer(1)
setdoublebuffer(True)
# (C API)
# int x = shuttingdown()
x: bool = shuttingdown()
# (C API)
# settextstyle(DEFAULT_FONT_8X8, 0, 1, 0)
settextstyle(DEFAULT_FONT_8X8, bold=False, italic=True, underline=False)
Exceptions
In cases where a function can return NULL on error, the Python version will raise an exception
(typically a ValueError).
# (C API)
# struct music_t *music = loadmid("does not exist.mid");
# if(!music) {
# printf("Could not load music\n");
# }
try:
music = loadmid('does not exist.mid')
except ValueError:
print('Could not load music')
Palette
The palette functions accept and return a named 3-tuple, RGB, that has r, g,
and b properties for the red, green, and blue channels respectively:
# (C API)
# int r, g, b;
# getpal(0, &r, &g, &b);
# print("%d, %d, %d\n", r, g, b);
color = getpal(0)
print(f'{color.r}, {color.g}, {color.b}')
# (C API)
# setpal(0, 1, 3, 5);
setpal(0, 1, 3, 5) # color index and red, green, and blue channels
# (C API)
# setpal(1, 2, 4, 6);
setpal(1, (2, 4, 6)) # color index and 3-tuple of ints
# (C API)
# setpal(3, 3, 5, 7);
setpal(2, RGB(3, 5, 7)) # color index and RGB namedtuple
GIF images
GIF images are returned in a GIF data class.
# (C API)
# int width, height, palcount;
# char palette[768];
# char *pixels = loadgif("test.gif", &width, &height, &palcount, palette);
gif = loadgif('test.gif')
# (C API)
# printf("test.gif: %dx%d, %d colors\n", width, height, palcount);
print(f'{gif.filename}: {gif.width}x{gif.height}, {len(gif.palette)} colors')
# (C API)
# char top_left = pixels[0]; // 1
top_left_byte = gif.pixels[0] # b'\x01'
top_left_index = top_left_byte[0] # 1
# (C API)
# char *color = &palette[top_left];
# printf("top left red: %d, green: %d, blue %d\n",
# *color, *(color + 1), *(color + 2);
color = gif.palette[top_left_index]
print(f'top left red: {color.r}, green: {color.g}, blue: {color.b}')
Polygons
Point lists for polygons may be a list of tuples [(𝑥1, 𝑦1), (𝑥2, 𝑦2)], a flattened list
of points [𝑥1, 𝑦1, 𝑥2, 𝑦2]`, or a buffer of a flattened list of points as ints.
# (C API)
# int points[] = {5, 0, 10, 10, 0, 10, 5, 0};
# drawpoly(points, 8);
drawpoly([(5, 0), (10, 10), (0, 10), (5, 0)])
# or flattened:
drawpoly([5, 0, 10, 10, 0, 10, 5, 0])
# or from a buffer:
data = struct.pack('8i', 5, 0, 10, 10, 0, 10, 5, 0)
drawpoly(data)
Font and sound bank handles
installuserfont() and installusersoundbank() return int subclasses
FontHandle and SoundBankHandle respectively. This is purely to help your
type checker (e.g. prevent you from passing a sound bank to a function expecting a font).
Keys and characters
readkeys() returns a list of KeyCode enums. The length of the list
should be used instead of searching for a zero value:
# (C api)
# enum keycode_t *keys = readkeys();
# int length = 0;
# for(enum keycode_t key = *keys; *keys++; key) {
# if(key == KEY_A) printf("A was pressed\n");
# length++;
# }
# printf("There were %d keys in the buffer.\n", length);
keys = readkeys()
for key in keys:
if key == KEY_A:
print('A was pressed')
print(f'There were {len(keys)} keys in the buffer.')
Similarly, readchars() returns a str of characters. The length of the string
should be used instead of searching for a NUL character:
# (C api)
# char *chars = readchars();
# int length = 0;
# for(char c = *chars; *chars++; c) {
# if(c == 'a') printf("A was pressed\n");
# length++;
# }
# printf("There were %d characters in the buffer.\n", length);
chars = readchars()
for char in chars:
if char == 'a':
print('A was pressed')
print(f'There were {len(chars)} characters in the buffer.')