Package: sdl-bgi
AboutSDL_bgiis a graphics library (GRAPHICS.H) for C, C++,
WebAssembly, and Python. It's based on SDL2 and it's portable on many
platforms.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 wroteSDL_bgibecause 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_bgiis functionally compatible with the BGI implementation in
Turbo C 2.01 and Borland C++ 1.0; for instance, it compiles and runs
the originalbgidemo.c.SDL_bgialso provides nearly full
compatibility with another BGI implementation, WinBGIm (see links
below). One of the aims ofSDL_bgiis the preservation of old
software written for BGI; but not only that.SDL_bgiprovides graphics primitives, and is much easier to use than
plain SDL2; it should be especially useful for beginners, i.e. in
introductory programming courses.SDL_bgiis pretty fast, and in
addition to BGI compatibility it provides extensions for ARGB colours,
mouse support, vector fonts, and multiple windows. Native SDL2
functions can be used alongsideSDL_bgifunctions.SDL_bgican
also be used in programs written in C++ or Python.SDL_bgiis written in C, and it should compile on any platform
supported by SDL2. It has been tested on GNU/Linux, MS Windows (MSYS2
and Mingw-w64, 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 thedemo/directory.RequirementsThe C version requires the SDL2 library development packages. The
Python module requires theSDL_bgibinaries and the SDL2 library
binaries.How to InstallOnce the dependencies above are met, just do:$ pip install sdl_bgiHow to useSDL_bgiin Python programsPlease make sure that you installed theSDL_bgibinaries for your
platform before proceeding.Implementation DetailsSDL_bgiPython bindings are implemented via
thectypeslibrary.
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 asctypesclasses that have the same name
and field names. For example:\smallC 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) ]
};\normalsizeThere are minor differences explained below.Syntax differencesctypesimplements new types that are mapped to equivalent Python
types; for example,c_intis equivalent toint. Please refer toctypes'Reference.2D arrays can be implemented viaNumpy; please
see for exampledemo/life.pyordemo/buffers_numpy.py. Strictly
speaking, Numpy is not required; but working with arrays without it is
a pain.Memory buffers, used for example bygetimage()orgetbuffer(), are
implemented using functioncreate_string_buffer().Thebyref()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)\normalsizePythonic SyntaxThe 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 ()\normalsizeHelper FunctionsThe following functions can be useful:list2vec (list): converts a Python list of integers to a vector;
used for example bydrawpoly()vec2buf (vector): returns a string buffer that contains the values
stored invector. This is a 1-dimensional array that can be obtained
from a Numpy 2D array 'matrix' withreshape (matrix, -1).sizeofint (): equivalent to Csizeof (int). Please note that this
is not the same assys.getsizeof()!Missing FeaturesSDL2-based variablesbgi_window,bgi_renderer,bgi_texture,PALETTE_SIZE, and functioncopysurface()are not available.Speeding Things UpPython is an interpreted language, and its performance is quite poor
if compared to compiled code. ThePyPyinterpreter should make Python code run faster, butSDL_bgiprograms
run much slower with PyPy than with CPython. Another Python
implementation,Pyston, actually runsSDL_bgiprograms definitely faster than CPython.To give your programs a real boost, I strongly suggest that moduleNumbabe 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 atdemo/mandelbrot.pyto see how it
works.Making Standalone BinariesTo deploy a Python program as a standalone executable file, you may usePyInstallerorNuitka.PyinstallerRun 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 directorydist/.NuitkaRun 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 getfern.exeandfern.cmd, which is a
batch file that sets up the proper runtime environment for the
executable. Runfern.cmdto start the program; on MSYS2, use:test$ start fern.cmdOn my GNU/Linux Mint 20.2 box, Nuitka creates a much smaller
executable than Pyinstaller does.LinksSDL_bgihome page:https://sdl-bgi.sourceforge.io/;https://pypi.org/project/sdl-bgiThe SDL library:https://www.libsdl.org/BGI on Wikipedia:https://en.wikipedia.org/wiki/Borland_Graphics_InterfaceWinBGIm, a BGI port for Windows:https://winbgim.codecutter.org/Xbgi, a BGI XLib port:http://libxbgi.sourceforge.net/PyEasyGraphics, a BGI-like Python port:https://github.com/royqh1979/PyEasyGraphicsBorland Turbo C 2.01 online emulator:https://archive.org/details/msdos_borland_turbo_c_2.01This library is released under the Zlib license; please see the
enclosed file LICENSE.Brought to you by Guido Gonzato, PhD