SDL-based 'GRAPHICS.H' implementation
Project description
About
SDL_bgi is a graphics library (GRAPHICS.H) for C, C++,
WebAssembly, and Python. It comes in two versions based on
SDL2 and SDL3, and it runs on many platforms; the two versions
have identical functionality.
Its name refers to BGI, the Borland Graphics Interface that was the
'de facto' standard in PC graphics back in DOS days; it was made
popular by Borland Turbo C/C++ compilers. I wrote SDL_bgi because I
wanted a simple to use but fast graphics library for my experiments
with fractals and cellular automata, using the BGI syntax I'm used to.
SDL_bgi is functionally compatible with the BGI implementation in
Turbo C 2.01 and Borland C++ 1.0; for instance, it compiles and runs
the original bgidemo.c. It also provides nearly full compatibility
with another BGI implementation, WinBGIm (see links below). One of
the aims of SDL_bgi is the preservation of old software written
for BGI; but not only that.
SDL_bgi provides graphics primitives, and is much easier to use than
plain SDL; it should be especially useful for beginners, i.e. in
introductory programming courses. SDL_bgi is pretty fast, and in
addition to BGI compatibility it provides extensions for ARGB colours,
mouse support, vector fonts, and multiple windows. Native SDL2 or SDL3
functions can be used alongside SDL_bgi functions. The library can
also be used in programs written in C++ or Python.
SDL_bgi is written in C, and it should compile on any platform
supported by SDL2 or SDL3. It has been tested on GNU/Linux, MS
Windows (MSYS2 and ucrt64, CodeBlocks, Dev-C++), macOS (High Sierra
and Catalina), Raspios (ARM, i386), and WebAssembly (Emscripten). A
few example programs in C and Python are provided in the demo/
directory.
Requirements
The C version requires the SDL2 or SDL3 library development packages.
The Python module requires the SDL_bgi binaries and the SDL2 or
SDL3 library binaries.
How to Install
Once the dependencies above are met, just do:
$ pip install sdl_bgi
How to use SDL_bgi in Python programs
Please make sure that you installed the SDL_bgi binaries for your
platform before proceeding.
Implementation Details
SDL_bgi Python bindings are implemented via
the ctypes library.
In general:
-
functions in Python have the same name as their C counterparts;
-
constants and enums are implemented as variables;
-
standard C types (
int,float,char *, etc.) are mapped to Python types; -
structs are available as
ctypesclasses that have the same name and field names. For example:
\small
C struct Python class
-------- ------------
struct arccoordstype { class arccoordstype (Structure):
int x; _fields_ = [ ("x", c_int),
int y; ("y", c_int),
int xstart; ("xstart", c_int)
int ystart; ("ystart", c_int)
int xend; ("xend", c_int),
int yend; ("yend", c_int) ]
};
\normalsize
There are minor differences explained below.
Syntax differences
ctypes implements new types that are mapped to equivalent Python
types; for example, c_int is equivalent to int. Please refer to
ctypes'
Reference.
2D arrays can be implemented via Numpy; please
see for example demo/life.py or demo/buffers_numpy.py. Strictly
speaking, Numpy is not required; but working with arrays without it is
a pain.
Memory buffers, used for example by getimage() or getbuffer(), are
implemented using function create_string_buffer().
The byref() function can be used to pass variables by reference, as
in the following functions:
\small
# void detectgraph (int *graphdriver, int *graphmode);
graphdriver, graphmode = c_int (), c_int ()
detectgraph (byref (graphdriver), byref (graphmode))
print ("graphdriver, graphmode: ", graphdriver.value, graphmode.value)
# void getarccoords (struct arccoordstype *arccoords);
ac = arccoordstype ()
getarccoords (byref (ac))
print ("x, y, xstart, ystart, xend, yend: ", ac.x, ac.y,
ac.xstart, ac.ystart, ac.xend, ac.yend)
# void getaspectratio (int *xasp, int *yasp);
xasp, yasp = c_int (), c_int ()
getaspectratio (byref (xasp), byref (yasp))
print ("xasp, yasp: ", xasp.value, yasp.value)
# void getfillsettings (struct fillsettingstype *fillinfo);
fillinfo = fillsettingstype ()
getfillsettings (byref (fillinfo))
print ("pattern, color: ", fillinfo.pattern, fillinfo.color)
# void getimage ()
isize = imagesize (0, 0, len, 16)
image = create_string_buffer (isize)
getimage (0, 0, len, 16, image)
# void getlinesettings (struct linesettingstype *lineinfo);
lineinfo = linesettingstype ()
getlinesettings (byref (lineinfo))
print ("linestyle, thickness: ", ls.linestyle, ls.thickness)
# void getmoderange (int graphdriver, int *lomode, int *himode);
lomode, himode = c_int (), c_int ()
getmoderange (0, byref (lomode), byref (himode))
print ("lomode, himode: ", lomode.value, lomode.value)
# void getmouseclick (int btn, int *x, int *y);
kind, x, y = c_int (), c_int (), c_int ()
getmouseclick (kind, byref (x), byref (y))
print ("mouse x, mouse y: ", x.value, y.value)
# void getscreensize (int x, int y);
x, y = c_int (), c_int ()
getscreensize (byref (x), byref (y))
print ("size x, size y: ", x, y)
\normalsize
Pythonic Syntax
The following functions provide a more Pytonic syntax that only uses standard Python types:
\small
# void detectgraph (int *graphdriver, int *graphmode);
graphdriver, graphmode = detectgraph ()
print ("graphdriver, graphmode: ", graphdriver, graphmode);
# void getarccoords (struct arccoordstype *arccoords);
ac = arccoordstype ()
ac = getarccoords ()
print ("x, y, xstart, ystart, xend, yend: ", ac.x, ac.y,
ac.xstart, ac.ystart, ac.xend, ac.yend)
# void getaspectratio (int *xasp, int *yasp);
xasp, yasp = getaspectratio ()
print ("xasp, yasp: ", xasp, yasp)
# void getfillsettings (struct fillsettingstype *fillinfo);
fs = fillsettingstype ()
fs = getfillsettings ()
print ("pattern, color: ", fs.pattern, fs.color)
# void getlinesettings (struct linesettingstype *lineinfo);
ls = linesettingstype ()
ls = getlinesettings ()
print ("linestyle, thickness: ", ls.linestyle, ls.thickness)
# void getmoderange (int graphdriver, int *lomode, int *himode);
lomode, himode = getmoderange ()
print ("lomode, himode: ", lomode, lomode)
# void getmouseclick (int btn, int *x, int *y);
x, y = getmouseclick (WM_LBUTTONDOWN)
print ("mouse x, mouse y: ", x, y)
# void getscreensize (int x, int y);
x, y = getscreensize ()
print ("size x, size y: ", x, y)
# void initgraph (int *graphdriver, int *graphmode, char *pathtodriver)
initgraph ()
\normalsize
Helper Functions
The following functions can be useful:
list2vec (list): converts a Python list of integers to a vector;
used for example by drawpoly()
vec2buf (vector): returns a string buffer that contains the values
stored in vector. This is a 1-dimensional array that can be obtained
from a Numpy 2D array 'matrix' with reshape (matrix, -1).
sizeofint (): equivalent to C sizeof (int). Please note that this
is not the same as sys.getsizeof()!
Missing Features
SDL2-based variables bgi_window, bgi_renderer, bgi_texture,
PALETTE_SIZE, and function copysurface() are not available.
Speeding Things Up
Python is an interpreted language, and its performance is quite poor
if compared to compiled code. The PyPy
interpreter should make Python code run faster, but SDL_bgi programs
run much slower with PyPy than with CPython. Another Python
implementation, Pyston, actually runs
SDL_bgi programs definitely faster than CPython.
To give your programs a real boost, I strongly suggest that module
Numba be used. Numba is a high
performance Python JIT compiler that can translate a large subset of
Python and NumPy code into fast machine code. It uses simple function
decorators; please have a look at demo/mandelbrot.py to see how it
works.
Making Standalone Binaries
To deploy a Python program as a standalone executable file, you may use PyInstaller or Nuitka.
Pyinstaller
Run it as in the following example:
test$ pyinstaller -F fern.py
121 INFO: PyInstaller: 5.4.1
121 INFO: Python: 3.10.4
...
7373 INFO: Building EXE from EXE-00.toc completed successfully.
test$ _
The resulting executable will be created in directory dist/.
Nuitka
Run it as in the following example:
test$ nuitka3 --onefile --remove-output fern.py
Nuitka-Options:INFO: Used command line options: --onefile \
--remove-output fern.py
Nuitka:INFO: Starting Python compilation with Nuitka '1.1.3' \
on Python '3.10' commercial grade 'not installed'.
...
Nuitka:INFO: Successfully created 'fern.bin'.
test$ _
When run on Windows, you get fern.exe and fern.cmd, which is a
batch file that sets up the proper runtime environment for the
executable. Run fern.cmd to start the program; on MSYS2, use:
test$ start fern.cmd
On my GNU/Linux Mint 21.2 box, Nuitka creates a much smaller executable than Pyinstaller does.
Links
-
SDL_bgihome page: https://sdl-bgi.sourceforge.io/; https://pypi.org/project/sdl-bgi -
The SDL library: https://www.libsdl.org/
-
BGI on Wikipedia: https://en.wikipedia.org/wiki/Borland_Graphics_Interface
-
WinBGIm, a BGI port for Windows: https://winbgim.codecutter.org/
-
Borland Turbo C 2.01 online emulator: https://archive.org/details/msdos_borland_turbo_c_2.01
-
PyEasyGraphics, a BGI-like Python port: https://github.com/royqh1979/PyEasyGraphics
This library is released under the Zlib license; please see the enclosed file LICENSE.
Brought to you by Guido Gonzato, PhD
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sdl_bgi-3.0.4.tar.gz.
File metadata
- Download URL: sdl_bgi-3.0.4.tar.gz
- Upload date:
- Size: 30.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5f4562d6c68b41641553cf58b9a006518e4682f4f2f5657ab180418bee866e8
|
|
| MD5 |
e2725645b5816e98f147c3a8ffcc143e
|
|
| BLAKE2b-256 |
53f10b3d16e8e01b5f1dbb820effb85072956fadff864dc3c97e0cc56e7f7c87
|
File details
Details for the file sdl_bgi-3.0.4-py3-none-any.whl.
File metadata
- Download URL: sdl_bgi-3.0.4-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb4081b242d073f43fed4f415e868db353017908c2972e5edf9dbc4a987ed06a
|
|
| MD5 |
f15aae159a0af76724aa75e25b7ffe28
|
|
| BLAKE2b-256 |
e7c2bc9509775de75a750f396bd8a75b0794a522bd0fbf1f0aea2aed928c0c86
|